Skip to content
On this page

Java 设计模式大揭秘:23 种模式全解析

📚 设计模式分类

Java 设计模式分为三大类,就像美食界的"中餐、西餐、日料",各有特色:

一、创建型模式(5 种):解决"生孩子"的问题

1. 单例模式(Singleton)

比喻:就像国家总统,一个国家只能有一个总统,所有部门都找同一个人办事。

应用场景:日志管理器、数据库连接池、配置中心(一个系统里只需要一个实例)。

代码示例

java
// 枚举单例(最推荐的方式,线程安全,防止反射攻击)
public enum Singleton {
    INSTANCE;

    public String getConfig() {
        return "配置信息";
    }
}

// 使用
Singleton instance = Singleton.INSTANCE;
System.out.println(instance.getConfig()); // 输出:配置信息

为什么好:避免资源浪费,防止多个实例导致冲突,代码简洁。

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

比喻:就像点外卖,你只需要说"我要一份披萨",不用关心是哪家店做的。

应用场景:对象创建逻辑复杂,需要解耦创建和使用。

代码示例

java
// 产品接口
interface Car {
    void drive();
}

// 具体产品
class SUV implements Car {
    public void drive() {
        System.out.println("越野车行驶");
    }
}

// 工厂类
class CarFactory {
    public Car createCar(String type) {
        if ("SUV".equals(type)) {
            return new SUV();
        }
        return null;
    }
}

// 使用
Car myCar = new CarFactory().createCar("SUV");
myCar.drive(); // 输出:越野车行驶

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

比喻:就像苹果生态,iPhone 和 AirPods 一起卖,小米手机和耳机一起卖。

应用场景:需要创建相关产品家族。

代码示例

java
interface Phone {
    void call();
}

interface Earphone {
    void play();
}

// 苹果产品家族
class iPhone implements Phone {
    public void call() {
        System.out.println("iPhone打电话");
    }
}

class AirPods implements Earphone {
    public void play() {
        System.out.println("AirPods播放音乐");
    }
}

// 工厂接口
interface TechFactory {
    Phone createPhone();
    Earphone createEarphone();
}

// 苹果工厂
class AppleFactory implements TechFactory {
    public Phone createPhone() {
        return new iPhone();
    }

    public Earphone createEarphone() {
        return new AirPods();
    }
}

// 使用
TechFactory appleFactory = new AppleFactory();
Phone phone = appleFactory.createPhone();
Earphone earphone = appleFactory.createEarphone();
phone.call(); // iPhone打电话
earphone.play(); // AirPods播放音乐

4. 建造者模式(Builder)

比喻:就像点咖啡,你告诉店员"要大杯、热的、加奶、不加糖",店员按照你的要求制作。

应用场景:对象创建过程复杂,参数多且有依赖关系。

代码示例

java
class Coffee {
    private int size;
    private boolean hot;
    private boolean milk;
    private boolean sugar;

    private Coffee(Builder builder) {
        this.size = builder.size;
        this.hot = builder.hot;
        this.milk = builder.milk;
        this.sugar = builder.sugar;
    }

    public static class Builder {
        private int size;
        private boolean hot = true;
        private boolean milk;
        private boolean sugar;

        public Builder size(int size) {
            this.size = size;
            return this;
        }

        public Builder hot(boolean hot) {
            this.hot = hot;
            return this;
        }

        public Builder milk(boolean milk) {
            this.milk = milk;
            return this;
        }

        public Builder sugar(boolean sugar) {
            this.sugar = sugar;
            return this;
        }

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

    @Override
    public String toString() {
        return "Coffee{" +
                "size=" + size +
                ", hot=" + hot +
                ", milk=" + milk +
                ", sugar=" + sugar +
                '}';
    }
}

// 使用
Coffee coffee = new Coffee.Builder()
        .size(300)
        .hot(false)
        .milk(true)
        .sugar(false)
        .build();
System.out.println(coffee); // Coffee{size=300, hot=false, milk=true, sugar=false}

5. 原型模式(Prototype)

比喻:就像复印机,你只需要一张纸,就可以快速复制出多份相同内容。

应用场景:创建对象成本高,需要快速复制已有对象。

代码示例

java
class Shape implements Cloneable {
    private String type;

