设计模式的七大原则

来源:互联网 发布:模块化数据机房 编辑:程序博客网 时间:2024/06/06 05:07

面向对象三大特性:封装,继承,多态

对象的优点:可维护,可扩展,可复用,灵活性好

 

1. 单一职责原则:

就一个类而言,应该仅有一个引起它变化的原因。

如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。

这种耦合会导致脆弱的设计,当变化发生时,设计会遭到意想不到的破坏。

例如界面和逻辑就需要分开,坚决不能在一个类中实现。否则界面的改动导致这个类发生变化,从而导致逻辑功能可能遭到破坏。

其实,软件设计真正要做的许多内容,就是发现职责并把职责相互分离。

判断是否需要分离一个类:如果你能找到多于一个动机去改变一个类,那么这个类就具有多于一个的职责。

 

 

2. 开放-封闭原则:

软件实体(类、模块、函数等等)应该可以扩展,但是不可以被修改。

对于扩展是开放的;

对于修改是封闭的;

无论模块是多么的封闭,都会存在一些无法对之封闭的变化,既然不可能完全封闭,设计人员必须对于它设计的模块应该对哪种变化封闭做出选择。

他必须猜测出最有可能发生的变化种类,然后构造抽象来隔离那些变化。

面对需求,对于程序的改动是通过增加新的代码进行的。而不是改动现有代码。

开放-封闭是面向对象设计的核心,只有做到它才能实现面向对象的优点:可维护,可扩展,可复用,灵活性好。

 

3. 依赖倒转原则:

针对接口编程,不要对实现编程。

高层模块不应该依赖底层模块。两个都应该依赖抽象。

抽象不应该依赖细节。细节应该依赖抽象。

同样的主板,各厂商遵循协议,针对接口编程,最终通用。

 依赖注入(DependencyInjection, DI)的方式注入到其他对象中,依赖注入是指当一个对象要与其他对象发生依赖关系时,通过抽象来注入所依赖的对象

 

 

4. 里氏代换原则:

子类型必须能够替换掉它们的父类型。

只有子类型可以替换掉父类,软件单位的功能不受影响时,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为。

例如狗,猫都是一种动物,动物有的基本特性它们都具有,因此可以替换。

鸵鸟是一种鸟类,但是如果鸟类定义为会飞的属性,那么鸵鸟则不能替换父类。因为鸵鸟不会飞。

在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。

里氏代换原则是实现开闭原则的重要方式之一

在大多数情况下,这三个设计原则会同时出现,开闭原则是目标,里氏代换原则是基础,依赖倒转原则是手段,它们相辅相成,相互补充,目标一致,只是分析问题时所站角度不同而已。

 

 

5. 合成/聚合复用原则:

尽量使用合成/聚合,尽量不要使用类继承。

聚合表示一种弱拥有关系,体现的是A对象可以包含B对象,但是B不是A的一部分:例如雁群包含大雁。

合成表示一种强拥有关系,体现的是严格的部分与整体的关系,部分和整体的生命周期一样。例如大雁拥有翅膀。

合成/聚合的好处:优先使用对象合成/聚合将有助于你保持每个类被封装,并被集中在单个任务上,这样类和类继承层次会保持较小的规模,并且不太可能增长为不可控的庞然大物。

例如:我们可以分析类的职责,而不是分析类的结构来考虑问题。

例如手机软件:通讯录,短信;

通讯录:A品牌的通讯录,B品牌的通讯录

短信:A品牌的短信,B品牌的短信

新增一个品牌,会很复杂。

如果从职责看,手机品牌包含手机软件,但是软件不是品牌的一部分。聚合关系。

这样,增加一个品牌,只需要处理品牌树的相关类即可,而不需要改变软件类。

 

 

6. 迪米特法则:又叫最少知识原则

如果两个类不必彼此直接通信,那么这两个类就不应当直接的相互作用。如果一种一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。

例如:view manager关系各个view,而各个view彼此不需要直接通信,极个别情况需要交互,则通过view manager类转发。

类之间的松耦合。

 

 

7. 接口隔离原则:

接口隔离原则(Interface  Segregation Principle, ISP):使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。

根据接口隔离原则,当一个接口太大时,我们需要将它分割成一些更细小的接口,使用该接口的客户端仅需知道与之相关的方法即可。每一个接口应该承担一种相对独立的角色,不干不该干的事,该干的事都要干。

这里的“接口”往往有两种不同的含义:一种是指一个类型所具有的方法特征的集合,仅仅是一种逻辑上的抽象;另外一种是指某种语言具体的“接口”定义,有严格的定义和结构,比如Java语言中的interface。对于这两种不同的含义,ISP的表达方式以及含义都有所不同:

      (1) 当把“接口”理解成一个类型所提供的所有方法特征的集合的时候,这就是一种逻辑上的概念,接口的划分将直接带来类型的划分。可以把接口理解成角色,一个接口只能代表一个角色,每个角色都有它特定的一个接口,此时,这个原则可以叫做“角色隔离原则”。

      (2) 如果把“接口”理解成狭义的特定语言的接口,那么ISP表达的意思是指接口仅仅提供客户端需要的行为,客户端不需要的行为则隐藏起来,应当为客户端提供尽可能小的单独的接口,而不要提供大的总接口。在面向对象编程语言中,实现一个接口就需要实现该接口中定义的所有方法,因此大的总接口使用起来不一定很方便,为了使接口的职责单一,需要将大接口中的方法根据其职责不同分别放在不同的小接口中,以确保每个接口使用起来都较为方便,并都承担某一单一角色。接口应该尽量细化,同时接口中的方法应该尽量少,每个接口中只包含一个客户端(如子模块或业务逻辑类)所需的方法即可,这种机制也称为“定制服务”,即为不同的客户端提供宽窄不同的接口。

在使用接口隔离原则时,我们需要注意控制接口的粒度,接口不能太小,如果太小会导致系统中接口泛滥,不利于维护;接口也不能太大,太大的接口将违背接口隔离原则,灵活性较差,使用起来很不方便。一般而言,接口中仅包含为某一类用户定制的方法即可,不应该强迫客户依赖于那些它们不用的方法。

 

 

 

 

0 0
原创粉丝点击