行为型设计模式

January 16, 2025 作者: southern 分类: 浏览: 5 评论: 0

行为型设计模式主要关注对象之间的职责分配和通信方式,旨在使对象之间的交互更加灵活和可维护。这类模式通过定义对象之间的交互方式,帮助我们在系统中更好地分配职责,减少对象之间的耦合。行为型设计模式包括以下几种:

  1. 责任链模式(Chain of Responsibility Pattern)

  2. 命令模式(Command Pattern)

  3. 解释器模式(Interpreter Pattern)

  4. 迭代器模式(Iterator Pattern)

  5. 中介者模式(Mediator Pattern)

  6. 备忘录模式(Memento Pattern)

  7. 观察者模式(Observer Pattern)

  8. 状态模式(State Pattern)

  9. 策略模式(Strategy Pattern)

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

  11. 访问者模式(Visitor Pattern)


1. 责任链模式

责任链模式就像是一个公司中的审批流程。一个请求(如请假申请)会从基层员工开始,逐级向上传递,直到某个级别的管理者有权限处理该请求。

责任链模式将请求的发送者和接收者解耦,允许多个对象都有机会处理请求,从而避免请求的发送者与接收者之间的耦合。

// 处理者接口
interface Handler {
    void setNext(Handler handler);
    void handleRequest(String request);
}
​
// 具体处理者
class Manager implements Handler {
    private Handler next;
​
    @Override
    public void setNext(Handler handler) {
        this.next = handler;
    }
​
    @Override
    public void handleRequest(String request) {
        if (request.equals("Leave")) {
            System.out.println("Manager approves the leave request.");
        } else if (next != null) {
            next.handleRequest(request);
        }
    }
}
​
class Director implements Handler {
    private Handler next;
​
    @Override
    public void setNext(Handler handler) {
        this.next = handler;
    }
​
    @Override
    public void handleRequest(String request) {
        if (request.equals("Promotion")) {
            System.out.println("Director approves the promotion request.");
        } else if (next != null) {
            next.handleRequest(request);
        }
    }
}
​
// 使用责任链模式
public class Main {
    public static void main(String[] args) {
        Handler manager = new Manager();
        Handler director = new Director();
​
        manager.setNext(director);
​
        manager.handleRequest("Leave");      // 输出: Manager approves the leave request.
        manager.handleRequest("Promotion"); // 输出: Director approves the promotion request.
    }
}

2. 命令模式

命令模式就像是一个餐厅的点餐系统。顾客(客户端)将订单(命令)交给服务员(调用者),服务员再将订单传递给厨师(接收者)执行。

命令模式将请求封装为对象,从而使你可以用不同的请求对客户进行参数化,并支持请求的排队、记录日志以及撤销操作。

// 命令接口
interface Command {
    void execute();
}
​
// 具体命令
class OrderCommand implements Command {
    private Chef chef;
​
    public OrderCommand(Chef chef) {
        this.chef = chef;
    }
​
    @Override
    public void execute() {
        chef.cook();
    }
}
​
// 接收者
class Chef {
    public void cook() {
        System.out.println("Chef is cooking the order.");
    }
}
​
// 调用者
class Waiter {
    private Command command;
​
    public void setCommand(Command command) {
        this.command = command;
    }
​
    public void takeOrder() {
        command.execute();
    }
}
​
// 使用命令模式
public class Main {
    public static void main(String[] args) {
        Chef chef = new Chef();
        Command order = new OrderCommand(chef);
​
        Waiter waiter = new Waiter();
        waiter.setCommand(order);
        waiter.takeOrder();  // 输出: Chef is cooking the order.
    }
}

3. 观察者模式

观察者模式就像是一个新闻订阅系统。当新闻发布者发布新内容时,所有订阅者(观察者)都会自动收到通知。

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象发生变化时,所有观察者都会收到通知并更新。

import java.util.ArrayList;
import java.util.List;
​
// 主题接口
interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}
​
// 具体主题
class NewsPublisher implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String news;
​
    @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(news);
        }
    }
