在软件开发中,设计模式(Design Patterns) 是解决常见问题的经典解决方案。它们不是具体的代码库或框架,而是经过验证的设计思想和模板,帮助我们编写更灵活、可维护、可扩展的代码。

Java 作为一门面向对象的语言,非常适合应用设计模式。本文将带你全面了解 23 种经典 GoF(Gang of Four)设计模式,并结合 Java 示例进行讲解。


一、什么是设计模式?

设计模式 = 问题 + 解决方案 + 场景

它由四位作者在《Design Patterns: Elements of Reusable Object-Oriented Software》一书中提出,总结了面向对象设计中的最佳实践。

设计模式的三要素:

  1. 模式名称(Pattern Name):便于交流。
  2. 问题(Problem):在什么情况下使用该模式?
  3. 解决方案(Solution):如何实现?类结构是怎样的?
  4. 后果(Consequences):带来的好处与代价。

使用设计模式的好处:

  • 提高代码复用性
  • 增强系统的可维护性和可扩展性
  • 降低模块间的耦合度
  • 提升团队沟通效率(有“共同语言”)

二、设计模式的三大分类

根据用途,设计模式分为三大类,共 23 种:

类别 模式数量 主要目的
创建型(Creational) 5 种 控制对象的创建过程
结构型(Structural) 7 种 组合类或对象形成更大结构
行为型(Behavioral) 11 种 定义对象间通信方式

下面我们逐一详解。


三、创建型模式(Creational Patterns)

这类模式关注如何创建对象,而不是直接使用 new 关键字,从而提高灵活性。

1. 单例模式(Singleton Pattern)

作用:确保一个类只有一个实例,并提供全局访问点。

适用场景

  • 配置管理器
  • 日志记录器
  • 线程池、连接池
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;
    }
}

✅ 注意:使用双重检查锁定 + volatile 保证线程安全。


2. 工厂方法模式(Factory Method Pattern)

作用:定义一个创建对象的接口,但让子类决定实例化哪个类。

interface Product {
    void use();
}

class ConcreteProductA implements Product {
    public void use() { System.out.println("使用产品A"); }
}

class ConcreteProductB implements Product {
    public void use() { System.out.println("使用产品B"); }
}

abstract class Factory {
    public abstract Product createProduct();
    
    public void doWork() {
        Product p = createProduct();
        p.use();
    }
}

class ConcreteFactoryA extends Factory {
    public Product createProduct() {
        return new ConcreteProductA();
    }
}

优点:符合开闭原则,新增产品无需修改工厂逻辑。


3. 抽象工厂模式(Abstract Factory Pattern)

作用:创建一系列相关或依赖对象的接口,而无需指定具体类。

interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

interface Button { void render(); }
interface Checkbox { void select(); }

class WinButton implements Button {
    public void render() { System.out.println("渲染Windows按钮"); }
}

class MacButton implements Button {
    public void render() { System.out.println("渲染Mac按钮"); }
}

class WinFactory implements GUIFactory {
    public Button createButton() { return new WinButton(); }
    public Checkbox createCheckbox() { return new WinCheckbox(); }
}

适用场景:跨平台 UI 组件库、主题系统。


4. 建造者模式(Builder Pattern)

作用:将复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。

class Computer {
    private String cpu;
    private String ram;
    private String storage;

    private Computer(Builder builder) {
        this.cpu = builder.cpu;
        this.ram = builder.ram;
        this.storage = builder.storage;
    }

    public static class Builder {
        private String cpu, ram, storage;

        public Builder setCpu(String cpu) { this.cpu = cpu; return this; }
        public Builder setRam(String ram) { this.ram = ram; return this; }
        public Builder setStorage(String storage) { this.storage = storage; return this; }

        public Computer build() { return new Computer(this); }
    }
}

// 使用
Computer pc = new Computer.Builder()
    .setCpu("i7")
    .setRam("16GB")
    .setStorage("512GB SSD")
    .build();

优点:避免构造函数参数过多,提升可读性。


5. 原型模式(Prototype Pattern)

作用:通过复制现有对象来创建新对象,而不是通过 new 创建。

class Prototype implements Cloneable {
    private String data;

    public Prototype clone() {
        try {
            return (Prototype) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }
}

适用场景:对象初始化成本高、需要动态配置时。


四、结构型模式(Structural Patterns)

这类模式关注类和对象的组合,形成更大的结构。

6. 适配器模式(Adapter Pattern)

作用:将一个类的接口转换成客户期望的另一个接口。

class EuropeanSocket {
    public void providePower() {
        System.out.println("提供220V电源");
    }
}

interface USSocket {
    void plugIn();
}

class SocketAdapter implements USSocket {
    private EuropeanSocket socket;

