Appearance
🎨 设计模式(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
└─ MacFactoryjava
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 → Productjava
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 → Adapteejava
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
└─ ImplBjava
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 ← ConcreteDecoratorjava
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 个典型场景分别用两种不同组合实现并比较复杂度与演进成本。
下一步
💡 提示:模式不是目的,解决问题才是。避免机械套用。
