设计模式是软件设计中常见问题的典型解决方案,是面向对象软件设计的经验总结。下面我将从原理、结构、实现和应用四个维度,全面解析GoF提出的23种经典设计模式。
一、创建型模式(5种)
1. 单例模式(Singleton)
原理:确保一个类只有一个实例,并提供全局访问点
结构:
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
演进:
-
饿汉式(类加载时初始化)
-
懒汉式(双重检查锁定)
-
静态内部类
-
枚举实现(最佳实践)
应用场景:
-
配置管理
-
日志系统
-
数据库连接池
2. 工厂方法模式(Factory Method)
原理:定义一个创建对象的接口,但让子类决定实例化哪个类
结构:
public interface Product {
void use();
}
public abstract class Creator {
public abstract Product factoryMethod();
public void operation() {
Product p = factoryMethod();
p.use();
}
}
变体:
-
简单工厂
-
多方法工厂
-
静态工厂
应用场景:
-
Spring的BeanFactory
-
JDBC的DriverManager
3. 抽象工厂模式(Abstract Factory)
原理:提供一个创建一系列相关或相互依赖对象的接口
结构:
public interface AbstractFactory {
ProductA createProductA();
ProductB createProductB();
}
public class ConcreteFactory1 implements AbstractFactory {
public ProductA createProductA() { return new ProductA1(); }
public ProductB createProductB() { return new ProductB1(); }
}
与工厂方法区别:
-
工厂方法:创建单一产品
-
抽象工厂:创建产品族
应用场景:
-
GUI组件库
-
跨平台应用
4. 建造者模式(Builder)
原理:将一个复杂对象的构建与其表示分离
结构:
public class Product {
private String part1;
private String part2;
// 构造方法私有
private Product(Builder builder) {
this.part1 = builder.part1;
this.part2 = builder.part2;
}
public static class Builder {
private String part1;
private String part2;
public Builder part1(String part1) {
this.part1 = part1;
return this;
}
public Product build() {
return new Product(this);
}
}
}
应用场景:
-
复杂对象创建
-
链式调用
-
Lombok的@Builder
5. 原型模式(Prototype)
原理:通过复制现有对象来创建新对象
结构:
public abstract class Prototype implements Cloneable {
public Prototype clone() {
try {
return (Prototype)super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}
深拷贝与浅拷贝:
-
浅拷贝:基本类型复制,引用类型共享
-
深拷贝:完全独立的对象图
应用场景:
-
对象初始化成本高
-
需要隔离对象状态
二、结构型模式(7种)
6. 适配器模式(Adapter)
原理:将一个类的接口转换成客户希望的另一个接口
结构:
public class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
public void request() {
adaptee.specificRequest();
}
}
分类:
-
类适配器(继承)
-
对象适配器(组合)
应用场景:
-
旧系统集成
-
第三方库适配
7. 桥接模式(Bridge)
原理:将抽象部分与实现部分分离,使它们可以独立变化
结构:
public abstract class Abstraction {
protected Implementor impl;
public Abstraction(Implementor impl) {
this.impl = impl;
}
public abstract void operation();
}
public interface Implementor {
void operationImpl();
}
应用场景:
-
多维度变化
-
GUI与平台分离
8. 组合模式(Composite)
原理:将对象组合成树形结构以表示"部分-整体"层次结构
结构:
public interface Component {
void operation();
void add(Component c);
void remove(Component c);
Component getChild(int i);
}
public class Leaf implements Component {
public void operation() { /* ... */ }
// 叶子节点不实现add/remove
}
public class Composite implements Component {
private List<Component> children = new ArrayList<>();
public void add(Component c) { children.add(c); }
public void operation() {
for (Component c : children) {
c.operation();
}
}
}
透明式与安全式:
-
透明式:Leaf也实现add/remove(可能抛出异常)
-
安全式:只在Composite中定义add/remove
应用场景:
-
文件系统
-
UI组件树
9. 装饰器模式(Decorator)
原理:动态地给对象添加额外职责
结构:
public abstract class Decorator implements Component {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
public void operation() {
component.operation();
}
}
public class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
public void operation() {
super.operation();
addedBehavior();
}
private void addedBehavior() { /* ... */ }
}
应用场景:
-
Java I/O流
-
Servlet过滤器
10. 外观模式(Facade)
原理:为子系统中的一组接口提供统一接口
结构:
public class Facade {
private SubSystemA a = new SubSystemA();
private SubSystemB b = new SubSystemB();
public void operation() {
a.operationA();
b.operationB();
}
}
与适配器区别:
-
适配器:接口转换
-
外观:简化接口
应用场景:
-
复杂系统封装
-
API网关
11. 享元模式(Flyweight)
原理:运用共享技术有效支持大量细粒度对象
结构:
public class FlyweightFactory {
private Map<String, Flyweight> flyweights = new HashMap<>();
public Flyweight getFlyweight(String key) {
if (!flyweights.containsKey(key)) {
flyweights.put(key, new ConcreteFlyweight(key));
}
return flyweights.get(key);
}
}
public class ConcreteFlyweight implements Flyweight {
private String intrinsicState;
public ConcreteFlyweight(String state) {
this.intrinsicState = state;
}
public void operation(String extrinsicState) { /* ... */ }
}
内蕴状态与外蕴状态:
-
内蕴:存储在享元内部,共享
-
外蕴:由客户端传入,不共享
应用场景:
-
文本编辑器
-
游戏中的粒子系统
12. 代理模式(Proxy)
原理:为其他对象提供代理以控制对这个对象的访问
结构:
public interface Subject {
void request();
}
public class RealSubject implements Subject {
public void request() { /* ... */ }
}
public class Proxy implements Subject {
private RealSubject realSubject;
public void request() {
if (realSubject == null) {
realSubject = new RealSubject();
}
preRequest();
realSubject.request();
postRequest();
}
}
分类:
-
远程代理
-
虚拟代理
-
保护代理
-
动态代理(JDK/CGLIB)
应用场景:
-
Spring AOP
-
MyBatis Mapper
三、行为型模式(11种)
13. 责任链模式(Chain of Responsibility)
原理:使多个对象都有机会处理请求
结构:
public abstract class Handler {
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract void handleRequest(Request request);
}
public class ConcreteHandler extends Handler {
public void handleRequest(Request request) {
if (canHandle(request)) {
// 处理请求
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
纯与不纯:
-
纯:处理者必须处理请求
-
不纯:可以传递请求
应用场景:
-
Servlet过滤器链
-
审批流程
14. 命令模式(Command)
原理:将请求封装为对象,支持请求排队、记录、撤销等
结构:
public interface Command {
void execute();
}
public class ConcreteCommand implements Command {
private Receiver receiver;
public ConcreteCommand(Receiver receiver) {
this.receiver = receiver;
}
public void execute() {
receiver.action();
}
}
public class Invoker {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void executeCommand() {
command.execute();
}
}
应用场景:
-
事务系统
-
宏命令
-
线程池任务队列
15. 解释器模式(Interpreter)
原理:定义语言的文法,并解释该语言中的句子
结构:
public interface Expression {
boolean interpret(String context);
}
public class TerminalExpression implements Expression {
private String data;
public TerminalExpression(String data) {
this.data = data;
}
public boolean interpret(String context) {
return context.contains(data);
}
}
public class OrExpression implements Expression {
private Expression expr1;
private Expression expr2;
public OrExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
public boolean interpret(String context) {
return expr1.interpret(context) || expr2.interpret(context);
}
}
应用场景:
-
正则表达式
-
SQL解析
-
规则引擎
16. 迭代器模式(Iterator)
原理:提供一种方法顺序访问聚合对象中的元素
结构:
public interface Iterator<T> {
boolean hasNext();
T next();
}
public interface Aggregate<T> {
Iterator<T> iterator();
}
public class ConcreteIterator implements Iterator<String> {
private String[] items;
private int position = 0;
public ConcreteIterator(String[] items) {
this.items = items;
}
public boolean hasNext() {
return position < items.length;
}
public String next() {
return items[position++];
}
}
内部迭代器与外部迭代器:
-
内部:由迭代器控制(如Stream的forEach)
-
外部:由客户端控制(如Java的Iterator)
应用场景:
-
Java集合框架
-
树形结构遍历
17. 中介者模式(Mediator)
原理:用一个中介对象封装一系列对象交互
结构:
public interface Mediator {
void notify(Colleague sender, String event);
}
public abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
}
public class ConcreteMediator implements Mediator {
private Colleague1 colleague1;
private Colleague2 colleague2;
public void setColleague1(Colleague1 colleague1) {
this.colleague1 = colleague1;
}
public void notify(Colleague sender, String event) {
if (sender == colleague1) {
colleague2.receive(event);
} else {
colleague1.receive(event);
}
}
}
应用场景:
-
GUI组件通信
-
聊天室系统
18. 备忘录模式(Memento)
原理:在不破坏封装性的前提下捕获对象内部状态并保存
结构:
public class Originator {
private String state;
public Memento save() {
return new Memento(state);
}
public void restore(Memento m) {
state = m.getState();
}
}
public class Memento {
private final String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
public class Caretaker {
private List<Memento> history = new ArrayList<>();
public void save(Originator o) {
history.add(o.save());
}
public void undo(Originator o) {
if (!history.isEmpty()) {
o.restore(history.remove(history.size()-1));
}
}
}
应用场景:
-
撤销/重做
-
游戏存档
-
事务回滚
19. 观察者模式(Observer)
原理:定义对象间一对多的依赖关系,当一个对象状态改变时,所有依赖它的对象都得到通知
结构:
public interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}
public class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
private String state;
public void setState(String state) {
this.state = state;
notifyObservers();
}
public void registerObserver(Observer o) {
observers.add(o);
}
public void notifyObservers() {
for (Observer o : observers) {
o.update(state);
}
}
}
public interface Observer {
void update(String state);
}
推模型与拉模型:
-
推:Subject主动推送数据
-
拉:Observer从Subject拉取数据
应用场景:
-
事件驱动系统
-
MVC架构
-
响应式编程
20. 状态模式(State)
原理:允许对象在内部状态改变时改变它的行为
结构:
public interface State {
void handle(Context context);
}
public class ConcreteStateA implements State {
public void handle(Context context) {
context.setState(new ConcreteStateB());
}
}
public class Context {
private State state;
public Context(State state) {
this.state = state;
}
public void request() {
state.handle(this);
}
}
与策略模式区别:
-
策略:算法可互换
-
状态:行为随状态改变
应用场景:
-
工作流引擎
-
游戏AI
21. 策略模式(Strategy)
原理:定义一系列算法,封装每个算法,并使它们可以互换
结构:
public interface Strategy {
void execute();
}
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void executeStrategy() {
strategy.execute();
}
}
应用场景:
-
排序算法
-
支付方式
-
折扣策略
22. 模板方法模式(Template Method)
原理:定义算法骨架,将某些步骤延迟到子类实现
结构:
public abstract class AbstractClass {
public final void templateMethod() {
primitiveOperation1();
primitiveOperation2();
}
protected abstract void primitiveOperation1();
protected abstract void primitiveOperation2();
}
public class ConcreteClass extends AbstractClass {
protected void primitiveOperation1() { /* ... */ }
protected void primitiveOperation2() { /* ... */ }
}
钩子方法:子类可以覆盖的可选方法
应用场景:
-
框架设计
-
算法流程固定但部分步骤可变
23. 访问者模式(Visitor)
原理:表示一个作用于某对象结构中各元素的操作
结构:
public interface Visitor {
void visit(ElementA e);
void visit(ElementB e);
}
public class ConcreteVisitor implements Visitor {
public void visit(ElementA e) {
// 对ElementA的操作
}
public void visit(ElementB e) {
// 对ElementB的操作
}
}
public interface Element {
void accept(Visitor v);
}
public class ElementA implements Element {
public void accept(Visitor v) {
v.visit(this);
}
}
双分派技术:通过两次方法调用来确定操作
应用场景:
-
编译器语法树
-
复杂对象结构操作
四、设计模式综合对比
创建型模式对比
模式 | 关注点 | 灵活性 | 复杂度 | 典型应用 |
---|---|---|---|---|
单例 | 实例控制 | 低 | 低 | 全局配置 |
工厂方法 | 子类决定实例化 | 高 | 中 | 框架扩展 |
抽象工厂 | 产品族创建 | 高 | 高 | 跨平台UI |
建造者 | 复杂对象构建 | 中 | 高 | 链式调用 |
原型 | 对象克隆 | 中 | 中 | 缓存对象 |
行为型模式对比
模式 | 交互方式 | 解耦程度 | 扩展性 | 典型应用 |
---|---|---|---|---|
观察者 | 一对多通知 | 高 | 高 | 事件系统 |
策略 | 算法替换 | 高 | 高 | 支付方式 |
状态 | 状态驱动行为 | 高 | 高 | 工作流 |
命令 | 请求封装 | 高 | 高 | 事务系统 |
责任链 | 请求传递 | 中 | 高 | 过滤器链 |