​
    public void setNews(String news) {
        this.news = news;
        notifyObservers();
    }
}
​
// 观察者接口
interface Observer {
    void update(String news);
}
​
// 具体观察者
class Subscriber implements Observer {
    private String name;
​
    public Subscriber(String name) {
        this.name = name;
    }
​
    @Override
    public void update(String news) {
        System.out.println(name + " received news: " + news);
    }
}
​
// 使用观察者模式
public class Main {
    public static void main(String[] args) {
        NewsPublisher publisher = new NewsPublisher();
​
        Observer subscriber1 = new Subscriber("Alice");
        Observer subscriber2 = new Subscriber("Bob");
​
        publisher.registerObserver(subscriber1);
        publisher.registerObserver(subscriber2);
​
        publisher.setNews("Breaking News: Java 17 Released!");
        // 输出:
        // Alice received news: Breaking News: Java 17 Released!
        // Bob received news: Breaking News: Java 17 Released!
    }
}

4. 策略模式

策略模式就像是一个导航系统。你可以选择不同的策略(如最短路径、最快路径、最少收费路径)来达到目的地,而不需要改变导航系统本身。

策略模式定义了一系列算法,并将每个算法封装起来,使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户端。

// 策略接口
interface RouteStrategy {
    void buildRoute(String from, String to);
}
​
// 具体策略
class ShortestRouteStrategy implements RouteStrategy {
    @Override
    public void buildRoute(String from, String to) {
        System.out.println("Building the shortest route from " + from + " to " + to);
    }
}
​
class FastestRouteStrategy implements RouteStrategy {
    @Override
    public void buildRoute(String from, String to) {
        System.out.println("Building the fastest route from " + from + " to " + to);
    }
}
​
// 上下文类
class Navigator {
    private RouteStrategy strategy;
​
    public void setStrategy(RouteStrategy strategy) {
        this.strategy = strategy;
    }
​
    public void buildRoute(String from, String to) {
        strategy.buildRoute(from, to);
    }
}
​
// 使用策略模式
public class Main {
    public static void main(String[] args) {
        Navigator navigator = new Navigator();
​
        navigator.setStrategy(new ShortestRouteStrategy());
        navigator.buildRoute("Home", "Office");  // 输出: Building the shortest route from Home to Office
​
        navigator.setStrategy(new FastestRouteStrategy());
        navigator.buildRoute("Home", "Airport"); // 输出: Building the fastest route from Home to Airport
    }
}

5. 模板方法模式

模板方法模式就像是一个烹饪食谱。食谱定义了烹饪的步骤(如准备食材、烹饪、装盘),但具体的实现细节(如食材种类、烹饪方式)可以由不同的厨师自行决定。

模板方法模式定义了一个算法的框架,并将一些步骤延迟到子类中实现。模板方法模式使得子类可以在不改变算法结构的情况下重新定义算法的某些步骤。

// 抽象类
abstract class Recipe {
    // 模板方法
    public final void cook() {
        prepareIngredients();
        cookDish();
        serve();
    }
​
    // 具体步骤
    protected abstract void prepareIngredients();
    protected abstract void cookDish();
​
    protected void serve() {
        System.out.println("Serving the dish.");
    }
}
​
// 具体实现
class PastaRecipe extends Recipe {
    @Override
    protected void prepareIngredients() {
        System.out.println("Preparing pasta, sauce, and cheese.");
    }
​
    @Override
    protected void cookDish() {
        System.out.println("Boiling pasta and mixing with sauce.");
    }
}
​
// 使用模板方法模式
public class Main {
    public static void main(String[] args) {
        Recipe recipe = new PastaRecipe();
        recipe.cook();
        // 输出:
        // Preparing pasta, sauce, and cheese.
        // Boiling pasta and mixing with sauce.
        // Serving the dish.
    }
}

6. 状态模式

