转自:http://www.cnblogs.com/lhming/archive/2010/11/14/1877239.html
设计模式整理--面相对像设计原则
一、设计模式原则:
1、单一职责原则:
具体描述:应该有且仅有一个原因引起类的变更,即一个方法尽可能只做一件事,即尽可能只实现一个功能,而接口尽可能只负责一类功能描述,而类的设计尽量做到只有一个原因引起变化。
实现好处:
降低类复杂性,实现什么职责都有清晰明确的定义,提高了可读性,更进一步地提高可维护性,且降低了变更引起的风险。以为一个变化只有一个原因引起,那变化引起的变更只修改一个地方便可。
2、里氏替换原则:
具体描述:
所有引用基类的地方必须能透明地使用期之类的对象。即只要父类能出现的地方,子类就可以出现,且替换为子类不会发生任何错误或异常,而使用者可能根本不需要知道是父类还是子类但是反过来就不可以,有子类出现的地方,父类未必可以适应。
一般,子类必须完全实现父类的方法,但子类可以有自己的个性。
实现好处:
使用里氏替换原则的目的是增强程序的健壮性,版本升级时也可以保持非常好的兼容性,即使增加子类,原有的子类还是可以继续运行,在实际应用中,每个子类对应不同的业务含义,使用父类作为参数,传递不同的子类则可以完成不同的业务逻辑。当然,要使用子类的“个性化”业务逻辑,必须创建子类的对象,不过采用里氏替换原则设计类时,应尽量避免子类的“个性化”。
注意:覆盖或实现父类的方法时,输入参数可以被放大,所以应该使子类中的方法的前置条件必须与超类中被覆写的方法的前置条件相同或更宽。
覆写或实现父类的方法是输出结果可以被缩小。
3、依赖倒置原则:
具体描述:高层模块不应该依赖底层模块,两者都应该依赖其抽象,抽象不该依赖实现细节,细节应该依赖于抽象,即,模块间的依赖通过抽象发生,实现类之间不发生直接依赖关系,其依赖关系式通过接口或抽象类产生,而接口或抽象类有不依赖于实现类,实现类则依赖于接口或抽象类。
对象的依赖关系有以下方式来传递:
A、构造函数传递依赖对象,即在类中通过构造函数声明依赖对象。
B、通过函数传递,即将接口作为参数来传递
C、接口声明对象依赖,即通过声明接口来产生依赖
一般实现:
A、每个类尽量都有借口或抽象类或者抽象类和接口两者都具备
B、变量的表面类型尽可能是借口或者抽象类
C、任何类都不应从具体的实现类派生
D、尽量不要覆写基类的方法
E、结合里氏替换原则使用,即接口负责定义public属性和方法,并且声明与其他对象的依赖关系,抽象类负责公共构造函数的实现,实现类准确的实现业务逻辑,同时在适当的时候对父类进行细化,但尽量避免子类的“个性化”。
一般在实际项目中,对大型的项目采用依赖倒置原则可以让维护轻松,扩展容易简单。
4、接口隔离原则:
具体描述:
客户端不应该以来它不需要的接口,尽可能的保持接口的纯洁性,而类间的依赖关系应该建立在最小的接口上,即建立单一的接口,使接口尽量细化,同时接口中的方法尽量少。
一般实现:
A、接口要尽量的小,但不能违反单一职责
B、接口要高内聚,即提高接口、类、模块的处理能力,减少对外的交互,使其各司其职,但有相互配合。即在接口中尽量少公布public方法,接口是对外的承诺,承诺越少对系统开发越有利,变更的风险也就越少,同时有利于降低成本。
C、定制服务,即单独为一个个体提供有利的服务,具体点就是只提供访问者需要的方法。
D、接口设计的粒度是有限度的,在可维护和以开发的前提下,尽可能地使设计粒度小,从而使系统更灵活。
一般在实际项目中,接口和类尽量使用原子接口或原子类来组装,使一个接口只服务于一个子模块或业务逻辑,通过业务逻辑压缩接口中的public方法,时常回顾接口,尽量减小其粒度,但若已经被耦合化,或过多耦合的接口,尽量去修改,但若变更风险太大,则尝试用适配器模式进行转化处理。不过也不要生搬乱套,要了解环境,拒绝盲从,深入业务逻辑,针对业务逻辑设计接口。
5、迪米特法则:
具体描述:
一个对象应该对其他对象有最少的了解,或一个类应该对自己需要耦合或调用的类知道得最少。
一般实现:
对象间,只和相互之间直接耦合的类通信,在设计时应该反复衡量是否可以再减少Public方法和属性,是否可以改为其他的诸如private,protected等访问权限,是否可以加上final等。如果一个方法放在本类中,即不增加类间关系,也对本类不产生负面影响,就放置在本类中。谨慎使用Serializable,迪米特法则的核心观念就是类间的解耦,弱耦合,类的复用率才可以提高,但解耦就意味和产生中专或跳转类,同时是系统的复杂性提高,同时也维护带来难度,所以使用此法则时需反复权衡,即做到让结构清晰,又做到高内聚低耦合。
6、开闭原则:
具体描述:
一个软件实体如类、模块和函数应该对扩展开发,对修改关闭。
一般实现:
尽可能使用扩展软件实体(项目或软件产品中按照一定的逻辑规划划分的模块,或抽象和类,方法),而不是通过修改已有的代码来完成变化,也就是说在设计时就该预留或提供可扩展的接口,或方法,一般的变化可归纳为逻辑变化,子模块变化,可见视图变化。
开闭原则的好处:
A、对测试的影响:新增加的类,新增加的测试方法,只要保证新增加的类的正确性就好。
B、提高复用性
C、提高维护性
如何使用:
A、抽象约束,即通过接口或抽象类约束扩展,对扩展进行边界界定,不允许出现在接口或抽象类中不存在的public方法,同时参数类型、引用类型尽量使用接口或抽象类,而不是实现类,在设计时确保抽象层的稳定性,一旦确定了,就不可以改了。
B、元数据控制模块行为,即用描述环境和数据的数据,或配置参数,参数可以从文件或数据库中获得。
C、制定项目章程:团队间制定相关规范,使成员必须或尽可能遵守。
D、封装变化:将相同的变化封装到一个接口或抽象类中,将不同的变化封装到不同的接口或抽象类中,不该有两个不同的变化出现在同一个接口后抽象类中。