# 目录
- [目录](#目录)
- [六大原则](#六大原则)
- [创建型模式](#创建型模式)
- [工厂模式](#工厂模式)
- [适用场景](#适用场景)
- [模式缺点](#模式缺点)
- [样例](#样例)
- [工厂方法模式](#工厂方法模式)
- [适用场景](#适用场景-1)
- [模式缺点](#模式缺点-1)
- [样例](#样例-1)
- [抽象工厂方法模式](#抽象工厂方法模式)
- [适用场景](#适用场景-2)
- [模式缺点](#模式缺点-2)
- [样例](#样例-2)
- [单例模式](#单例模式)
- [适用场景](#适用场景-3)
- [模式缺点](#模式缺点-3)
- [样例](#样例-3)
- [建造者模式](#建造者模式)
- [适用场景](#适用场景-4)
- [模式缺点](#模式缺点-4)
- [样例](#样例-4)
- [原型模式](#原型模式)
- [适用场景](#适用场景-5)
- [模式缺点](#模式缺点-5)
- [样例](#样例-5)
- [结构型模式](#结构型模式)
- [适配器模式](#适配器模式)
- [适用场景](#适用场景-6)
- [模式缺点](#模式缺点-6)
- [样例](#样例-6)
- [桥接模式(称为嫁接更直观)](#桥接模式称为嫁接更直观)
- [适用场景](#适用场景-7)
- [模式缺点](#模式缺点-7)
- [样例](#样例-7)
- [过滤器模式](#过滤器模式)
- [适用场景](#适用场景-8)
- [模式缺点](#模式缺点-8)
- [样例](#样例-8)
- [组合模式(树型模式更贴切)](#组合模式树型模式更贴切)
- [适用场景](#适用场景-9)
- [模式缺点](#模式缺点-9)
- [样例](#样例-9)
- [装饰器模式](#装饰器模式)
- [适用场景](#适用场景-10)
- [模式缺点](#模式缺点-10)
- [样例](#样例-10)
- [外观模式](#外观模式)
- [适用场景](#适用场景-11)
- [模式缺点](#模式缺点-11)
- [样例](#样例-11)
- [享元模式](#享元模式)
- [适用场景](#适用场景-12)
- [模式缺点](#模式缺点-12)
- [样例](#样例-12)
- [代理模式](#代理模式)
- [适用场景](#适用场景-13)
- [模式缺点](#模式缺点-13)
- [样例](#样例-13)
- [行为型模式](#行为型模式)
- [责任链模式](#责任链模式)
- [适用场景](#适用场景-14)
- [模式缺点](#模式缺点-14)
- [样例](#样例-14)
- [命令模式](#命令模式)
- [适用场景](#适用场景-15)
- [模式缺点](#模式缺点-15)
- [样例](#样例-15)
- [解释器模式](#解释器模式)
- [适用场景](#适用场景-16)
- [模式缺点](#模式缺点-16)
- [样例](#样例-16)
- [迭代器模式](#迭代器模式)
- [适用场景](#适用场景-17)
- [模式缺点](#模式缺点-17)
- [样例](#样例-17)
- [中介者模式](#中介者模式)
- [适用场景](#适用场景-18)
- [模式缺点](#模式缺点-18)
- [样例](#样例-18)
- [备忘录模式](#备忘录模式)
- [适用场景](#适用场景-19)
- [模式缺点](#模式缺点-19)
- [样例](#样例-19)
- [观察者模式(或者叫发布-订阅模式)](#观察者模式或者叫发布-订阅模式)
- [适用场景](#适用场景-20)
- [模式缺点](#模式缺点-20)
- [样例](#样例-20)
- [状态模式(或者叫发布-订阅模式)](#状态模式或者叫发布-订阅模式)
- [适用场景](#适用场景-21)
- [模式缺点](#模式缺点-21)
- [样例](#样例-21)
- [空对象模式](#空对象模式)
- [适用场景](#适用场景-22)
- [模式缺点](#模式缺点-22)
- [样例](#样例-22)
- [策略模式](#策略模式)
- [适用场景](#适用场景-23)
- [模式缺点](#模式缺点-23)
- [样例](#样例-23)
- [模板模式](#模板模式)
- [适用场景](#适用场景-24)
- [模式缺点](#模式缺点-24)
- [样例](#样例-24)
- [访问者模式](#访问者模式)
- [适用场景](#适用场景-25)
- [模式缺点](#模式缺点-25)
- [样例](#样例-25)
# 六大原则
1. 开闭原则(Open Close Principle)
开闭原则的意思是:对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。
2. 里氏代换原则(Liskov Substitution Principle)
里氏代换原则是面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
3. 依赖倒转原则(Dependence Inversion Principle)
这个原则是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。
4. 接口隔离原则(Interface Segregation Principle)
这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。它还有另外一个意思是:降低类之间的耦合度。由此可见,其实设计模式就是从大型软件架构出发、便于升级和维护的软件设计思想,它强调降低依赖,降低耦合。
5. 迪米特法则,又称最少知道原则(Demeter Principle)
最少知道原则是指:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。
6. 合成复用原则(Composite Reuse Principle)
合成复用原则是指:尽量使用合成/聚合的方式,而不是使用继承。
# 创建型模式
这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。
## 工厂模式
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
### 适用场景
1. 很多地方都需要创建某种对象时。
2. 创建对象操作比较复杂,同时接口又需要统一时,同时又想要对外屏蔽时。
3. 想要能够方便地扩展类型实现时。
### 模式缺点
1. 工厂对于具体实现类型会产生依赖。
2. 类型非常多时工厂类会变得非常复杂。
### 样例
````java
public interface Shape {}
public class Circle implements Shape {}
public class Square implements Shape {}
public class ShapeFactory {
public Shape getShape1() { return new Circle(); }
public Shape getShape2() { return new Square(); }
public Shape getShape(String shape) {
switch (shape) {
case "circle": return new Circle();
case "square": return new Square();
}
return null;
}
}
````
## 工厂方法模式
工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现‘开-闭 原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。
### 适用场景
1. 同“工厂方法模式”
2. 不希望每次增加一个类型时都需要修改工厂基类时。
### 模式缺点
1. 代码结构变得更复杂了。
2. 工厂也变得更多了。
### 样例
````java
public interface Shape {}
public class Circle implements Shape {}
public class Square implements Shape {}
public interface ShapeAbstractFactory {
Shape getShape();
}
public class CircleFactory implements ShapeAbstractFactory {
public Shape getShape() { return new Circle(); }
}
public class SquareFactory implements ShapeAbstractFactory {
public Shape getShape() { return new Square(); }
}
````
## 抽象工厂方法模式
抽象工厂模式(Abstract Factory Pattern)隶属于设计模式中的创建型模式,用于产品族的构建。抽象工厂是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂是指当有多个抽象角色时使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象。
工厂模式中的每一个形态都是针对一定问题的解决方案,工厂方法针对的是一类产品;而抽象工厂模式针对的是多类产品,一类产品内又有多种实现类型的情况。
### 适用场景
1. 通常情况下产品需要成套使用。
2. 每套解决方案内部又存在多种组合解决方案。
### 模式缺点
1. 代码结构变得更复杂了。
### 样例
````java
public interface Shape {}
public class Circle implements Shape {}
public class Square implements Shape {}
public interface color {}
public class Red implements Color {}
public class Blue implements Color {}
public interface AbstractFactory {
Shape getShape();
Red getColor();
}
public class Factory1 implements AbstractFactory { ... }
public class Factory2 implements AbstractFactory { ... }
````
## 单例模式
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意:单例类只能有一个实例。
### 适用场景
1. 逻辑相对简单的情况。
2. 想要避免实例过多占用系统资源的情况。
### 模式缺点
1. 修改单例对象的属性时,需要考虑多线程和高并发场景。
### 样例
````java
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){} // 不允许通过new来实例化对象
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
````
## 建造者模式
建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。
### 适用场景
1. 对象内部较为复杂,同时需要分离对象的创建与构建行为时。
2. 一些内部基本部件相对稳定不变,而只是其组合经常变化的时候。
3. 初始化一个对象时,参数过多,或者很多参数具有默认值时。
### 模式缺点
1. 不适合创建差异性很大的产品类。
2. 如内部变化复杂,会有很多的建造类。
### 样例
````java
public interface Porudct { }
public interface Builder {
Product buildPart(Product p);
}
public interface Director {
Product getProduct();
}
````
## 原型模式
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。
### 适用场景
1. 当一个系统应该独立于它的产品创建,构成和表示时。
2. 当要实例化的类是在运行时指定时,例如,通过动态装载。
3. 为了避免一个与产品类层次平行的工厂类层次时。
4. 当一个类的实例只能有几个不同状态组合中的一种时。创建相应数目的原型并克隆它们可能比每次用何时的状态手工实例化该类更方便一些。
### 模式缺点
1. 配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。
2. 必须实现Cloneable接口。
### 样例
````java
public interface Cloneable {
Object clone();
}
````
# 结构型模式
## 适配器模式
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。
### 适用场景
1. 可以让任何两个没有关联的类一起运行。
2. 提高了类的复用。
3. 增加了类的透明度。
4. 灵活性好。
### 模式缺点
1. 过多地使用适配器,会让系统非常零乱,不易整体进行把握。
2. 由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。
### 样例
略,简单来说就是随意调用,类似于行为型地中介者模式。
## 桥接模式(称为嫁接更直观)
桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。
这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。
我们通过下面的实例来演示桥接模式(Bridge Pattern)的用法。其中,可以使用相同的抽象类方法但是不同的桥接实现类,来画出不同颜色的圆。
### 适用场景
1. 想要避免在抽象与实现之间存在永久绑定。
2. 如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
3. 对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
4. 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
### 模式缺点
1. 桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
### 样例
略,简单来说就是将多种维度的属性从继承关系转化为组合关系。
## 过滤器模式
过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准。
### 适用场景
1. 设计人员将整个系统的输入输出行为理解为单个过滤器行为的叠加与组合。这样可以将问题分解,化繁为简。
2. 任何两个过滤器,只要它们之间传送的数据遵守共同的规约就可以相连接。每个过滤器都有自己独立的输入输出接口,如果过滤器间传输的数据遵守其规约,只要用管道将它们连接就可以正常工作。
3. 整个系统易于维护和升级:旧的过滤器可以被替代,新的过滤器可以添加到已有的系统上。软件的易于维护和升级是衡量软件系统质量的重要指标之一。在管道-过滤器模型中,只要遵守输入输出数据规约,任何一个过滤器都可以被另一个新的过滤器代替,同时为增强程序功能,可以添加新的过滤器。这样,系统的可维护性和可升级性得到了保证。
4. 支持并发执行,每个过滤器作为一个单独的执行任务,可以与其它过滤器并发执行。过滤器的执行是独立的。不依赖于其它过滤器的。
### 模式缺点
1. 效率较低。
2. 过滤器如果组合情况复杂,那么会导致过滤器之间的结构变得复杂并且难以维护。
### 样例
````java
public interface Filter {
List