设计模式简介
设计模式简介
概要
1995年,有四位小伙伴合著了一本书,书名叫做《设计模式:可复用面向对象软件的基础》里面共收录了23种设计模式。
这23种设计模式,又可以根据设计的目的,分三大类型:创建型、结构型、行为型。下面分别来介绍各个类型下的设计模式。
每一个类型所包含的具体设计模式,总结在下图当中:
下面分别来介绍各个类型下的设计模式。
一、创建型模式(5 种)
这一类设计模式的目的是用于创建对象。
包含了5种设计模式:
1. 工厂方法模式:子类决定实例化
2. 抽象工厂模式:抽象接口
3. 单例模式: 唯一实例
4. 原型模式: 原型实例,拷贝
5. 建造者模式:类和构造分离
二、结构型模式(7 种)
这一类设计模式的目的是优化不同类、对象、接口之间的结构关系。
包含了7种设计模式:
代理模式:代理控制
装饰器模式:附加职责
桥接模式:抽象和实现分离
组合模式:整体-不分,树形结构
适配器模式:转换,兼容接口
外观模式:对外统一接口
享元模式:细粒度,共享
其中有两组设计模式很相似,但是侧重点和适用场景各有不同,如下:
1) 装饰器模式和代理模式很相似,不同点是装饰器模式关注增强功能,代理模式关注控制访问;
2)适配器模式和桥接模式很相似,不同点是适配器模式是事后补救,把不兼容接口适配起来,桥接是预设设计,将实现与抽象分类,支持独立扩展
三、行为型模式(11 种)
这一类设计模式的目的是更好地实现类与类之间的交互以及算法的执行。包含了 11 种设计模式:
1. 观察者模式:通知、自动更新
2. 策略模式:算法替换
3. 命令模式:日志记录,可撤销
4. 状态模式:状态变成类
5. 备忘录模式:保存,恢复
6. 解释器模式:解释器,虚拟机
7. 迭代器模式:顺序访问,不暴露内部
8. 中介者模式:不直接引用
9. 访问者模式:数据和操作分离
10. 模版方法模式: 模版方法
11. 职责链模式:传递请求,职责链接
其中有两组设计模式很相似,但是侧重点和适用场景各有不同,如下:
1)策略模式 VS 状态模式,都是通过“上下文 + 接口 + 实现类”组合方式实现行为的封装和变化,利用多态动态改变行为。区别是策略模式侧重外部控制来决定选择哪种策略,状态模式侧重自动或内部决定,且不同状态之间有“流程依赖”。
2)职责链模式 VS 命令模式,都涉及“请求的处理”与“请求者和处理者的解耦”,区别是职责链模式侧重多个候选处理者,命令模式侧重请求封装与调用解耦。
3)观察者模式 VS 中介者模式,都涉及处理多个对象之间的交互关系,并解耦组件之间的直接通信。观察者模式侧重以“主题-订阅者”方式实现一对多依赖,中介者模式侧重所有组件通过一个中介进行交互,强调中心化协调,各组件不直接引用彼此。
四、常用的设计模式
常用的有单例模式、工厂模式、观察者模式、建造者模式、策略模式、模版方法模式、装饰器模式、职责链模式等
PS:补充一下面向对象的设计原则
1. 依赖倒置原则
依赖倒置原则(Dependency Inversion Principle,简称DIP)是面向对象设计中的一条原则,它是面向对象设计中的五个SOLID原则之一。该原则提出了两个关键思想:
高层模块不应该依赖于底层模块,两者都应该依赖于抽象。
抽象不应该依赖于具体,具体应该依赖于抽象。
说明:依赖倒置原则的目的是实现模块之间的松耦合,提高系统的可维护性、可扩展性和可复用性。通过引入抽象层,高层次的模块不需要关心底层模块的具体实现细节,只需要依赖于抽象接口。
这样,当底层模块发生变化时,高层模块不受影响,只需要保持对抽象的依赖关系。
2. 里氏替换原则
定义:子类型必须能够替换掉他们的父类型 分析:子类拥有父类所有非private的行为和属性,正因为有了里氏替换原则,使得继承复用成为了可能,只有当子类可以替换掉父类,软件单位的功能不受到影响时,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为。
正是由于子类的可替换性才使得父类类型的模块在无需修改的情况下就可以扩展
3. 迪米特原则
也叫最少知道原则,迪米特法则强调了类之间的松耦合
定义: 如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用
分析:类之间的耦合越弱,越有利于复用,一个处在弱耦合的类被修改,不会对有关系的类造成波及。
4. 开闭原则
一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。即一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化。
在程序中对“扩展”开放,对“修改”封闭。如果每次业务改动都要增加新的if-else,就涉及对旧有代码的修改,不但容易出错,可读性也不好。