状态模式就像是一个电灯的开关。电灯有不同的状态(开或关),当你按下开关时,电灯的行为会根据当前状态发生变化。

状态模式允许一个对象在其内部状态改变时改变它的行为,使得对象看起来像是修改了它的类。

// 状态接口
interface State {
    void handle();
}
​
// 具体状态
class OnState implements State {
    @Override
    public void handle() {
        System.out.println("The light is on.");
    }
}
​
class OffState implements State {
    @Override
    public void handle() {
        System.out.println("The light is off.");
    }
}
​
// 上下文类
class LightSwitch {
    private State state;
​
    public void setState(State state) {
        this.state = state;
    }
​
    public void press() {
        state.handle();
    }
}
​
// 使用状态模式
public class Main {
    public static void main(String[] args) {
        LightSwitch lightSwitch = new LightSwitch();
​
        lightSwitch.setState(new OffState());
        lightSwitch.press();  // 输出: The light is off.
​
        lightSwitch.setState(new OnState());
        lightSwitch.press();  // 输出: The light is on.
    }
}

7. 中介者模式

中介者模式就像是一个聊天室的服务器。多个用户(对象)通过服务器(中介者)进行通信,而不是直接相互联系。

中介者模式用一个中介对象来封装一系列对象之间的交互,从而降低对象之间的耦合度。

import java.util.ArrayList;
import java.util.List;
​
// 中介者接口
interface ChatMediator {
    void sendMessage(String message, User user);
    void addUser(User user);
}
​
// 具体中介者
class ChatRoom implements ChatMediator {
    private List<User> users = new ArrayList<>();
​
    @Override
    public void sendMessage(String message, User user) {
        for (User u : users) {
            if (u != user) {
                u.receive(message);
            }
        }
    }
​
    @Override
    public void addUser(User user) {
        users.add(user);
    }
}
​
// 用户类
class User {
    private String name;
    private ChatMediator mediator;
​
    public User(String name, ChatMediator mediator) {
        this.name = name;
        this.mediator = mediator;
    }
​
    public void send(String message) {
        System.out.println(name + " sends: " + message);
        mediator.sendMessage(message, this);
    }
​
    public void receive(String message) {
        System.out.println(name + " receives: " + message);
    }
}
​
// 使用中介者模式
public class Main {
    public static void main(String[] args) {
        ChatMediator chatRoom = new ChatRoom();
​
        User alice = new User("Alice", chatRoom);
        User bob = new User("Bob", chatRoom);
​
        chatRoom.addUser(alice);
        chatRoom.addUser(bob);
​
        alice.send("Hi Bob!");  // 输出: Alice sends: Hi Bob! \n Bob receives: Hi Bob!
        bob.send("Hello Alice!"); // 输出: Bob sends: Hello Alice! \n Alice receives: Hello Alice!
    }
}

8. 迭代器模式

迭代器模式就像是一个书架上的书籍目录。你可以通过目录逐页浏览书籍内容,而不需要知道书籍的具体存储方式。

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

import java.util.Iterator;
​
// 迭代器接口
interface BookIterator extends Iterator<String> {}
​
// 聚合接口
interface BookCollection {
    BookIterator createIterator();
}
​
// 具体聚合
class BookShelf implements BookCollection {
    private String[] books;
​
    public BookShelf(String[] books) {
        this.books = books;
    }
​
    @Override
    public BookIterator createIterator() {
        return new BookShelfIterator(books);
    }
}
​
// 具体迭代器
class BookShelfIterator implements BookIterator {
    private String[] books;
    private int position = 0;
​
    public BookShelfIterator(String[] books) {
        this.books = books;
    }
​
    @Override
    public boolean hasNext() {
        return position < books.length;
    }
​
    @Override
    public String next() {
        return books[position++];
    }
}
​
// 使用迭代器模式
public class Main {
    public static void main(String[] args) {
        String[] books = {"Book 1", "Book 2", "Book 3"};
        BookCollection bookShelf = new BookShelf(books);
        BookIterator iterator = bookShelf.createIterator();
​
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        // 输出:
        // Book 1
        // Book 2
        // Book 3
    }
}

