【学习笔记】大话设计模式——一些心得及各设计模式思想记录

一、思考

首先个人愚见,也有可能是太懒了,并不喜欢去记各种设计模式是怎么写的怎么做的,更倾向于遇到了实际的场景后对其进行抽象,但是抽象的时候就要满足很多的原则,好多原则和模式的思想其实不止可以用在代码中,更可以用在生活中。

个人认为这些原则是比设计模式更重要的东西,他们才是我们实用设计模式的目的,满足这些原则后,我们的代码一定是更加健壮、安全、易于维护的。

那么什么叫好代码呢?

首先是易读的,每个变量、类的名称见名知义,代码结构要清晰;其次在需要修改的时候相同的逻辑尽量只需要修改一处然后处处生效,甚至是只需要新增,不需要修改任何代码,通常代码满足开闭原则时不会存在大量的重复代码;低内聚高耦合,每个类的职责尽量单一。

通常做到以上三点在日常工作中就会少去很多叹气的时间。

二、设计原则

1.单一职责原则

定义:引起类改变的原因最好只有一个,使一个类的责任尽可能单一

优势:防止一个类太过复杂,易于维护,只需要修改相关类中的代码即可。在业务变更时更加容易定位到需要修改的地方,且修改后对其他模块产生的影响更小

2.开放-封闭原则

定义:对扩展开放、对修改封闭

优势:减少类的修改,使用新增类来代替修改原有的类,有效降低对原有代码的影响

3.依赖倒转原则

定义:高层模块不应该依赖底层模块,两个都应该依赖抽象;抽象不应该依赖细节,细节应该依赖抽象

优势:面向对象设计的核心原则,有效降低类之间的耦合度,提高代码复用度

4.里氏代换原则

定义:一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,而且它察觉不出父类对象和子类对象的区别,也就是说,在软件中将父类都替换成子类,程序的行为没有变化。【我的理解就是父类能做到的事情,子类一定可以】

优势:降低代码混乱度,提高代码复用性。

5.迪米特法则

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

优势:首先不应该在类中大量的new对象,可以考虑通过使用类字段来解决问题,或者是通过中介类解决问题,但是所有场景下都适用中介类,但使用中介类可以有效减少业务类对其他类的依赖,但是中介类太过复杂也不好维护。

6.合成/聚合复用原则

定义:尽量使用合成/聚合,尽量不要使用继承,除非从抽象的概念上看确实存在父子关系,而不是为了代码的复用

【合成是严格的部分与整体的关系,聚合是一种弱拥有关系】

优势:减少代码复杂性

7.敏捷开发原则

定义:不要为代码添加基于猜测的,实际不需要的功能,除非很确定后面系统的发展方向

优势:开发更加快速,迅捷,出现问题时可以重构,并且不要害怕重构,每次重构都是对业务模型的更加深刻的一次理解

三、设计模式

1.简单工厂模式

定义:将创建对象的工作交给工厂,通过参数来创建对象

优势:灵活、耦合度低。如果创建对象的工序很复杂的话,也可以减少创建对象的重复工作,而且引入配置文件,也可以通过改变参数来拿到不同的配置文件,而不用修改项目代码(即可以通过同一个创建对象的方法拿到不同的子类)。

2.策略模式

定义:用一个抽象类并且调用其方法来占位,具体不同的实现交给子类

优势:常见操作,主要用于调用不同的算法,可以配合lambda表达式使用

3.装饰模式

定义:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生产子类更为灵活;定义抽象父类,将被装饰类set进具体的装饰子类中,相当于一种包装

优势:与继承相比,他最大的好处是动态的,而且对于被装饰类如果可加的功能非常多,而且组合的多样性也很大的话,装饰者模式就很优于继承

4.代理模式

定义:为其它对象提供一种代理以控制对这个对象的访问,即使用的是相同的接口,用代理类控制实际对象

优势:使用一个对象时,提供一定的间接性,相当于先一步于调用者拿到该对象

5.工厂方法模式

定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类

优势:使用依赖倒转原则,使对工厂的依赖,依赖于接口,减少耦合

6.原型模式

定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象

优势:减少new对象的开销与重复代码

7.模板方法模式

定义:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义算法的某些特定步骤。【很基础的模式,spring源码中大量使用,平时工作也如此】

优势:将相同代码提到父类,父类在相同代码中调用给子类留的"口子",减少重复代码,已维护,易修改,符合面向对象开发。

8.外观模式(门面模式)

定义:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。【设计初期便要有意识的将两个不同的层分离,而层与层之间需要设计接口来调用他们】

