Skip to content

🎨 设计模式(24种,图示 + 实战)

设计模式是抽象的经验总结。建议以“何时用、为什么、如何落地”为主线理解,每种模式都包含:本质、ASCII 图示、简明代码与实践提示。

三大类:
创建型(5):单例、工厂方法、抽象工厂、建造者、原型
结构型(7):适配器、桥接、组合、装饰、外观、享元、代理
行为型(12):责任链、命令、解释器、中介者、迭代器、备忘录、观察者、状态、策略、模板方法、访问者、备选:空对象

创建型

1. 单例(Singleton)

本质:控制实例唯一性与全局访问点。

Client → Singleton.getInstance() → 唯一实例
java
public class Singleton {
    private static volatile Singleton INSTANCE;
    private Singleton() {}
    public static Singleton getInstance() {
        if (INSTANCE == null) {
            synchronized (Singleton.class) {
                if (INSTANCE == null) INSTANCE = new Singleton();
            }
        }
        return INSTANCE;
    }
}

提示:优先枚举式单例或惰性 + DCL + volatile;注意序列化与反射攻击。

2. 工厂方法(Factory Method)

本质:将创建延迟到子类。

Creator ──factory()──▶ Product
  ▲  ▲
  │  └─ ConcreteCreatorA/B 覆盖创建
java
interface Product { String name(); }
class A implements Product { public String name(){return "A";} }
abstract class Creator { abstract Product factory(); }
class ACreator extends Creator { Product factory(){ return new A(); } }

提示:当新增产品时,仅新增具体工厂即可,遵循开闭原则。

3. 抽象工厂(Abstract Factory)

本质:同一产品族的一组工厂方法。

GUIFactory → createButton / createTextField
    ├─ WinFactory
    └─ MacFactory
java
interface Button { void draw(); }
interface TextField { void render(); }
interface GUIFactory { Button btn(); TextField tf(); }
class WinFactory implements GUIFactory { public Button btn(){return ()->{};} public TextField tf(){return ()->{};} }

提示:应对多维度变化(平台 × 组件),配合依赖注入更灵活。

4. 建造者(Builder)

本质:分步构建复杂对象,解耦“构建过程与表示”。

Director → Builder → Product
java
class User { final String name; final int age; User(String n,int a){name=n;age=a;} static class Builder{String n;int a; Builder name(String x){n=x;return this;} Builder age(int x){a=x;return this;} User build(){return new User(n,a);} } }

提示:在 Java 中常用流式 API;避免构造器参数爆炸。

5. 原型(Prototype)

本质:拷贝而非新建。

java
class Doc implements Cloneable { String text; public Doc clone(){ try{ return (Doc)super.clone(); }catch(Exception e){ throw new AssertionError(e);} } }

提示:浅拷贝/深拷贝要明确;可用序列化或 MapStruct/手写复制。

结构型

6. 适配器(Adapter)

本质:接口不匹配时的中间层。

Client → Target

         Adapter → Adaptee
java
interface Target { void call(); }
class Adaptee { void specific(){ System.out.println("legacy"); } }
class Adapter implements Target { private final Adaptee a; Adapter(Adaptee a){this.a=a;} public void call(){ a.specific(); } }

7. 桥接(Bridge)

本质:抽象与实现解耦,独立扩展。

Abstraction ──┐        Implementor
  └ RefinedAbstraction  ├─ ImplA
                         └─ ImplB
java
interface Renderer { void draw(String s); }
abstract class Shape { protected Renderer r; Shape(Renderer r){this.r=r;} abstract void render(); }
class Circle extends Shape { Circle(Renderer r){super(r);} void render(){ r.draw("circle"); } }

8. 组合(Composite)

本质:树形结构的统一对待。

Component
 ├─ Leaf
 └─ Composite → children[*]
java
interface Node { void print(); }
class Leaf implements Node { public void print(){ System.out.println("leaf"); } }
class Composite implements Node { List<Node> children=new ArrayList<>(); public void print(){ children.forEach(Node::print);} }

9. 装饰(Decorator)

本质:在不改变接口的前提下叠加行为。

Component ← Decorator ← ConcreteDecorator
java
interface Cost { int price(); }
class Base implements Cost { public int price(){ return 10; } }
class Extra implements Cost { private final Cost c; Extra(Cost c){this.c=c;} public int price(){ return c.price()+3; } }

10. 外观(Facade)

本质:为复杂子系统提供统一入口。

java
class Facade { A a; B b; C c; void doAll(){ a.x(); b.y(); c.z(); } }

11. 享元(Flyweight)

本质:共享细粒度对象,降低内存。

java
class Flyweights { private static final Map<String, Glyph> cache = new ConcurrentHashMap<>(); static Glyph of(String k){ return cache.computeIfAbsent(k, Glyph::new);} }