9. 备忘录模式

备忘录模式就像是一个游戏存档系统。你可以在游戏的关键时刻保存进度,并在需要时恢复到之前的存档点。

备忘录模式在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后可以恢复到之前的状态。

// 备忘录类
class GameMemento {
    private String state;
​
    public GameMemento(String state) {
        this.state = state;
    }
​
    public String getState() {
        return state;
    }
}
​
// 原发器类
class Game {
    private String state;
​
    public void setState(String state) {
        this.state = state;
    }
​
    public GameMemento save() {
        return new GameMemento(state);
    }
​
    public void restore(GameMemento memento) {
        state = memento.getState();
    }
​
    public void printState() {
        System.out.println("Current State: " + state);
    }
}
​
// 管理者类
class Caretaker {
    private GameMemento memento;
​
    public void saveMemento(GameMemento memento) {
        this.memento = memento;
    }
​
    public GameMemento getMemento() {
        return memento;
    }
}
​
// 使用备忘录模式
public class Main {
    public static void main(String[] args) {
        Game game = new Game();
        Caretaker caretaker = new Caretaker();
​
        game.setState("Level 1");
        caretaker.saveMemento(game.save());  // 保存状态
        game.printState();  // 输出: Current State: Level 1
​
        game.setState("Level 2");
        game.printState();  // 输出: Current State: Level 2
​
        game.restore(caretaker.getMemento());  // 恢复状态
        game.printState();  // 输出: Current State: Level 1
    }
}

10. 解释器模式

解释器模式就像是一个翻译器。它可以将一种语言(如数学表达式)翻译成另一种形式(如计算结果)。

解释器模式定义了一个语言的文法,并用一个解释器来解释语言中的句子。

// 抽象表达式
interface Expression {
    int interpret();
}
​
// 终结符表达式
class Number implements Expression {
    private int value;
​
    public Number(int value) {
        this.value = value;
    }
​
    @Override
    public int interpret() {
        return value;
    }
}
​
// 非终结符表达式
class Add implements Expression {
    private Expression left;
    private Expression right;
​
    public Add(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }
​
    @Override
    public int interpret() {
        return left.interpret() + right.interpret();
    }
}
​
// 使用解释器模式
public class Main {
    public static void main(String[] args) {
        Expression expression = new Add(new Number(5), new Number(3));
        System.out.println("Result: " + expression.interpret());  // 输出: Result: 8
    }
}

11. 访问者模式

访问者模式就像是一个博物馆的导游。导游(访问者)可以带领游客参观不同的展品(元素),并根据展品的特点提供不同的讲解。

访问者模式将算法与对象结构分离,使得可以在不修改对象结构的情况下定义新的操作。

// 元素接口
interface Element {
    void accept(Visitor visitor);
}
​
// 具体元素
class Museum implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
​
    public String exhibit() {
        return "Ancient Artifacts";
    }
}
​
class Park implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
​
    public String scenery() {
        return "Beautiful Landscape";
    }
}
​
// 访问者接口
interface Visitor {
    void visit(Museum museum);
    void visit(Park park);
}
​
// 具体访问者
class Tourist implements Visitor {
    @Override
    public void visit(Museum museum) {
        System.out.println("Tourist visits museum and sees " + museum.exhibit());
    }
​
    @Override
    public void visit(Park park) {
        System.out.println("Tourist visits park and enjoys " + park.scenery());
    }
}
​
// 使用访问者模式
public class Main {
    public static void main(String[] args) {
        Element museum = new Museum();
        Element park = new Park();
​
        Visitor tourist = new Tourist();
​
        museum.accept(tourist);  // 输出: Tourist visits museum and sees Ancient Artifacts
        park.accept(tourist);    // 输出: Tourist visits park and enjoys Beautiful Landscape
    }
}


#2025(4)

评论