7个设计模式的基本原则

单一职责原则

一个类(或者大到模块,小到方法)承担的职责越多,它被复用的可能性越小。类的职责表现在数据职责行为职责。前者通过属性体现,后者通过方法体现。高内聚、低耦合。把不同的职责分离成不同的类。类不要过于庞大。

开闭原则

对扩展开发,对修改关闭。设计一个模块的时候,使得该模块可以在不被修改的前提下进行扩展。一般使用抽象化的设计原则。扩展的时候,仅仅是对抽象类的一个实现与扩展。抽象化是开闭原则的关键,或者说是可变性封装原则,即把经常改动的模块抽象化,并封装成抽象类,如果拓展功能的话,仅仅继承抽象类并实现即可。
举例说明:如果我们有一个对话界面,用户可以根据自己的喜好来调整对话界面按键的形状,可以使用封闭原则这样设计:
这里写图片描述
MyDialog不是使用某个特定的Button类,而是使用一个抽象的Button。这样,可以根据用户的需要对抽象的Button进行拓展,这样仅仅更改Button就可以满足需求了。

里氏代换原则

定义:所有能使用基类的地方必须可以透明地使用派生类

这表明派生类的功能是对基类的一个拓展,派生类包含了基类的所有特征,并在者基础上进行拓展。也就是说:软件中如果能够使用基类对象,那么一定能够使用其子类对象

意义:里氏代换原则是实现开闭原则的一个重要手段,在程序中,尽量使用基类或者抽象类实现对对象的定义,运行的时候根据需要,使派生类对基类进行替换。

上图的对话框是一个很好的说明实例。在这里添加一个司机开车的例子。
这里写图片描述
司机驾驶汽车,两者是依赖关系。但是,司机可以开任何汽车,在这里仅仅是开一般的汽车。如果要开其他的汽车,比如跑车之类的,直接让跑车继承汽车即可。根据里氏代换原则,可以用跑车代替汽车传递给司机的drive方法。

依赖倒转原则

定义:高层模块不应该依赖低层模块,它们都应该依赖抽象。抽象不应该依赖于细节,细节应该依赖于抽象定义.
另一种表述为:要针对接口编程,而不是针对实现编程

我们可以理解为代码要依赖于抽象的类,而不要依赖于具体的类;要针对接口或抽象类编程,而不是针对具体类编程。该原则也是实现开闭原则的一个重要手段。在这里再添加一个士兵的例子:
这里写图片描述
士兵有射击操作和穿不同类型的衣服的操作。射击依赖于武器,穿衣服依赖于不同的衣服。把武器和衣服设计成抽象类,比如这里的枪和炮继承于抽象的武器类,礼服和防弹背心依继承于抽象的衣服类。

接口隔离原则

如果一个接口太大,应该把这个接口分解成更小的接口。使得客户端不必依赖于它不需要的接口。或者理解成使用多个专门的接口,而不是使用一个总的接口,这个思想类似于单一职责原则。不要让接口太臃肿。一个接口只代表一个角色,接口仅仅提供客户端需要的行为。

下面这个接口就过于臃肿:
这里写图片描述

根据接口隔离原则,把这个接口分解成多个子接口,实现各自的功能:
这里写图片描述

合成复用原则

在新对象里尽量使用组合或者聚合的方式来实现一些功能,而不是使用继承。尽量使用组合/聚合,少用继承。继承会使得类之间的耦合度过高!!!如果必须使用继承,那么要严格的遵循里氏代换原则,如果继承的类不能满足里氏代换,就不考虑继承。

假设有两种不同的通信设备,都需要进行网络连接。根据合成复用的原则,应该如下设计:
这里写图片描述
手机和电脑都可以上网,但是不要继承上网这个类,而是让Connection作为这两个类的成员,如果后期需要改变链接方式,仅需要让不同的连接继承Connection即可。

迪米特原则

又称最少知识原则。一个软件实体应当尽可能少的与其他实体发生相互作用.

一个软件的“朋友”的定义:
(1) 当前对象本身(this);
(2) 以参数形式传入到当前对象方法中的对象;
(3) 当前对象的成员对象;
(4) 如果当前对象的成员对象是一个集合,那么集合中的元素也都是朋友;
(5) 当前对象所创建的对象。
不满足上述条件的对象,就不是本对象的“朋友”,不能和本对象有通信!!

在狭义的迪米特法则中,如果两个类之间不必彼此直接通信,那么这两个类就不应当发生直接的相互作用,如果其中的一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。

该法则最核心的是尽量减少类直接的关联关系!!
比如这里写图片描述
上图有Form和DAO之间的关系过于凌乱,而下图根据迪米特法则,引入中介者进行通信,降低关系复杂度。
这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_35976351/article/details/80073895