优势:不论子系统设计的多复杂,都可以通过接口来简单的调用他们,可以让调用者更易于调用子系统而不必关心实现细节,极大降低耦合性。

9.建造者模式

定义:将一个负责对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示【设计一个建造者类,把创建主要对象的不可或缺的几步抽象成方法,每次创建对象必须时间这几个方法】

优势:创建一个对象每次都会做那几步,是对象的创建更加规范、方便。

10.观察者模式

定义:定义了一种一对多的依赖关系,让多个观察者对象同事监听某一个主题对象,这个主体对象在状态发生变化时,会通知所有观察者对象使他们自动更新自己

【将监听者注册进主题对象列表,并提供触发的方法】

优势:当一个对象状态变化时,通知其他对象也发生变化,当需要有新的对象被通知时,只需要新增一个类且让如对象列表,而不用修改变化方法主体,使各类之间保持低耦合。

11.抽象工厂模式

定义:提供一个创建一些列相关或相互依赖对象的接口,而不需要制定他们具体的类

【为工厂对象增加抽象接口,来创建不同的工厂对象,多态思想】

优势:最终目的都是为了尽可能少的膝盖程序,一次修改处处生效,以及符合开闭原则,实际情况中不一定需要这么重的工厂模式

12.状态模式

定义:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类【为类创建一系列的状态类,通过设置对象的状态,来改变对象的行为,讲不通状态的行为放到状态类中,即更改类中的状态类,即可改变行为,而不用使用if】

优势:减少if判断形成的方法,符合开闭原则

13.适配器模式

定义:将一个类的接口转换成客户希望的另一个接口,是的原本由于接口不兼容而不能一起工作的类可以一起工作【在一个类上封一层,实际调用的还是需要的方法,只是对调用方需要的返回值做了适配】

优势:使不同的类协同工作,除了调用方不受控制的情况,否则应该在设计初期就预防这样的需求发生。

14.备忘录模式

定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以将该对象恢复到原先保存的状态。

【将需要保存的属性提取成备忘录类,主要类的保存与恢复捅咕哦使用这个类来实现】

优势:将属性恢复封装到主要类中,不让调用方自己恢复属性字段,而备忘录类的封装更加大了抽象性,更符合单一职责原则

15.组合模式

定义:将对象组合成树形结构以表示部分-整体的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性【定义叶子与枝干类,是的每个对象除了可以操作自己外,还可以遍历以操作分支下的所有类】

优势:可以对单个对象和组合起来的所有对象在使用上具有一致性

16.迭代器模式

定义:提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示【定义一个迭代器接口,实现它,用来遍历集合类】

优势:可以访问集合中的所有元素,而不暴露细节

17.单例模式

定义:保证一个类只有一个实例并提供一个访问它的全局访问点

优势:减少重复创建类消耗的资源,且方便实例的管理

18.桥接模式

定义:将抽象部分与它的实现部分分离,使它们都可以独立地变化【将一个具体类中的某系功能抽象成接口,使用聚合/合成将他们组合在一起,而不是继承】

优势:符合合成/聚合复通原则

19.命令模式

定义:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤销的操作

优势:将命令抽象成接口,就可以拿到一系列命令进行统一操作,记录日志,撤销等操作

20.责任链模式

定义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。

【将处理对象抽象出来,并为每一个处理对象设置下一个递交请求的对象,处理对象只需要判断该请求是否需要自己处理并编写自己的处理方法】

优势:将长方法的多分支拆分,使得请求对象与处理对象解耦,易修改与维护,使代码符合单一职责原则与开闭原则

21.中介者模式

定义:用一个中介对象来封装一系列的对象交互【将一组对象的相互调用放到中介者对象中实现】

优势:减少每个对象间的耦合度,但增加了一个复杂的中介类(迪米特法则的实现)

22.享元模式

定义:运用享元技术有效的支持大量细粒度的对象【将一些内部状态相同,外部状态改变的对象实例共享,每次有需要时去工厂中去(如字符串常量池)】

优势:节省细粒度对象所占空间,但增加了系统复杂性

23.解释器模式

定义:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子【将文本中的字符用特定的规则来执行,比如正则使用到了解释器模式,IE浏览器解释HTML,XML的解析等等都应该用了比较简单的解释器模式】

24.访问者模式

定义:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作【将对于对象的一系列操作抽象成接口,在对象中调用接口的方法完成操作,新增操作时只需要增加操作类即可】

优势:使对象主类相对稳定,不易变化。在针对于对象主体操作容易变化时,可以使用访问者模式