    public Shape(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

// 使用
Shape circle = new Shape("Circle");
Shape clonedCircle = (Shape) circle.clone();
System.out.println(clonedCircle.getType()); // Circle

二、结构型模式(7 种):解决"如何组合"的问题

6. 适配器模式(Adapter)

比喻:就像手机充电器的转接头,把不同接口的充电口转换成通用的。

应用场景:将不兼容的接口转换成兼容的接口。

代码示例

java
// 目标接口
interface MediaPlayer {
    void play(String audioType, String fileName);
}

// 适配者
class AdvancedMediaPlayer {
    public void playVlc(String fileName) {
        System.out.println("Playing vlc file. Name: " + fileName);
    }

    public void playMp4(String fileName) {
        System.out.println("Playing mp4 file. Name: " + fileName);
    }
}

// 适配器
class MediaAdapter implements MediaPlayer {
    private AdvancedMediaPlayer advancedMediaPlayer;

    public MediaAdapter(String audioType) {
        if ("vlc".equalsIgnoreCase(audioType)) {
            advancedMediaPlayer = new AdvancedMediaPlayer();
        } else if ("mp4".equalsIgnoreCase(audioType)) {
            advancedMediaPlayer = new AdvancedMediaPlayer();
        }
    }

    @Override
    public void play(String audioType, String fileName) {
        if ("vlc".equalsIgnoreCase(audioType)) {
            advancedMediaPlayer.playVlc(fileName);
        } else if ("mp4".equalsIgnoreCase(audioType)) {
            advancedMediaPlayer.playMp4(fileName);
        }
    }
}

// 使用
MediaPlayer mediaPlayer = new MediaAdapter("vlc");
mediaPlayer.play("vlc", "movie.vlc"); // Playing vlc file. Name: movie.vlc

7. 装饰模式(Decorator)

比喻:就像披萨,基础披萨是核心,加芝士、火腿、蘑菇都是装饰。

应用场景:动态地给对象添加职责,不使用继承。

代码示例

java
// 组件接口
interface Coffee {
    String getDescription();
    double cost();
}

// 具体组件
class SimpleCoffee implements Coffee {
    @Override
    public String getDescription() {
        return "Simple Coffee";
    }

    @Override
    public double cost() {
        return 1.0;
    }
}

// 装饰器
abstract class CoffeeDecorator implements Coffee {
    protected Coffee coffee;

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

    @Override
    public String getDescription() {
        return coffee.getDescription();
    }

    @Override
    public double cost() {
        return coffee.cost();
    }
}

// 具体装饰器
class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return super.getDescription() + ", Milk";
    }

    @Override
    public double cost() {
        return super.cost() + 0.5;
    }
}

// 使用
Coffee coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee);
System.out.println(coffee.getDescription()); // Simple Coffee, Milk
System.out.println(coffee.cost()); // 1.5

8. 外观模式(Facade)

比喻:就像手机 APP,你不需要知道手机内部怎么运作,只需要点几个按钮。

应用场景:为复杂的子系统提供一个统一的接口。

代码示例

java
// 子系统
class CPU {
    public void start() {
        System.out.println("CPU is starting...");
    }
}

class Memory {
    public void load() {
        System.out.println("Memory is loading...");
    }
}

class HardDrive {
    public void read() {
        System.out.println("Hard drive is reading...");
    }
}

// 外观
class ComputerFacade {
    private CPU cpu;
    private Memory memory;
    private HardDrive hardDrive;

    public ComputerFacade() {
        this.cpu = new CPU();
        this.memory = new Memory();
        this.hardDrive = new HardDrive();
    }

    public void start() {
        cpu.start();
        memory.load();
        hardDrive.read();
        System.out.println("Computer started successfully!");
    }
}

// 使用
ComputerFacade computer = new ComputerFacade();
computer.start();
// 输出:
// CPU is starting...
// Memory is loading...
// Hard drive is reading...
// Computer started successfully!

9. 代理模式(Proxy)

比喻:就像经纪人,你不需要直接和明星接触,通过经纪人就能安排见面。

应用场景:控制对对象的访问,如权限控制、延迟加载。

代码示例

java
// 接口
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("Loading " + fileName);
    }

    @Override
    public void display() {
        System.out.println("Displaying " + fileName);
    }
}

// 代理
class ProxyImage implements Image {
    private RealImage realImage;
    private String fileName;

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

    @Override
    public void display() {
        if (realImage == null) {
            realImage = new RealImage(fileName);
        }
        realImage.display();
    }
}

// 使用
Image image = new ProxyImage("test.jpg");
image.display(); // Loading test.jpg, Displaying test.jpg
image.display(); // Displaying test.jpg (不再加载,直接显示)

