OO之美
㈠ 设计的分寸
对于设计,还有很多看似"惯常"的法则与经验广泛存在于软件系统中,例如除了经典的23种设计设计模式.还有很多模式之外的模式,按照粒度的大小,系统的特点,规模的大小,而形成的架构规则.
设计的哲学就是对关系的处理,就像人类的复杂关系一样,如何简单明了的处理类与类,模块与模块,层次与层次的关系是设计的精髓所在.
对于设计来说,或许永远没有唯一的答案,你只能无限地接近最好
设计原则是系统设计的灵魂,而设计模式是系统开发的模版,灵活自如的应用才是设计以不变应万变的准则.
设计能力的提升绝非一朝一夕之功,软件开发中的设计大师,往往必须具备多年的修行方可称之"架构师".在设计的广义概念里,几个必需的概念是应该首先被了解和认知的,以排名不分先后的原则罗列,他们大概包括:
⑴面向对象关于面向对象没有必要重复嚼舌.
⑵面向服务.SO至少是个时髦的话题,WCF至少是个时髦的话题,WCF伴着.NET3.5的发布,一个一统江湖的面向服务的基础框架横空出世.可以想象的是,未来的分布式系统架构将变得更加柔性和统一,简单而有效
⑶框架.所谓框架就是应用系统构建所需的基础设施.应用程序是变化万千,而基础架构则是相对稳定.这正是我们基于.NET Framework来实施数以万计的.NET应用:Winforms Form Application ,Web Form Application,XML Web Service等,都体现了框架和应用的关系. .NET Framwork本身就是一个基础性架构,正如经典的MFC一样,提供了.NET应用赖以生存的基础性支持.对于框架的探索和实践,是每个有意提高设计能力的开发者的必经之路.选择一个或者几个经典的框架进行梳理与实践,才能有效地了解软件世界的庞大体系是如何和谐统一的运作.从经典框架设计中,寻找灵感,锻炼体验,例如分享经典案例Petshop三层架构的实践体验,通过真正的需求,设计,开发和测试,而在这个旅程中我们就能完成从概念到实践,从表面到思想的体验.
⑷设计原则.是面向对象设计程序开发的思想大成,了解面向对象,深入设计模式,则有必要深入设计原则之精髓.可以完全不了解全部的设计模式,但必须深入每一个设计原则.一个是内功,一个是招式设计的第一项修炼就从内功开始:面向对象设计原则
⑸设计模式.23个设计模式,23个智慧经典,了解和掌握几个重要的设计模式,是修炼面向对象招式的必经之路.无论如何,作为设计者你应该在自己心中知道什么是Abstract Factory.Iterator.Signleton.Adapter,Decoraor.Observer.Facade.Template.Command.
⑹模式之外,除了23个经典的设计模式,其实还存在很多模式之外的模式,按照粒度的不同而广泛应用在实际的项目系统中.例如,在SOA系统中的Event driven Architecture,Message Bus以及分布式Broker模式:数据持久层的Repository,Active Record还有Identity Map模式;可伸缩系统下的Map/Reduce.Load Balancer以及Result Cache模式;更高架构层面的MVC,MVP以及Pipeline/Filter模式.在某种意义上而言,模式是一种经验的积累和总结,对于系统设计与架构考量,架构师要完成的不仅仅是对功能性需求的把握,还包括非功能的积累和总结,对于系统设计与架构考量,架构师要完成的不仅仅是对功能性需求的把握,还包括非功能性需求,平台与框架的平衡,性能与安全的考量.
其实每个人都是食神,其实开发者都是设计师.关键在于掌勺的你,是否能让做饭的家伙油光锃亮
作为学习者,可能我们还不具备在宏观上把握如何将上述模糊的概念进行统筹和消化,那么作为预备设计师,首先要做好的工作就是逐个认识SOA,Mapper,Pieline,DTO,Message Bus这些概念,有了这些基本功之后再看着唱本骑驴走远.
㈡依赖的哲学
要了解依赖倒置,首先应该回答以下问题:
1.控制反转,依赖导致,依赖注入这些概念,你认识但是否熟悉?
2.Uinity,ObjectBuilder,Cache这些容器,你相识是否相知?
3.面向接口,面向抽象,开放封闭这些思想,你了解但是否了然?
带着以上的问题,重新认识依赖.
什么是依赖和耦合:依赖阐释了耦合本质,而耦合量化了依赖程度
从依赖的角度:
①无依赖,代表没有发生任何联系,所以二者相互独立,互不影响,没有耦合关系.
②单向依赖,关系双方的依赖是单向的,代表了影响的方向也是单向的,其中一个实体发生改变,会对另外的实体产生影响,反之则不然,耦合度不高.
③双向依赖,关系双方的依赖是相互的,影响也是相互的,耦合读较高.
从耦合的角度:
①零耦合:表示两个类没有依赖.
②具体耦合,如果一个类持有另一个类的引用,那么这两个类就发生了具体耦合关系.所以具体耦合发生在具体类之间的依赖,因此具有类的变更将引起对其关联类的影响.
③抽象耦合,发生在具体类和抽象类的依赖,其最大的作用就是通过对抽象的依赖,应用面向对象的多态机制,实现了灵活的扩展性和稳定性.
不同的耦合,代表了依赖程度的差别,以"粒度"为概念来分析其耦合程度.引用中间层来分离耦合,可以使设计更优雅,架构更加富有柔性,但直接的依赖也存在其市场,过度的设计也并非可取之道.因为,效率与性能同样是设计需要考量的因素,过多的不必要分离会增加调用的次数,造成效率浪费.
耦合的分类
1.继承
2.聚合
3.接口
4.方法调用和引用
5.服务调用
知道以上耦合之后,就要知道设计的目标:高内聚,低耦合
低耦合
:代表了实现最简单的依赖关系,尽可能地减少类与类,模块与模块,层次与层次,系统与系统之间的联系.低耦合,体现了人类追求简单操作的理想状态,按照软件开发的基本实现技巧追求软件实体之间的简单化,正是大部分设计模式力图追求的目标;低耦合,降低了一个类或一个模块发生修改对其他类或模块造成的影响,将影响范围简单化.在这里,实现单向的依赖,实现抽象的耦合,都是实现低耦合的基础条件.
高内聚
:一方面代表了职责的统一管理,一方面体现了关系的有效隔离.例如单一职责原则其实归根结底是对功能性的一种指导性体现,将功能紧密联系的职责封装为一个类(或模块),而判断的准则正是基于引起类变化的原因.所以,封装离不开依赖,而抽象离不开变化,二者的概念和本质都是相对而言.因此,高内聚的目标体现了以隔离为目标进行统一管理的思想
因此在设计软件时:
⑴尽可能实现单向依赖
⑵不需要进行数据交换的双方,不要实现多此一举的关联,人们将此形象成为"不要和陌生人说话"
⑶保持内部的封装性,关联的双方不要深入实现细节进行通信,这是保证高内聚的必须条件.
关联应该终止于抽象而不是具体,具体类发生修改,不会影响到其他模块或者关系
如何抽象:简要概括以下几点:
⒈层次清晰化,清晰的层次划分,进而形成的模块话,是实现系统抽象的必经之路.
⒉分散集中化,是一个梳理需求到形成设计的过程,因此对于把握系统中的抽象和具体而言,是一个重要的分析过程和手段.现代软件工程已经对此形成了科学的标准化流程处理逻辑,例如可以借助UML更加清晰地设计流程,分析设计要素,进行标准化沟通和交流.
⒊具体抽象化,将具体问题抽象化,是本节的要点,但怎么处理呢?答案就是在设计模式中.作为软件设计话题中最重量级的话题,关注模式和实践模式是成长的记录.
⒋封装变化点.在变化的地方寻找抽象是面对抽象对理想的方式.
OO之美的更多相关文章
- 《你必须知道的.NET》读书笔记三:体验OO之美
此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.依赖也是哲学 (1)本质诠释:“不要调用我们,我们会调用你” (2)依赖和耦合: ①无依赖,无耦合 ...
- OO之美4(好代码与坏代码)
前言:写代码不仅仅要做到能与机器交流,更要做到能和人交流 编码规范:编码规范就是最佳实践,是前辈在编码这件事上的积累和总结,是智慧的延续和工业的实践,如下: ⑴命名规范 ⑵避免行数过多的方法 ⑶代码缩 ...
- OO之美3
面向对象和基于对象 基于对象:所以基于对象,就是一种对数据类型的抽象,封装一个结构包含了数据和函数,然后以对象为目标进行操作.构建的基础是对象,但是操作对象并不体现出面向对象的继承性,也就是基于对象局 ...
- OO之美2
面向对象并没有想象中那么神秘,以生活的现实眼光来看更是如此.把面向对象深度浓缩起来,可以概括为: ⑴目标:重用,扩展,兼容 ⑵核心:低耦合,高内聚 ⑶手段:封装变化 ⑷思想:面向接口编程,面向抽象编程 ...
- 《必须知道.NET》3.OO之美
3.2 依赖的哲学 3.2.1 本质诠释 "不要调用我们,我们会调用你" 3.2.2 什么是依赖,什么是抽象 "耦合是不可避免的" (1)什么是依赖和耦合 依赖 ...
- C#刨根究底:《你必须知道的.NET》读书笔记系列
一.此书到底何方神圣? <你必须知道的.NET>来自于微软MVP—王涛(网名:AnyTao,博客园大牛之一,其博客地址为:http://anytao.cnblogs.com/)的最新技术心 ...
- 设计模式之美:Type Object(类型对象)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Type Object 的经典介绍. 实现方式(二):Type Object 在游戏设计中的使用. 意图 允许在运行时动态灵活的 ...
- 结对编程-地铁续(有种上个学期OO的既视感)
我们组比较特殊..三人结对 github:https://github.com/qingchanghan/WPFUI_Metro po一张照片: 石浩然,韩青长.陈彦吉 (台式机真的很高端,分屏贼帅) ...
- 菜鸡谈OO 第二单元总结
“欢迎来到(玄学)多线程的新世界” Homework1 单部傻瓜电梯调度 Part1 多线程设计策略 第一次学到了线程这个概念,与之前的编程体验大有不同.最大的区别在于从原本的线性发生程序变成了多个行 ...
随机推荐
- BZOJ3825 : [Usaco2014 Nov]Marathon
不跳过任何点的路程=dis(l,l+1)+dis(l+1,l+2)+...+dis(r-2,r-1)+dis(r-1,r) 要跳过一个点i,则要最小化dis(i,i+2)-dis(i,i+1)-dis ...
- JavaScript中toStirng()与Object.prototype.toString.call()方法浅谈
toStirng()与Object.prototype.toString.call()方法浅谈 一.toString()是一个怎样的方法?它是能将某一个值转化为字符串的方法.然而它是如何将一个值从一种 ...
- u盘文件系统故障的修复方法
比如U盘挂载的文件系统是/dev/sda1,且文件系统有故障(FAT: Filesystem error) 修复U盘文件系统故障 sudo dosfsck -v -a /dev/sda1
- JAVA_RSA密钥生成
在网上找了下RSA的密钥的创建,结果全是用java序列化PublicKey和PrivateKey来保存,就自己写了个RSA公钥和私钥的创建,及进行Base64编码后保存. 这里用到了 bcprov-j ...
- C# DateTime 日期加1天 减一天 加一月 减一月 等方法(转)
//今天 DateTime.Now.Date.ToShortDateString(); //昨天,就是今天的日期减一 DateTime.Now.AddDays(-1).ToShortDateStrin ...
- tableviewcell的这贴状态和传值总结
01 控制器 1.1 定义一个可变数组存放数据,再定义一个可变数组来记录分组的折叠状态 @property(nonatomic)NSMutableArray *dataArr; //记录所有分组的折 ...
- 1.Java为什么能跨平台运行?请简述原理。
使用不同操作系统的JVM(JAVA虚拟机)解释运行编译好的字节码文件(.class)
- [转载] - QWidget、QMainWindow、QDialog和QFrame的区别
继承关系:在Qt中所有的类都有一个共同的基类QObject ,QWidget直接继承与QPaintDevice类,QDialog.QMainWindow.QFrame直接继承QWidget 类. ...
- java网络编程之UDP实例
package Socket; import java.net.DatagramPacket; import java.net.InetAddress; public class Dgram { pu ...
- 安装Bind过程中提示丢失MSVCR110.dll的解决办法
前几天在线安装Visual Studio 2012 Update 3,由于在线安装需要不断下载安装文件,时间很长,后来等不下去,就取消了,不幸的是VS启动不了了,弹出“devenv.exe – 系统错 ...