一.设计模式的六大原则
- 开闭原则(Open Close Principle)
开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。
- 里氏代换原则(Liskov Substitution Principle)
里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
- 依赖倒转原则(Dependence Inversion Principle)
这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。
- 接口隔离原则(Interface Segregation Principle)
这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。
- 迪米特法则(最少知道原则)(Demeter Principle)
为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。
- 合成复用原则(Composite Reuse Principle)
原则是尽量使用合成/聚合的方式,而不是使用继承。
二.设计模式分类
- 创建型模式
对象实例化的模式,创建型模式用于解耦对象的实例化过程。
- 结构型模式
把类或对象结合在一起形成一个更大的结构。
- 行为型模式
类和对象如何交互,及划分责任和算法。
三.创建型模式
- 工厂方法模式
- 定义一个创建对象的接口,让子类决定实例化那个类。
- 工厂方法模式包含如下角色:
抽象产品:产品对象同一的基类,或者是同一的接口
具体的产品:各个不同的实例对象类
抽象工厂:所有的子类工厂类的基类,或是同一的接口
具体的工厂子类:负责每个不同的产品对象的实际创建
- 抽象工厂模式
- 创建相关或依赖对象的家族,而无需明确指定具体类。
- 相较于工厂方法模式,抽象工厂模式的抽象工厂中可以生产多种抽象对象
- 单例模式
- 某个类只能有一个实例,提供一个全局的访问点。
- Singleton的静态属性instance中,只有instance为null的时候才创建一个实例,构造函数私有,确保每次都只创建一个,避免重复创建
- 建造者模式
- 封装一个复杂对象的构建过程,并可以按步骤构造。
- 建造者模式包含如下角色:
Builder:为创建一个产品对象的各个部件指定抽象接口
ConcreteBuilder:具体Builder实现类
Director:构造一个使用Builder接口的对象
Product:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口
- 原型模式
- 通过复制现有的实例来创建新的实例。
- 应用程序可能有某些对象的结构比较复杂,但是我们又需要频繁的使用它们,如果这个时候我们来不断的新建这个对象势必会大大损耗系统内存的,这个时候我们需要使用原型模式来对这个结构复杂又要频繁使用的对象进行克隆
- 原型模式包含如下角色:
Prototype:抽象原型类
ConcretePrototype:具体原型类
Client:客户类
四.结构型模式
- 适配器模式
- 将一个类的方法接口转换成客户希望的另外一个接口。
- 适配器模式有两种
对象适配器
接口适配器 - 适配器模式包含如下角色:
Target:目标抽象类
Adapter:适配器类
Adaptee:适配者类
Client:客户类
- 装饰器模式
- 动态的给对象添加新的功能。
- 装饰模式包含如下角色:
Component: 抽象构件
ConcreteComponent: 具体构件
Decorator: 抽象装饰类
ConcreteDecorator: 具体装饰类
- 代理模式
- 为其他对象提供一个代理以便控制这个对象的访问。
- 代理模式就是给一个对象提供一个代理,并由代理对象控制对原对象的引用。它使得客户不能直接与真正的目标对象通信。代理对象是目标对象的代表,其他需要与这个目标对象打交道的操作都是和这个代理对象在交涉。
- 代理模式包含:
静态代理
动态代理
CGlib代理 - 代理模式包含如下角色:
Subject: 抽象主题角色
Proxy: 代理主题角色
RealSubject: 真实主题角色
- 外观模式
- 对外提供一个统一的方法,来访问子系统中的一群接口。
- 它让一个应用程序中子系统间的相互依赖关系减少到了最少,它给子系统提供了一个简单、单一的屏障,客户通过这个屏障来与子系统进行通信。
- 外观模式包含如下角色:
Facade: 外观角色
SubSystem:子系统角色
- 桥接模式
- 将抽象部分和它的实现部分分离,使它们都可以独立的变化。
- 桥接模式将继承关系转化成关联关系,它降低了类与类之间的耦合度,减少了系统中类的数量,也减少了代码量
- 桥接模式包含如下角色:
Abstraction:抽象类
RefinedAbstraction:扩充抽象类
Implementor:实现类接口
ConcreteImplementor:具体实现类
- 组合模式
- 将对象组合成树形结构以表示“”部分-整体“”的层次结构。
- 组合模式包含如下角色:
Component: 抽象构件
Leaf: 叶子构件
Composite: 容器构件
Client: 客户类
- 享元模式
- 通过共享技术来有效的支持大量细粒度的对象。
- String常量池、数据库连接池、缓冲池等等都是享元模式的应用,所以说享元模式是池技术的重要实现方式.
- 享元模式包含如下角色:
Flyweight: 抽象享元类
ConcreteFlyweight: 具体享元类
UnsharedConcreteFlyweight: 非共享具体享元类
FlyweightFactory: 享元工厂类
五.行为型模式
- 策略模式
- 定义一系列算法,把他们封装起来,并且使它们可以相互替换。
- 策略模式包含如下角色:
Context: 环境类
Strategy: 抽象策略类
ConcreteStrategy: 具体策略类
- 模板方法模式
- 定义一个算法结构,而将一些步骤延迟到子类实现。
- 所谓模板方法模式就是在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
- 模板方法模式包含如下角色:
AbstractClass: 抽象类
ConcreteClass: 具体子类
- 观察者模式
- 对象间的一对多的依赖关系。
- 其实就是发布订阅模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。
- 观察者模式包含如下角色:
Subject: 目标
ConcreteSubject: 具体目标
Observer: 观察者
ConcreteObserver: 具体观察者
- 迭代模式
- 一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构。
- 所谓迭代器模式就是提供一种方法顺序访问一个聚合对象中的各个元素,而不是暴露其内部的表示。迭代器模式是将迭代元素的责任交给迭代器,而不是聚合对象,我们甚至在不需要知道该聚合对象的内部结构就可以实现该聚合对象的迭代。
- 迭代器模式包含如下角色:
Iterator: 抽象迭代器
ConcreteIterator: 具体迭代器
Aggregate: 抽象聚合类
ConcreteAggregate: 具体聚合类
- 责任链模式
- 将请求的发送者和接收者解耦,使的多个对象都有处理这个请求的机会。
- 职责链模式描述的请求如何沿着对象所组成的链来传递的。它将对象组成一条链,发送者将请求发给链的第一个接收者,并且沿着这条链传递,直到有一个对象来处理它或者直到最后也没有对象处理而留在链末尾端。
- 职责链模式包含如下角色:
Handler: 抽象处理者
ConcreteHandler: 具体处理者
Client: 客户类
- 命令模式
- 将命令请求封装为一个对象,使得可以用不同的请求来进行参数化。
- 有些时候我们想某个对象发送一个请求,但是我们并不知道该请求的具体接收者是谁,具体的处理过程是如何的,们只知道在程序运行中指定具体的请求接收者即可,对于这样将请求封装成对象的我们称之为命令模式。所以命令模式将请求封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。同时命令模式支持可撤销的操作。
- 命令模式包含如下角色:
Command: 抽象命令类
ConcreteCommand: 具体命令类
Invoker: 调用者
Receiver: 接收者
Client:客户类
- 备忘录模式
- 在不破坏封装的前提下,保持对象的内部状态。
- 备忘录模式给我们的软件提供后悔药的机制,通过它可以使系统恢复到某一特定的历史状态
- 备忘录模式包含如下角色:
Originator: 原发器
Memento: 备忘录
Caretaker: 负责人
- 状态模式
- 允许一个对象在其对象内部状态改变时改变它的行为。
- 在很多情况下我们对象的行为依赖于它的一个或者多个变化的属性,这些可变的属性我们称之为状态,也就是说行为依赖状态,即当该对象因为在外部的互动而导致他的状态发生变化,从而它的行为也会做出相应的变化。
- 状态模式包含如下角色:
Context: 环境类
State: 抽象状态类
ConcreteState: 具体状态类
- 访问者模式
- 在不改变数据结构的前提下,增加作用于一组对象元素的新功能。
- 在我们软件开发中我们可能会对同一个对象有不同的处理,如果我们都做分别的处理,将会产生灾难性的错误。对于这种问题,访问者模式提供了比较好的解决方案。访问者模式即表示一个作用于某对象结构中的各元素的操作,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
- 访问者模式包含如下角色:
Vistor: 抽象访问者
ConcreteVisitor: 具体访问者
Element: 抽象元素
ConcreteElement: 具体元素
ObjectStructure: 对象结构
- 中介者模式
- 用一个中介对象来封装一系列的对象交互。
- 中介者模式就是用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。在中介者模式中,中介对象用来封装对象之间的关系,各个对象可以不需要知道具体的信息通过中介者对象就可以实现相互通信。(各种中介机构工作模式)
- Mediator: 抽象中介者
ConcreteMediator: 具体中介者
Colleague: 抽象同事类
ConcreteColleague: 具体同事类
- 解释器模式
- 给定一个语言,定义它的文法的一种表示,并定义一个解释器。
- 所谓解释器模式就是定义语言的文法,并且建立一个解释器来解释该语言中的句子。解释器模式描述了如何构成一个简单的语言解释器,主要应用在使用面向对象语言开发的编译器中。它描述了如何为简单的语言定义一个文法,如何在该语言中表示一个句子,以及如何解释这些句子。
- AbstractExpression: 抽象表达式
TerminalExpression: 终结符表达式
NonterminalExpression: 非终结符表达式
Context: 环境类
Client: 客户类
六.参考资料
1.JAVA设计模式总结之23种设计模式
2.设计模式UML模型图
3.GitHub Jasonandy/patterns
七.欢迎关注我的公众号 编译未来
- 分享Java学习历程