    public SocketAdapter(EuropeanSocket socket) {
        this.socket = socket;
    }

    public void plugIn() {
        System.out.print("转换电压 -> ");
        socket.providePower();
    }
}

适用场景:集成第三方库、旧系统迁移。


7. 装饰器模式(Decorator Pattern)

作用:动态地给对象添加功能,而不改变其结构。

interface Coffee {
    String getDescription();
    double cost();
}

class SimpleCoffee implements Coffee {
    public String getDescription() { return "咖啡"; }
    public double cost() { return 2.0; }
}

abstract class CoffeeDecorator implements Coffee {
    protected Coffee coffee;

    public CoffeeDecorator(Coffee coffee) {
        this.coffee = coffee;
    }
}

class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) { super(coffee); }

    public String getDescription() {
        return coffee.getDescription() + ", 牛奶";
    }

    public double cost() {
        return coffee.cost() + 0.5;
    }
}

// 使用
Coffee c = new MilkDecorator(new SimpleCoffee());
System.out.println(c.getDescription() + ": $" + c.cost()); // 咖啡, 牛奶: $2.5

优点:替代继承,避免类爆炸。


8. 代理模式(Proxy Pattern)

作用:为其他对象提供一种代理以控制对这个对象的访问。

interface Image {
    void display();
}

class RealImage implements Image {
    private String filename;

    public RealImage(String filename) {
        this.filename = filename;
        loadFromDisk();
    }

    private void loadFromDisk() {
        System.out.println("加载图片: " + filename);
    }

    public void display() {
        System.out.println("显示图片: " + filename);
    }
}

class ProxyImage implements Image {
    private String filename;
    private RealImage realImage;

    public ProxyImage(String filename) {
        this.filename = filename;
    }

    public void display() {
        if (realImage == null) {
            realImage = new RealImage(filename);
        }
        realImage.display();
    }
}

应用场景:懒加载、权限控制、日志记录、远程调用(RMI)。


9. 外观模式(Facade Pattern)

作用:为子系统提供一个统一的接口,简化客户端调用。

class CPU {
    public void freeze() { System.out.println("CPU 冻结"); }
    public void jump(long position) { System.out.println("跳转到地址: " + position); }
    public void execute() { System.out.println("执行指令"); }
}

class Memory {
    public void load(long position, byte[] data) {
        System.out.println("内存加载数据");
    }
}

class HardDrive {
    public byte[] read(long lba, int size) {
        System.out.println("硬盘读取数据");
        return new byte[1024];
    }
}

class ComputerFacade {
    private CPU cpu = new CPU();
    private Memory memory = new Memory();
    private HardDrive hd = new HardDrive();

    public void start() {
        cpu.freeze();
        byte[] data = hd.read(0, 1024);
        memory.load(0, data);
        cpu.jump(0);
        cpu.execute();
    }
}

// 客户端只需调用
new ComputerFacade().start();

优点:解耦复杂系统,降低使用门槛。


10. 桥接模式(Bridge Pattern)

作用:将抽象部分与实现部分分离,使它们可以独立变化。

interface Color {
    void applyColor();
}

class Red implements Color {
    public void applyColor() { System.out.println("红色"); }
}

abstract class Shape {
    protected Color color;

    public Shape(Color color) {
        this.color = color;
    }

    abstract void draw();
}

class Circle extends Shape {
    public Circle(Color color) { super(color); }

    public void draw() {
        System.out.print("圆形 - ");
        color.applyColor();
    }
}

优点:避免类层次结构爆炸,支持多维度扩展。


11. 组合模式(Composite Pattern)

作用:将对象组合成树形结构以表示“部分-整体”的层次结构。

import java.util.*;

abstract class Component {
    protected String name;

    public Component(String name) {
        this.name = name;
    }

    public abstract void operation();
}

class Leaf extends Component {
    public Leaf(String name) { super(name); }

    public void operation() {
        System.out.println("叶子节点: " + name);
    }
}

class Composite extends Component {
    private List<Component> children = new ArrayList<>();

    public Composite(String name) { super(name); }

    public void add(Component c) {
        children.add(c);
    }

    public void remove(Component c) {
        children.remove(c);
    }

    public void operation() {
        System.out.println("容器节点: " + name);
        for (Component child : children) {
            child.operation();
        }
    }
}

适用场景:文件系统、菜单树、组织架构图。


12. 享元模式(Flyweight Pattern)

作用:共享细粒度对象,减少内存使用。

class CharacterFlyweight {
    private char character;
    private String font;
    private int size;

    public CharacterFlyweight(char character, String font, int size) {
        this.character = character;
        this.font = font;
        this.size = size;
    }

