设计模式六大原则
单一职责原则
一个方法尽可能做一件事情,一般来说不应该让一个方法承担多个职责。
单一职责原则的英文名称是Single Responsibility Principle,简称是SRP。单一职责原则的定义是:应该有且仅有一个原因引起类的变更。
SRP的原话解释是:There should never be more than one reason for a class to change.
单一职责原则提出了一个编写程序的标准,用“职责”或“变化原因”来衡量接口或设计是否优良,但是“职责”跟“变化原因”都是不好度量的,要“因地制宜”。
单一职责适用于接口、类,同时也适用于方法,也就是说,一个方法尽可能做一件事情,一般来说不应该让一个方法承担多个职责。
里氏替换原则
子类应该能替换掉它的父类。
里氏替换原则为良好的继承定义了一个规范,一句简单的定义包含了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。子类必须能替换掉它们的父类。这样理解起来就比较顺利了。
依赖倒置原则
细节依赖抽象,低层依赖高层。
依赖倒置原则的原始定义是: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.
包含了三层含义:
1、高层模块不应该依赖低层模块,两者都应该依赖其抽象;
2、抽象不应该依赖细节;
3、细节应该依赖抽象。
这一原则在Java语言中的表现就是:
1、模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的;
2、接口或抽象类不依赖于实现类;
3、实现类依赖接口或抽象类。
一般抽象是不变的,而具体是易变的。每个较高层次都为它所需要的服务声明一个抽象接口,较低的层次实现这些抽象接口,每个高层类都通过该抽象接口使用下一层的服务,接口属于高层,低层要实现高层的接口,因此现在是低层依赖于高层。是依赖关系倒置和接口所有权的倒置。在周围环境发生变化的时候,如果设计可以做到不怎么发生改变,那这样的设计就是好的。
接口隔离原则
应该尽量建立单一接口,不要建立臃肿的接口,接口应该尽量细化。
接口隔离原则的原始定义是: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.类间的依赖关系应该建立在最小的接口上。
这两个定义概括起来就是,应该尽量建立单一接口,不要建立臃肿的接口,接口应该尽量细化。
接口分离的手段主要有以下两种:
委托分离,通过增加一个新的类型来委托客户的请求,隔离客户和接口的直接依赖,但会增加系统开销。
多重继承分离,通过接口多继承来实现客户需求。
迪米特法则
一个类应该对自己需要耦合或调用的类知道得最少。
迪米特法则(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等访问权限。
开闭原则
开闭原则要求尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来完成变化。
开闭原则的定义:
Software entities like classes,modules and functios should be open for extemsion but closed for modifications.
一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。
一个软件产品只要在生命期内,都会发生变化,既然变化是一个既定的事实,我们应该在设计时尽量适应这些变化,以提高项目的稳定性和灵活性。开闭原则要求尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来完成变化。如何做到开闭原则:抽象、封装。
三大类别
建造型设计模式
在软件工程中,创建型模式是处理对象创建的设计模式,试图根据实际情况使用合适的方式创建对象。基本的对象创建方式可能会导致设计上的问题,或增加设计的复杂度。创建型模式通过以某种方式控制对象的创建来解决问题。创建型模式由两个主导思想构成。一是将系统使用的具体类封装起来,二是隐藏这些具体类的实例创建和结合的方式。创建型模式又分为对象创建型模式和类创建型模式。对象创建型模式处理对象的创建,类创建型模式处理类的创建。详细地说,对象创建型模式把对象创建的一部分推迟到另一个对象中,而类创建型模式将它对象的创建推迟到子类中。
让子类来决定要创建哪个对象。
创建多个产品族中的产品对象。
确保某一个类只有一个实例,并且提供一个全局访问点。
用来创建复杂的复合对象。
通过复制原型来创建新对象。
结构型设计模式
结构型模式涉及到如何组合类和对象以获得更大的结构。结构型模式采用继承机制来组合接口或实现。结构型对象模式不是对接口和实现进行组合,而是描述了如何对一些对象进行组合,从而实现新功能的一些方法。因为可以在运行时刻改变对象组合关系,所以对象组合方式具有更大的灵活性。
将原来不兼容的两个类融合在一起。
将两个能够独立变化的部分分离开来。
将整体与局部(树形结构)进行递归组合,让客户端能够以一种的方式对其进行处理。
为对象添加新功能。
对外提供一个统一的接口用来访问子系统。
使用对象池来减少重复对象的创建。
控制客户端对对象的访问。
行为型设计模式
行为型模式主要是用于描述类或者对象是怎样交互和怎样分配职责的。它涉及到算法和对象间的职责分配,不仅描述对象或者类的模式,还描述了他们之间的通信方式,它将你的注意力从控制流转移到了对象间的关系上来。行为型类模式采用继承机制在类间分派行为,而行为型对象模式使用对象复合而不是继承。
将事件沿着链去处理。
将请求封装成命令,并记录下来,能够撤销与重做。
定义语法,并对其进行解释。
提供一种方法顺序访问一个聚合对象中的各个元素。
将网状结构转变为星型结构,所有行为都通过中介。
保存对象的状态,在需要时进行恢复。
状态发生改变时通知观察者,一对多的关系。
根据不同的状态做出不同的行为。
封装不同的算法,算法之间能互相替换。
定义一套流程模板,根据需要实现模板中的操作。
基于稳定数据结构,定义新的操作行为。
注:点击蓝色字体跳转至原文,《24种设计模式详解》!
3个月的设计模式篇已完结,接下来全心备战《微服务与Spring Cloud》
码字不易,点个在看,点点关注吧!
最新评论