10. 桥接模式(Bridge)

比喻:就像手机和 SIM 卡,手机(抽象)和 SIM 卡(实现)可以分离。

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

代码示例

java
// 实现类接口
interface Implementor {
    void operationImpl();
}

// 具体实现
class ConcreteImplementorA implements Implementor {
    @Override
    public void operationImpl() {
        System.out.println("ConcreteImplementorA operation");
    }
}

class ConcreteImplementorB implements Implementor {
    @Override
    public void operationImpl() {
        System.out.println("ConcreteImplementorB operation");
    }
}

// 抽象类
abstract class Abstraction {
    protected Implementor implementor;

    public Abstraction(Implementor implementor) {
        this.implementor = implementor;
    }

    public abstract void operation();
}

// 扩展抽象类
class RefinedAbstraction extends Abstraction {
    public RefinedAbstraction(Implementor implementor) {
        super(implementor);
    }

    @Override
    public void operation() {
        System.out.println("RefinedAbstraction operation");
        implementor.operationImpl();
    }
}

// 使用
Implementor implementorA = new ConcreteImplementorA();
Abstraction abstraction = new RefinedAbstraction(implementorA);
abstraction.operation();
// 输出:
// RefinedAbstraction operation
// ConcreteImplementorA operation

11. 组合模式(Composite)

比喻:就像一棵树,有根节点、分支节点和叶子节点,但可以统一处理。

应用场景:表示对象的"整体-部分"层次结构。

代码示例

java
// 组件
abstract class Component {
    protected String name;

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

    public abstract void add(Component component);
    public abstract void remove(Component component);
    public abstract void display(int depth);
}

// 叶子节点
class Leaf extends Component {
    public Leaf(String name) {
        super(name);
    }

    @Override
    public void add(Component component) {
        System.out.println("Cannot add to a leaf");
    }

    @Override
    public void remove(Component component) {
        System.out.println("Cannot remove from a leaf");
    }

    @Override
    public void display(int depth) {
        System.out.println("-".repeat(depth) + name);
    }
}

// 组合节点
class Composite extends Component {
    private List<Component> children = new ArrayList<>();

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

    @Override
    public void add(Component component) {
        children.add(component);
    }

    @Override
    public void remove(Component component) {
        children.remove(component);
    }

    @Override
    public void display(int depth) {
        System.out.println("-".repeat(depth) + name);
        for (Component child : children) {
            child.display(depth + 2);
        }
    }
}

// 使用
Component root = new Composite("Root");
Component branch1 = new Composite("Branch1");
Component leaf1 = new Leaf("Leaf1");
Component leaf2 = new Leaf("Leaf2");

branch1.add(leaf1);
branch1.add(leaf2);
root.add(branch1);

root.display(0);
// 输出:
// Root
//   Branch1
//     Leaf1
//     Leaf2

12. 享元模式(Flyweight)

比喻:就像图书馆的书籍,很多读者看同一本书,但不需要为每个人复制一本。

应用场景:共享大量细粒度对象,减少内存占用。

代码示例

java
// 享元
interface Flyweight {
    void operation(String extrinsicState);
}

// 具体享元
class ConcreteFlyweight implements Flyweight {
    private String intrinsicState;

    public ConcreteFlyweight(String intrinsicState) {
        this.intrinsicState = intrinsicState;
    }

    @Override
    public void operation(String extrinsicState) {
        System.out.println("Intrinsic: " + intrinsicState + ", Extrinsic: " + extrinsicState);
    }
}

// 享元工厂
class FlyweightFactory {
    private Map<String, Flyweight> flyweights = new HashMap<>();

    public Flyweight getFlyweight(String intrinsicState) {
        if (!flyweights.containsKey(intrinsicState)) {
            flyweights.put(intrinsicState, new ConcreteFlyweight(intrinsicState));
        }
        return flyweights.get(intrinsicState);
    }
}

// 使用
FlyweightFactory factory = new FlyweightFactory();
Flyweight flyweight1 = factory.getFlyweight("A");
Flyweight flyweight2 = factory.getFlyweight("B");
Flyweight flyweight3 = factory.getFlyweight("A");

flyweight1.operation("X"); // Intrinsic: A, Extrinsic: X
flyweight2.operation("Y"); // Intrinsic: B, Extrinsic: Y
flyweight3.operation("Z"); // Intrinsic: A, Extrinsic: Z

三、行为型模式(11 种):解决"如何交互"的问题

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

