设计模式总结(二) 七大原则

七大原则

(一)单一职责原则

单一职责原则(Single Responsibility Principle,SRP)
单一职责原则是最简单的面向对象设计原则,它用于控制类的粒度大小。

定义: 一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中。

分析: 类的职责主要包括两个方面:数据职责和行为职责,数据职责通过其属性来体现,而行为职责通过其方法来体现。一个类(或大到模块,小到方法)承担的职责越多,它被复用的可能性越小,而且如果一个类承担的职责过多,就相当于将这些职责耦合在一起,当其中一个职责变化时,可能会影响其他职责的运行。单一职责原则是实现高内聚、低耦合的指导方针。

(二)开闭原则

开闭原则(Open-Closed Principle,OCP)
开闭原则是面向对象的可复用设计的第一块基石,它是最重要的面向对象设计原则。

定义: 一个软件应当对扩展开放,对修改关闭。也就是说在设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展,即实现在不修改源代码的前提下改变这个模块的行为。

分析: 在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试。当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化,虽然百分百的开闭原则很难达到,但是要尽可能使系统设计符合开闭原则。

核心: 对系统进行抽象化,并且从抽象化导出具体化。从抽象化到具体化的过程需要使用继承关系以及下一点里氏代换原则

(三)里氏代换原则

里氏代换原则(Liskov Substitution Principle,LSP)
从抽象化到具体化的过程需要使用继承关系以及本点的里氏代换原则

定义: 第一种定义:如果每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1都代换o2时,程序P的行为没有变化,那么类型S是类型T的子类型。 第二种定义:所有引用基类(父类)的地方必须能透明地使用其子类的对象。

分析: 通俗说法,里氏代换原则指在软件中如果使用基类对象,那么一定能够使用其子类对象。把基类都替换为它的子类,程序将不会出现任何错误和异常,反过来则不成立,如果一个软件实体使用的是一个子类的话,那么它一定不能够使用基类。

(四)依赖倒转原则

依赖倒转原则(Dependence Inversion Principle,DIP)
如果说开闭原则是面向对象设计的目标的话,那么依赖倒转原则就是实现面向对象设计的主要机制。依赖倒转原则是系统抽象化的具体实现。

定义: 高层模块不应该依赖底层模块,它们都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。

分析: 代码要依赖于抽象的类,而要依赖于具体的类;要针对接口或抽象类编程,而不是针对具体类编程。当一个具体类只实现接口或抽象类中声明过的方法,而不给出多余的方法,否则在子类中增加的新方法时要修改具体类的代码。在引入抽象层后,系统将具有很好的灵活性,在程序中尽量使用抽象层进行编程,而将具体类写在配置文件中,这样一来,如果系统行为发生变化,只需要对抽象层进行扩展,并修改配置文件,而无须修改原有系统的源代码,在不修改的情况下来扩展系统的功能,满足开闭原则的要求。

(五)接口隔离原则

接口隔离原则(Interface Segregation Principle,ISP)
接口隔离原则要求我们将一些大的接口进行细化,使用多个专门的接口代替单一的总接口。

定义: 第一种定义:客户端不应该依赖那些它不需要的接口;第二种定义:一旦接口太大,则需要将它分隔成一些更小的接口,使用该接口的客户端仅需要知道与之相关的方法即可

分析: 实质上,接口隔离原则是指使用多个专门的接口,而不是使用单一的总接口。每一个接口应该承担一种相对独立的角色,不多不少,不干不该干的事,该干的事都干。

(六)合成复用原则

合成复用原则(Composite Reuse Principle,CRP)又称为组合/聚合复用原则(Composition/ Aggregate Reuse Principle,CARP)
合成复用原则是面向对象设计中非常重要的一条原则。为了降低系统中类之间的耦合度,该原则倡导在复用功能时多用关联关系,少用继承关系。

定义: 尽量使用对象组合,而不是继承来达到复用的目的。

分析: GoF提倡实现复用时更多考虑对象组合机制,而不是用类继承机制。通俗地说,合成复用机制就是指在一个新的对象里通过关联关系(包括组合关系和聚合关系)来使用一些已有的对象,使之成为新对象的一部分;新对象通过委派调用已有对象的方法达到复用其已有功能的目的,简言之,合成复用原则是要尽量使用组合/聚合关系,少用继承。

思考: 为什么不推荐用继承复用?
继承复用破坏包装,因为继承将基类的实现细节暴露给派生类,基类的内部细节通常对子类来说是可见的,这种复用也称为"白箱复用"。这里有一个明显的问题是:派生类继承自基类,如果基类的实现发生改变,将会影响到所有派生类的实现;如果从基类继承而来的实现是静态的,不可能在运行时发生改变,不够灵活。

由于合成或聚合关系可以将已有的对象,一般叫成员对象,纳入到新对象中,使之成为新对象的一部分,因此新对象可以调用已有对象的功能,这样做可以使得成员对象的内部实现细节对于新对象不可见,所以这种复用又称为"黑箱"复用,相对继承关系而言,其耦合度相对较低,成员对象的变化对新对象的影响不大,可以在新对象中根据实际需要有选择性地调用成员对象的操作;合成/聚合复用可以在运行时动态进行,新对象可以动态地引用与成员对象类型相同的其他对象。

(七)迪米特法则

迪米特法则(Law of Demeter,LoD)又称为最少知识原则(Least Knowledge Principle, LKP)
迪米特法则用于降低系统的耦合度,使类与类之间保持松散的耦合关系。

定义: 第一种定义:不要和“陌生人”讲话;第二种定义:只于你的直接朋友通信;第三种定义:每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。

分析: 类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。
最早是在1987年由美国Northeastern University的Ian Holland提出。通俗的来讲,就是一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类来说,无论逻辑多么复杂,都尽量地的将逻辑封装在类的内部,对外除了提供的public方法,不对外泄漏任何信息。迪米特法则的一个简单的定义:只与直接的朋友通信。

尽量降低类与类之间的耦合。 自从接触编程开始,就应该知道软件编程的总的原则:低耦合,高内聚。无论是面向过程编程还是面向对象编程,只有使各个模块之间的耦合尽量的低,才能提高代码的复用率。

发布了56 篇原创文章 · 获赞 70 · 访问量 8927

猜你喜欢

转载自blog.csdn.net/weixin_44835732/article/details/103596388