设计模式之六大设计原则整理

字数 1650阅读 60

1. 单一职责原则

单一职责原则的英文名称是Single Responsibility Principle,简称是SRP。单一职责原则的定义是:应该有且仅有一个原因引起类的变更。
SRP的原话解释是:
There should never be more than one reason for a class to change.
单一职责原则提出了一个编写程序的标准,用“职责”或“变化原因”来衡量接口或设计是否优良,但是“职责”跟“变化原因”都是不好度量的,要“因地制宜”。

单一职责适用于接口、类,同时也适用于方法,也就是说,一个方法尽可能做一件事情,一般来说不应该让一个方法承担多个职责。

2. 里氏替换原则

里氏替换原则为良好的继承定义了一个规范,一句简单的定义包含了4层含义。

1、子类必须完全实现父类的方法

2、子类可以有自己的个性。

3、覆盖或实现父类的方法时输入参数可以被放大。

4、覆写或实现父类的方法时输出结果可以被缩小
即如果父类的一个方法的返回值是一个类型T,子类的相同方法(重载或覆写)的返回值为S,那么里氏替换原则就要求S必须小于等于T,也就是说,要么S和T是同一个类型,要么S是T的子类。

好像挺难理解的,查找了一些资料。著名技术作家Robert Martin在1996年为《C++ Reporter》写了一篇题为《The The Liskov Substitution Principle》的文章,专门介绍LSP。在Martin的文章中,他给了LSP一个解释:

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.

意思是:“使用指向基类的指针或引用的函数,必须能够在不知道具体派生类对象类型的情况下使用它们。”在2002年,Martin在他出版的《Agile Software Development Principles Patterns and Practices》一书中,又进一步简化为:

Subtypes must be substitutable for their base types。子类必须能替换掉它们的父类。
这样理解起来就比较顺利了。

3. 依赖倒置

依赖倒置原则的原始定义是:

High level modules should not depend upon low level modules.Both should depend upon abstractions.Abstractions should not depend upon details.Details should depend upon abstractions.

包含了三层含义:

  • 高层模块不应该依赖低层模块,两者都应该依赖其抽象;
  • 抽象不应该依赖细节;
  • 细节应该依赖抽象。

这一原则在Java语言中的表现就是:
1、模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系
是通过接口或抽象类产生的;
2、接口或抽象类不依赖于实现类;
3、实现类依赖接口或抽象类。

一般抽象是不变的,而具体是易变的。每个较高层次都为它所需要的服务声明一个抽象接口,较低的层次实现这些抽象接口,每个高层类都通过该抽象接口使用下一层的服务,接口属于高层,低层要实现高层的接口,因此现在是低层依赖于高层。是依赖关系倒置和接口所有权的倒置。在周围环境发生变化的时候,如果设计可以做到不怎么发生改变,那这样的设计就是好的。

4. 接口隔离原则

接口隔离原则的原始定义是:

Clients should not be forced to depend upon interfaces that they don't use.
客户端不应该依赖它不需要的接口。
The dependency of one class to another one should depend on the smallest possible interface.
类间的依赖关系应该建立在最小的接口上。

这两个定义概括起来就是,应该尽量建立单一接口,不要建立臃肿的接口,接口应该尽量细化。

接口分离的手段主要有以下两种:

  1. 委托分离,通过增加一个新的类型来委托客户的请求,隔离客户和接口的直接依赖,但会增加系统开销。
  2. 多重继承分离,通过接口多继承来实现客户需求。

5. 迪米特法则

迪米特法则(Law of Demeter)又叫最少知道原则(Least Knowledge Principle),1987年秋天由美国Northeastern University的Ian Holland提出,被UML的创始者之一Booch等普及。后来,因为在经典著作《 The Pragmatic Programmer》中提出而广为人知。

迪米特法则还有一个英文解释是:Only talk to your immediate friends。

一个对象应该对其他对象有最少的了解。通俗地讲,一个类应该对自己需要耦合或调用的类知道得最少。一个类公开的public属性或方法越多,修改时涉及的面也就越大,变更引起的风险扩散也就越大。在设计时需要反复衡量,是否可以减少public方法和属性,是否可以修改为private、package-private、protected等访问权限,是否可以加上final关键字等。迪米特法则要求类尽量不要对外公布太多的public方法和非静态的public变量,尽量内敛,多使用private、package-private、protected等访问权限。

6. 开闭原则

开闭原则的定义:
Software entities like classes,modules and functios should be open for extemsion but closed for modifications.

一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。一个软件产品只要在生命期内,都会发生变化,既然变化是一个既定的事实,我们应该在设计时尽量适应这些变化,以提高项目的稳定性和灵活性。开闭原则要求尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来完成变化。

如何做到开闭原则: 抽象、封装。

推荐阅读更多精彩内容