比喻:就像公司审批流程,小问题找部门经理,大问题找总监,最终找 CEO。

应用场景:多个对象可以处理请求,但具体哪个对象处理未知。

代码示例

java
// 处理者接口
abstract class Handler {
    protected Handler successor;

    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    public abstract void handleRequest(String request);
}

// 具体处理者
class Manager extends Handler {
    @Override
    public void handleRequest(String request) {
        if ("salary".equals(request)) {
            System.out.println("Manager handles salary request");
        } else if (successor != null) {
            successor.handleRequest(request);
        }
    }
}

class Director extends Handler {
    @Override
    public void handleRequest(String request) {
        if ("project".equals(request)) {
            System.out.println("Director handles project request");
        } else if (successor != null) {
            successor.handleRequest(request);
        }
    }
}

// 使用
Handler manager = new Manager();
Handler director = new Director();
manager.setSuccessor(director);

manager.handleRequest("salary"); // Manager handles salary request
manager.handleRequest("project"); // Director handles project request

14. 命令模式(Command)

比喻:就像点餐,你点菜(命令)给服务员(调用者),服务员传给厨师(接收者)。

应用场景:将请求封装为对象,实现解耦。

代码示例

java
// 命令接口
interface Command {
    void execute();
}

// 接收者
class Light {
    public void turnOn() {
        System.out.println("Light is on");
    }

    public void turnOff() {
        System.out.println("Light is off");
    }
}

// 具体命令
class TurnOnLightCommand implements Command {
    private Light light;

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

    @Override
    public void execute() {
        light.turnOn();
    }
}

class TurnOffLightCommand implements Command {
    private Light light;

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

    @Override
    public void execute() {
        light.turnOff();
    }
}

// 调用者
class RemoteControl {
    private Command command;

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

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

// 使用
Light light = new Light();
Command turnOn = new TurnOnLightCommand(light);
Command turnOff = new TurnOffLightCommand(light);

RemoteControl remote = new RemoteControl();
remote.setCommand(turnOn);
remote.pressButton(); // Light is on

remote.setCommand(turnOff);
remote.pressButton(); // Light is off

15. 解析器模式(Interpreter)

比喻:就像语言翻译,把自然语言转换成计算机能理解的指令。

应用场景:定义语言的文法,并解释该语言的句子。

代码示例

java
// 表达式接口
interface Expression {
    boolean interpret(String context);
}

// 终结符表达式
class TerminalExpression implements Expression {
    private String data;

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

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

// 非终结符表达式
class OrExpression implements Expression {
    private Expression expr1;
    private Expression expr2;

    public OrExpression(Expression expr1, Expression expr2) {
        this.expr1 = expr1;
        this.expr2 = expr2;
    }

    @Override
    public boolean interpret(String context) {
        return expr1.interpret(context) || expr2.interpret(context);
    }
}

// 使用
Expression isMale = new TerminalExpression("Male");
Expression isMarried = new TerminalExpression("Married");

Expression expression = new OrExpression(isMale, isMarried);
System.out.println(expression.interpret("Male")); // true
System.out.println(expression.interpret("Married")); // true
System.out.println(expression.interpret("Single")); // false

16. 迭代器模式(Iterator)

比喻:就像翻书,你不需要知道书的内部结构,只需要按顺序一页页翻。

应用场景:提供一种方法顺序访问一个聚合对象的各个元素。

代码示例

java
// 迭代器接口
interface Iterator {
    boolean hasNext();
    Object next();
}

// 聚合
interface Aggregate {
    Iterator createIterator();
}

// 具体迭代器
class BookShelfIterator implements Iterator {
    private BookShelf bookShelf;
    private int index;

    public BookShelfIterator(BookShelf bookShelf) {
        this.bookShelf = bookShelf;
        this.index = 0;
    }

    @Override
    public boolean hasNext() {
        return index < bookShelf.getSize();
    }

    @Override
    public Object next() {
        Book book = bookShelf.getBook(index);
        index++;
        return book;
    }
}

// 具体聚合
class BookShelf implements Aggregate {
    private List<Book> books = new ArrayList<>();

    public void addBook(Book book) {
        books.add(book);
    }

    public Book getBook(int index) {
        return books.get(index);
    }

    public int getSize() {
        return books.size();
    }