12. 代理(Proxy)

本质:控制访问(远程、保护、缓存、懒加载)。

java
interface Svc { String get(); }
class Real implements Svc { public String get(){ return "data"; } }
class CacheProxy implements Svc { private final Svc s; private String cache; CacheProxy(Svc s){this.s=s;} public String get(){ return cache!=null?cache:(cache=s.get()); } }

行为型

13. 责任链(Chain of Responsibility)

本质:请求在链上传递,直到被处理。

java
abstract class Handler { private Handler next; Handler next(Handler n){this.next=n; return n;} void handle(String r){ if(!doHandle(r) && next!=null) next.handle(r);} abstract boolean doHandle(String r);}

14. 命令(Command)

本质:将请求封装为对象,支持撤销/队列。

java
interface Command { void exec(); }
class Print implements Command { public void exec(){ System.out.println("hi"); } }
class Invoker { void call(Command c){ c.exec(); } }

15. 解释器(Interpreter)

本质:为语言定义文法与求值。

java
interface Expr { int eval(); }
class Num implements Expr { int v; Num(int v){this.v=v;} public int eval(){return v;} }
class Add implements Expr { Expr l,r; Add(Expr l,Expr r){this.l=l;this.r=r;} public int eval(){return l.eval()+r.eval();} }

16. 中介者(Mediator)

本质:对象通过中介沟通,降低耦合。

java
interface Bus { void send(String ch, String msg); void on(String ch, Consumer<String> c); }

17. 迭代器(Iterator)

本质:顺序访问聚合对象而无需暴露内部。

java
for (var e : list) { /* ... */ }

18. 备忘录(Memento)

本质:在不破坏封装的前提下保存与恢复状态。

java
record M(String state){}
class Caretaker { Deque<M> stack = new ArrayDeque<>(); void save(M m){stack.push(m);} M undo(){return stack.pop();} }

19. 观察者(Observer)

本质:发布-订阅,事件驱动。

java
interface Obs { void on(String msg); }
class Pub { List<Obs> os=new ArrayList<>(); void sub(Obs o){os.add(o);} void pub(String m){ os.forEach(o->o.on(m)); } }

20. 状态(State)

本质:对象在不同状态下行为不同,状态转移显式化。

[Idle] --play--> [Playing] --pause--> [Paused]
java
interface State { void handle(Player p); }
class Playing implements State { public void handle(Player p){ p.setState(new Paused()); } }
class Player { private State s; void setState(State s){this.s=s;} void press(){ s.handle(this);} }

21. 策略(Strategy)

本质:在运行期切换算法。

java
interface Pay { boolean exec(int cents); }
class Wechat implements Pay { public boolean exec(int c){ return true; } }
class Context { private Pay p; Context(Pay p){this.p=p;} boolean pay(int c){ return p.exec(c);} }

22. 模板方法(Template Method)

本质:固定流程骨架,将可变步骤延迟到子类。

java
abstract class Task { final void run(){ step1(); step2(); } abstract void step1(); abstract void step2(); }

23. 访问者(Visitor)

本质:在不改变元素类的前提下,为其增加新操作。

java
interface Visitor { void visit(File f); void visit(Dir d); }
interface NodeV { void accept(Visitor v); }

24. 空对象(Null Object)

本质:以对象替代 null,消除条件分支。

java
interface Logger { void log(String m); }
class NopLogger implements Logger { public void log(String m){} }

实战总览:用策略 + 责任链 + 装饰构建支付引擎

Request → 责任链校验 → 策略路由(微信/支付宝/…) → 装饰(限流/幂等/日志) → 网关

要点:

  • 变化隔离:算法用策略,校验用链,非功能性用装饰;
  • 组合多模式,控制复杂度;
  • 保持接口语义稳定,便于测试与替换。

对照表(何时选哪一个)

  • 创建型:对象创建复杂/多变 → 工厂/建造者;唯一性 → 单例;复制 → 原型。
  • 结构型:接口不兼容 → 适配;横向扩展功能 → 装饰;多维扩展 → 桥接;树结构 → 组合;子系统简化 → 外观;对象大量重复 → 享元;控制访问 → 代理。
  • 行为型:职责传递 → 责任链;命令可撤销/排队 → 命令;状态驱动 → 状态;算法可替换 → 策略;固定骨架 → 模板;事件驱动 → 观察者;跨类型操作 → 访问者。

掌握 24 种模式的关键在于识别“变化点与稳定点”。建议配合你的实际项目,选 2-3 个典型场景分别用两种不同组合实现并比较复杂度与演进成本。

下一步


💡 提示:模式不是目的,解决问题才是。避免机械套用。