    public void display(int x, int y) {
        System.out.println("显示字符 '" + character + "' at (" + x + "," + y + ")");
    }
}

class FlyweightFactory {
    private Map<String, CharacterFlyweight> pool = new HashMap<>();

    public CharacterFlyweight get(char c, String font, int size) {
        String key = c + "-" + font + "-" + size;
        return pool.computeIfAbsent(key, k -> 
            new CharacterFlyweight(c, font, size));
    }
}

适用场景:文本编辑器、大量相似对象的系统。


五、行为型模式(Behavioral Patterns)

这类模式关注对象之间的职责分配和通信机制

13. 策略模式(Strategy Pattern)

作用:定义一系列算法,封装每个算法,并使它们可互换。

interface PaymentStrategy {
    void pay(int amount);
}

class CreditCardPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("使用信用卡支付: " + amount);
    }
}

class WeChatPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("使用微信支付: " + amount);
    }
}

class ShoppingCart {
    private PaymentStrategy strategy;

    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    public void checkout(int amount) {
        strategy.pay(amount);
    }
}

优点:消除条件判断,易于扩展新策略。


14. 观察者模式(Observer Pattern)

作用:定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖者自动更新。

import java.util.*;

interface Observer {
    void update(String message);
}

class User implements Observer {
    private String name;

    public User(String name) { this.name = name; }

    public void update(String message) {
        System.out.println(name + " 收到通知: " + message);
    }
}

class Subject {
    private List<Observer> observers = new ArrayList<>();

    public void addObserver(Observer o) {
        observers.add(o);
    }

    public void notifyObservers(String msg) {
        for (Observer o : observers) {
            o.update(msg);
        }
    }
}

// 使用
Subject subject = new Subject();
subject.addObserver(new User("Alice"));
subject.addObserver(new User("Bob"));
subject.notifyObservers("系统更新啦!");

应用场景:事件监听、消息订阅、MVC 模式中的视图更新。


15. 责任链模式(Chain of Responsibility)

作用:将请求沿处理链传递,直到某个对象处理它。

abstract class Handler {
    protected Handler next;

    public void setNext(Handler next) {
        this.next = next;
    }

    public abstract void handle(Request request);
}

class Request {
    private String type;
    public Request(String type) { this.type = type; }
    public String getType() { return type; }
}

class AuthHandler extends Handler {
    public void handle(Request request) {
        System.out.println("认证检查...");
        if (next != null) next.handle(request);
    }
}

class LoggingHandler extends Handler {
    public void handle(Request request) {
        System.out.println("记录日志...");
        if (next != null) next.handle(request);
    }
}

// 使用
Handler chain = new AuthHandler();
chain.setNext(new LoggingHandler());
chain.handle(new Request("login"));

优点:解耦发送者与接收者,支持动态组合处理流程。


16. 命令模式(Command Pattern)

作用:将请求封装为对象,使其可以参数化、队列化、撤销等。

interface Command {
    void execute();
    void undo();
}

class Light {
    public void on() { System.out.println("灯打开了"); }
    public void off() { System.out.println("灯关闭了"); }
}

class LightOnCommand implements Command {
    private Light light;

    public LightOnCommand(Light light) { this.light = light; }

    public void execute() { light.on(); }
    public void undo() { light.off(); }
}

class RemoteControl {
    private Command command;

    public void setCommand(Command command) {
        this.command = command;
    }

    public void pressButton() {
        command.execute();
    }
}

应用场景:GUI 按钮、事务操作、宏命令、撤销/重做功能。


17. 状态模式(State Pattern)

作用:允许对象在其内部状态改变时改变其行为。

interface State {
    void handle(Context context);
}

class Context {
    private State state;

    public void setState(State state) {
        this.state = state;
    }

    public void request() {
        state.handle(this);
    }
}

class ConcreteStateA implements State {
    public void handle(Context context) {
        System.out.println("处于状态A");
        context.setState(new ConcreteStateB());
    }
}

class ConcreteStateB implements State {
    public void handle(Context context) {
        System.out.println("处于状态B");
        context.setState(new ConcreteStateA());
    }
}

优点:避免大量 if-else 判断状态转移。


18. 模板方法模式(Template Method Pattern)

作用:定义算法骨架,将某些步骤延迟到子类实现。

abstract class GameTemplate {
    public final void play() {
        initialize();
        startPlay();
        endPlay();
    }

    abstract void initialize();
    abstract void startPlay();
    void endPlay() {
        System.out.println("游戏结束");
    }
}

class Cricket extends GameTemplate {
    void initialize() { System.out.println("初始化棒球游戏"); }
    void startPlay() { System.out.println("开始打棒球"); }
}

应用场景:框架设计(如 Spring 中的 JdbcTemplate)。


