1. 设计模式定义
1.1 什么是设计模式
在 GoF(Gang of Four)的书籍《设计模式-可复用面向对象软件的基础》中是这样定义设计模式的:“每一个模式描述了一个在我们周围不断重复发生的问题以及该问题的解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复劳动”。
一般而言,设计模式有四个基本要素:
- 模式名称(pattern name):一个助记名,它用一两个词来描述模式的问题、解决方案和效果。
- 问题(problem):描述了应该在何时使用模式。
- 解决方案(solution):描述了设计的组成成分,它们之间的相关关系以及各自的职责和协作方案。
- 效果(consequences):描述了模式应用的效果以及使用模式应该权衡的问题。
1.2 设计原则与设计模式
设计原则和设计模式的关系:
- 设计原则是指导思想,往往是高度概括性和原则性的;设计模式是实现方式,并且往往并非一种实现方式。
- 设计原则由设计模式共同遵守,一种设计模式往往采用多种设计原则。
1.3 设计原则分类
1.3.1 根据目的来分
- 创建型模式:抽象了对象的实例化过程,将对象的创建和使用分离。
- 单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式
- 结构型模式:处理类或对象的组合,实现新功能。
- 适配器模式、桥接模式、组合模式、装饰器模式、外观模式、享元模式、代理模式
- 行为型模式: 算法和对象间职责的分配,关注对象间的联系方式。
- 责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式
2. 创建型模式
2.1 单例模式(Singleton)
2.1.1 定义
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
单例模式主要解决两个问题:
- 保证一个类仅有一个实例:
- 作用:(1)防止重复创建导致的资源浪费(2)防止多个实例导致的数据同步问题
- 使用:控制某些共享资源 (例如数据库或文件) 的访问权限等
- 实现:private 修饰构造函数,在类中创建对象
- 为该实例提供一个全局访问节点:
- 作用:防止实例数据被覆盖
- 实现:提供全局访问方法
2.1.2 实现
饿汉式-线程安全
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
懒汉式-线程不安全
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
懒汉式-线程安全
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
懒汉式-双重校验锁-线程安全
public class Singleton {
private static volatile Singleton instance; // volatile 防止JVM对指令进行重排
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) { // 防止两个线程都在第一个if判断instance为null,先后进入锁创建实例
instance = new Singleton();
}
}
}
return instance;
}
}
静态内部类
使用内部类的好处是,静态内部类不会在单例加载时就加载,而是在调用 getInstance() 方法时才进行加载,而且由 JVM 提供了对线程安全的支持。
public class Singleton {
private Singleton() {
}
private static class SingletonHolder {
private static Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
枚举实现
单例模式的最佳实现,能保证只有一个实例且线程安全,并且在面对复杂的序列化或者反射攻击的时候,能够防止实例化多次,唯一缺点是无法适用继承场景。
public enum Singleton {
instance;
}
2.2 工厂方法模式(Factory Method)
2.2.1 定义
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。
2.2.2 实现
2.3 抽象工厂模式(Abstract Factory)
2.3.1 定义
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
2.3.2 实现
![img](https://img-blog.csdnimg.cn/img_convert/1465367d7993e96cedd57f3711f327fb.png)
2.4 建造者模式(Builder)
2.4.1 定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
2.4.2 实现
以下是一个简易的 StringBuilder 实现,参考了 JDK 1.8 源码。
abstract class AbstractStringBuilder {
char[] value;
int count;
AbstractStringBuilder() {
}
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
public AbstractStringBuilder append(char c) {
ensureCapacityInternal(count + 1);
value[count++] = c;
return this;
}
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0) {
value = Arrays.copyOf(value,
newCapacity(minimumCapacity));
}
}
private int expandCapacity(int minCapacity) {
int newCapacity = value.length * 2 + 2;
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0) {
if (Integer.MAX_VALUE - minCapacity < 0) // overflow
throw new OutOfMemoryError();
newCapacity = (minCapacity > MAX_ARRAY_SIZE) ? minCapacity : MAX_ARRAY_SIZE;
}
return newCapacity;
}
public abstract String toString();
}
public final class StringBuilder extends AbstractStringBuilder {
public StringBuilder() {
super(16);
}
@Override
public StringBuilder append(char c) {
super.append(c);
return this;
}
@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
}
3. 结构性模式
3.1 适配器模式(Adapter)
3.1.1 定义
将一个类的接口转换成客户希望的另外一个接口。
3.1.2 实现
3.2 桥接模式(Bridge)
3.2.1 定义
将抽象部分与它的实现部分分离,使它们都可以独立地变化。
3.2.2 实现
3.3 装饰器模式(Decorator)
3.3.1 定义
动态地给一个对象添加一些额外的职责。
3.3.2 实现
3.4 代理模式(Proxy)
3.4.1 定义
为其他对象提供一种代理以控制对这个对象的访问。
3.4.2 实现
4. 行为型模式
4.1 观察者模式(Observer)
4.1.1 定义
定义对象间的一种一对多的依赖关系 ,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
4.1.2 实现
4.2 策略模式(Strategy)
4.2.1 定义
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
4.2.2 实现
4.3 模板方法模式(Template Method)
4.3.1 定义
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
4.3.2 实现
4.4 责任链模式(Chain of Responsibility)
4.4.1 定义
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
4.4.2 实现
4.5 迭代器模式(Iterator)
4.5.1 定义
提供一种方法顺序访问一个聚合对象中各个元素 , 而又不需暴露该对象的内部表示。
4.5.2 实现
4.6 状态模式(State)
4.6.1 定义
允许一个对象在其内部状态改变时改变它的行为。
4.6.2 实现
状态模式和策略模式的区别:状态模式中特定状态知道其它状态的存在,且可以切换到其它状态;而策略模式中,一个策略并不知晓其它策略的存在。
参考资料