    @Override
    public Iterator createIterator() {
        return new BookShelfIterator(this);
    }
}

// 使用
BookShelf bookShelf = new BookShelf();
bookShelf.addBook(new Book("Book1"));
bookShelf.addBook(new Book("Book2"));
bookShelf.addBook(new Book("Book3"));

Iterator iterator = bookShelf.createIterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next()); // Book1, Book2, Book3
}

17. 中介者模式(Mediator)

比喻:就像微信群,大家不需要直接互相联系,只需要通过群主(中介者)沟通。

应用场景:用一个中介对象来封装一系列对象之间的交互。

代码示例

java
// 中介者
interface Mediator {
    void send(String message, Colleague colleague);
}

// 同事
abstract class Colleague {
    protected Mediator mediator;

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

    public abstract void receive(String message);
}

// 具体同事
class ConcreteColleague1 extends Colleague {
    public ConcreteColleague1(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void receive(String message) {
        System.out.println("Colleague1 received: " + message);
    }

    public void send(String message) {
        mediator.send(message, this);
    }
}

class ConcreteColleague2 extends Colleague {
    public ConcreteColleague2(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void receive(String message) {
        System.out.println("Colleague2 received: " + message);
    }

    public void send(String message) {
        mediator.send(message, this);
    }
}

// 具体中介者
class ConcreteMediator implements Mediator {
    private ConcreteColleague1 colleague1;
    private ConcreteColleague2 colleague2;

    public void setColleague1(ConcreteColleague1 colleague1) {
        this.colleague1 = colleague1;
    }

    public void setColleague2(ConcreteColleague2 colleague2) {
        this.colleague2 = colleague2;
    }

    @Override
    public void send(String message, Colleague colleague) {
        if (colleague == colleague1) {
            colleague2.receive(message);
        } else {
            colleague1.receive(message);
        }
    }
}

// 使用
ConcreteMediator mediator = new ConcreteMediator();
ConcreteColleague1 colleague1 = new ConcreteColleague1(mediator);
ConcreteColleague2 colleague2 = new ConcreteColleague2(mediator);
mediator.setColleague1(colleague1);
mediator.setColleague2(colleague2);

colleague1.send("Hello from Colleague1"); // Colleague2 received: Hello from Colleague1
colleague2.send("Hello from Colleague2"); // Colleague1 received: Hello from Colleague2

18. 备忘录模式(Memento)

比喻:就像游戏存档,你可以随时保存状态,需要时恢复。

应用场景:在不破坏封装性的前提下,捕获并外部化对象的内部状态。

代码示例

java
// 备忘录
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 String getState() {
        return state;
    }

    public Memento saveStateToMemento() {
        return new Memento(state);
    }

    public void getStateFromMemento(Memento memento) {
        state = memento.getState();
    }
}

// 管理者
class CareTaker {
    private List<Memento> mementoList = new ArrayList<>();

    public void addMemento(Memento memento) {
        mementoList.add(memento);
    }

    public Memento getMemento(int index) {
        return mementoList.get(index);
    }
}

// 使用
Originator originator = new Originator();
CareTaker careTaker = new CareTaker();

originator.setState("State1");
careTaker.addMemento(originator.saveStateToMemento());

originator.setState("State2");
careTaker.addMemento(originator.saveStateToMemento());

originator.setState("State3");
System.out.println("Current State: " + originator.getState()); // State3

originator.getStateFromMemento(careTaker.getMemento(0));
System.out.println("Restored State: " + originator.getState()); // State1

19. 观察者模式(Observer)

比喻:就像天气预报,你订阅了天气,天气变化时会收到通知。

应用场景:当对象间存在一对多的依赖关系时。

代码示例

java
// 观察者
interface Observer {
    void update(String message);
}

// 主题
interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

// 具体主题
class WeatherData implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private float temperature;

    public void setTemperature(float temperature) {
        this.temperature = temperature;
        notifyObservers();
    }

    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update("Temperature: " + temperature);
        }
    }
}

// 具体观察者
class TemperatureDisplay implements Observer {
    @Override
    public void update(String message) {
        System.out.println("TemperatureDisplay: " + message);
    }
}

class WeatherStation {
    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();
        Observer display = new TemperatureDisplay();

        weatherData.registerObserver(display);
        weatherData.setTemperature(25.5f); // TemperatureDisplay: Temperature: 25.5
    }
}

20. 状态模式(State)

比喻:就像手机状态,待机、通话、游戏,不同状态下功能不同。

应用场景:对象的行为依赖于它的状态,并且可以运行时改变状态。

代码示例