19. 访问者模式(Visitor Pattern)

作用:在不修改类的前提下,为类增加新的操作。

interface Element {
    void accept(Visitor visitor);
}

interface Visitor {
    void visit(Book book);
    void visit(DVD dvd);
}

class Book implements Element {
    private double price;
    public Book(double price) { this.price = price; }
    public double getPrice() { return price; }
    public void accept(Visitor visitor) { visitor.visit(this); }
}

class TaxVisitor implements Visitor {
    public void visit(Book book) {
        System.out.println("图书税费: " + book.getPrice() * 0.05);
    }
    public void visit(DVD dvd) {
        System.out.println("DVD税费: " + dvd.getPrice() * 0.1);
    }
}

适用场景:报表生成、数据导出、多种操作需要遍历同一结构。


20. 中介者模式(Mediator Pattern)

作用:用一个中介对象封装一系列对象之间的交互。

interface Mediator {
    void sendMessage(String msg, Colleague colleague);
}

abstract class Colleague {
    protected Mediator mediator;
    protected String name;

    public Colleague(Mediator mediator, String name) {
        this.mediator = mediator;
        this.name = name;
    }

    public abstract void receive(String msg);
    public abstract void send(String msg);
}

class ChatRoom implements Mediator {
    public void sendMessage(String msg, Colleague colleague) {
        System.out.println(colleague.name + " 发送: " + msg);
    }
}

优点:减少对象间的直接依赖,集中管理交互逻辑。


21. 备忘录模式(Memento Pattern)

作用:在不破坏封装性的前提下,捕获并外部化一个对象的内部状态,以便以后恢复。

class Memento {
    private String state;
    public Memento(String state) { this.state = state; }
    public String getState() { return state; }
}

class Originator {
    private String state;

    public void setState(String state) { this.state = state; }
    public Memento saveState() { return new Memento(state); }
    public void restoreState(Memento m) { this.state = m.getState(); }
}

class Caretaker {
    private Stack<Memento> history = new Stack<>();
    public void push(Memento m) { history.push(m); }
    public Memento pop() { return history.pop(); }
}

应用场景:撤销功能、快照机制。


22. 迭代器模式(Iterator Pattern)

作用:提供一种方法顺序访问聚合对象中的各个元素,而又不暴露其内部表示。

interface Iterator<T> {
    boolean hasNext();
    T next();
}

interface Collection<T> {
    Iterator<T> createIterator();
}

class MyList<T> implements Collection<T> {
    private List<T> items = new ArrayList<>();

    public void add(T item) { items.add(item); }

    public Iterator<T> createIterator() {
        return new ListIterator<>(items);
    }
}

class ListIterator<T> implements Iterator<T> {
    private List<T> items;
    private int index = 0;

    public ListIterator(List<T> items) { this.items = items; }

    public boolean hasNext() { return index < items.size(); }
    public T next() { return items.get(index++); }
}

Java 中的 Iterator 接口就是典型的实现。


23. 解释器模式(Interpreter Pattern)

作用:定义语言的文法,并解释执行句子。

interface Expression {
    boolean interpret(String context);
}

class TerminalExpression implements Expression {
    private String data;

    public TerminalExpression(String data) { this.data = data; }

    public boolean interpret(String context) {
        return context.contains(data);
    }
}

适用场景:简单规则引擎、正则表达式解析(较少使用,因性能较低)。


六、总结:如何选择合适的设计模式?

问题 推荐模式
只想创建一个实例 单例模式
对象创建逻辑复杂 工厂 / 建造者
需要动态添加功能 装饰器
多种算法可切换 策略
对象状态频繁变化 状态
发布-订阅机制 观察者
请求处理流程长 责任链
避免紧耦合 适配器 / 中介者 / 门面

💡 设计模式不是银弹,过度使用会导致代码复杂化。应遵循:

  • KISS 原则(Keep It Simple, Stupid)
  • YAGNI 原则(You Aren’t Gonna Need It)
  • 先写好代码,再考虑是否需要重构为模式

参考资料

  • 《设计模式:可复用面向对象软件的基础》——GoF
  • 《Head First 设计模式》——易懂入门书
  • Refactoring Guru 网站
  • JDK 源码中的设计模式(如 java.util.Collections 使用装饰器)

🙌 感谢你读到这里!
🔍 技术之路没有捷径,但每一次阅读、思考和实践,都在悄悄拉近你与目标的距离。
💡 如果本文对你有帮助,不妨 👍 点赞、📌 收藏、📤 分享 给更多需要的朋友!
💬 欢迎在评论区留下你的想法、疑问或建议,我会一一回复,我们一起交流、共同成长 🌿
🔔 关注我,不错过下一篇干货!我们下期再见!✨

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。