java
// 状态接口
interface State {
    void handleRequest();
}

// 具体状态
class ConcreteStateA implements State {
    @Override
    public void handleRequest() {
        System.out.println("ConcreteStateA handles request");
    }
}

class ConcreteStateB implements State {
    @Override
    public void handleRequest() {
        System.out.println("ConcreteStateB handles request");
    }
}

// 上下文
class Context {
    private State state;

    public Context(State state) {
        this.state = state;
    }

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

    public void request() {
        state.handleRequest();
    }
}

// 使用
Context context = new Context(new ConcreteStateA());
context.request(); // ConcreteStateA handles request

context.setState(new ConcreteStateB());
context.request(); // ConcreteStateB handles request

21. 策略模式(Strategy)

比喻:就像外卖选择配送方式,雨天用电动车,晴天用自行车,晚高峰用摩托。

应用场景:定义一系列算法,把它们封装起来,并且使它们可以相互替换。

代码示例

java
// 策略接口
interface Strategy {
    void execute();
}

// 具体策略
class ConcreteStrategyA implements Strategy {
    @Override
    public void execute() {
        System.out.println("Executing strategy A");
    }
}

class ConcreteStrategyB implements Strategy {
    @Override
    public void execute() {
        System.out.println("Executing strategy B");
    }
}

// 上下文
class Context {
    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

    public void executeStrategy() {
        strategy.execute();
    }
}

// 使用
Context context = new Context(new ConcreteStrategyA());
context.executeStrategy(); // Executing strategy A

context.setStrategy(new ConcreteStrategyB());
context.executeStrategy(); // Executing strategy B

22. 模板方法模式(Template Method)

比喻:就像做咖啡的流程:烧水 → 加咖啡粉 → 冲泡 → 搅拌,子类只改"加奶还是糖"。

应用场景:定义一个算法的框架,允许子类在不改变结构的情况下重写步骤。

代码示例

java
// 抽象类
abstract class CaffeineBeverage {
    final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }

    abstract void brew();
    abstract void addCondiments();

    void boilWater() {
        System.out.println("Boiling water");
    }

    void pourInCup() {
        System.out.println("Pouring into cup");
    }
}

// 具体实现
class Tea extends CaffeineBeverage {
    @Override
    void brew() {
        System.out.println("Steeping the tea");
    }

    @Override
    void addCondiments() {
        System.out.println("Adding lemon");
    }
}

class Coffee extends CaffeineBeverage {
    @Override
    void brew() {
        System.out.println("Dripping coffee through filter");
    }

    @Override
    void addCondiments() {
        System.out.println("Adding sugar and milk");
    }
}

// 使用
CaffeineBeverage tea = new Tea();
tea.prepareRecipe();
// 输出:
// Boiling water
// Steeping the tea
// Pouring into cup
// Adding lemon

CaffeineBeverage coffee = new Coffee();
coffee.prepareRecipe();
// 输出:
// Boiling water
// Dripping coffee through filter
// Pouring into cup
// Adding sugar and milk

23. 访问者模式(Visitor)

比喻:就像医院体检,一队医生(访问者)轮流检查你身体每个器官。

应用场景:对一个对象结构中的元素进行操作,不改变元素的类。

代码示例

java
// 访问者接口
interface Visitor {
    void visit(Animal animal);
    void visit(Plant plant);
}

// 具体访问者
class ZooKeeper implements Visitor {
    @Override
    public void visit(Animal animal) {
        System.out.println("ZooKeeper feeding " + animal.getName());
    }

    @Override
    public void visit(Plant plant) {
        System.out.println("ZooKeeper watering " + plant.getName());
    }
}

// 元素接口
interface Element {
    void accept(Visitor visitor);
}

// 具体元素
class Animal implements Element {
    private String name;

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

    public String getName() {
        return name;
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

class Plant implements Element {
    private String name;

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

    public String getName() {
        return name;
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

// 使用
Element animal = new Animal("Lion");
Element plant = new Plant("Tree");

Visitor zooKeeper = new ZooKeeper();
animal.accept(zooKeeper); // ZooKeeper feeding Lion
plant.accept(zooKeeper); // ZooKeeper watering Tree

💡 为什么学习设计模式?

设计模式不是"必须用"的魔法,而是"知道时能用"的工具。就像你不会每顿饭都用刀叉,但知道怎么用才能吃得更好。

"设计模式不是目的,而是手段;不是为了用而用,而是为了更好地解决问题。"

上次更新于: