Java 设计模式:行为型模式详解

Java 设计模式:行为型模式详解

行为型模式关注对象之间的交互和算法,它们可以提高代码的可扩展性、可复用性和可维护性。以下将详细讲解六种常见的行为型模式:责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式。

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

定义: 责任链模式将请求处理的对象连接成一条链,沿着链传递请求,直到某个对象处理它。

优势:

  • 减轻发送者和接收者的耦合: 发送者无需知道请求的具体处理者,只需发送请求,链上的对象会自动处理。
  • 灵活的请求处理: 可以动态添加或移除链上的对象,方便扩展。
  • 简化代码逻辑: 将请求处理逻辑分散到不同的对象中,提高代码可读性。

实例:

假设我们要处理员工的请假申请,需要审批流程,不同职位的人员有不同的审批权限:

// 审批者接口
interface Approver {
    void approve(LeaveRequest request);
    void setNextApprover(Approver approver);
}

// 具体审批者类
class Manager implements Approver {
    private Approver nextApprover;

    @Override
    public void approve(LeaveRequest request) {
        if (request.getDays() <= 3) {
            System.out.println("Manager approved the leave request.");
        } else {
            if (nextApprover != null) {
                nextApprover.approve(request);
            } else {
                System.out.println("Leave request rejected.");
            }
        }
    }

    @Override
    public void setNextApprover(Approver approver) {
        this.nextApprover = approver;
    }
}

class Director implements Approver {
    private Approver nextApprover;

    @Override
    public void approve(LeaveRequest request) {
        if (request.getDays() <= 7) {
            System.out.println("Director approved the leave request.");
        } else {
            if (nextApprover != null) {
                nextApprover.approve(request);
            } else {
                System.out.println("Leave request rejected.");
            }
        }
    }

    @Override
    public void setNextApprover(Approver approver) {
        this.nextApprover = approver;
    }
}

// 请假申请类
class LeaveRequest {
    private int days;

    public LeaveRequest(int days) {
        this.days = days;
    }

    public int getDays() {
        return days;
    }
}

public class ChainOfResponsibilityExample {
    public static void main(String[] args) {
        Manager manager = new Manager();
        Director director = new Director();
        manager.setNextApprover(director);

        LeaveRequest request1 = new LeaveRequest(2); // Manager审批
        LeaveRequest request2 = new LeaveRequest(5); // Director审批
        LeaveRequest request3 = new LeaveRequest(10); // Rejected

        manager.approve(request1);
        manager.approve(request2);
        manager.approve(request3);
    }
}

2. 命令模式(Command)

定义: 命令模式将请求封装为对象,从而使你能够参数化客户端,将请求排队或记录请求日志,并支持可撤销的操作。

优势:

  • 解耦调用者和接收者: 调用者无需了解具体操作的实现细节,只需执行命令对象。
  • 可扩展性强: 可以很容易地添加新的命令,无需修改调用者的代码。
  • 易于撤销操作: 命令对象可以保存操作的上下文,方便撤销。

实例:

假设我们要实现一个简单的文本编辑器,用户可以使用不同的命令来操作文本:

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

// 具体命令类
class InsertCommand implements Command {
    private String text;
    private Editor editor;

    public InsertCommand(String text, Editor editor) {
        this.text = text;
        this.editor = editor;
    }

    @Override
    public void execute() {
        editor.insertText(text);
    }

    @Override
    public void undo() {
        editor.deleteText(text);
    }
}

class DeleteCommand implements Command {
    private String text;
    private Editor editor;

    public DeleteCommand(String text, Editor editor) {
        this.text = text;
        this.editor = editor;
    }

    @Override
    public void execute() {
        editor.deleteText(text);
    }

    @Override
    public void undo() {
        editor.insertText(text);
    }
}

// 文本编辑器类
class Editor {
    private String text;

    public void insertText(String text) {
        this.text += text;
    }

    public void deleteText(String text) {
        this.text = this.text.replace(text, "");
    }

    public String getText() {
        return text;
    }
}

public class CommandExample {
    public static void main(String[] args) {
        Editor editor = new Editor();
        InsertCommand insertCommand = new InsertCommand("Hello, ", editor);
        DeleteCommand deleteCommand = new DeleteCommand("Hello, ", editor);

        insertCommand.execute(); // 插入文本
        System.out.println(editor.getText());

        deleteCommand.execute(); // 删除文本
        System.out.println(editor.getText());

        deleteCommand.undo(); // 撤销删除操作
        System.out.println(editor.getText());
    }
}

3. 解释器模式(Interpreter)

定义: 解释器模式提供了一种方式来定义语言的文法,并使用该文法来解析和执行语言中的句子。

优势:

  • 易于扩展: 可以方便地添加新的语法规则,而无需修改现有的解释器代码。
  • 代码可读性好: 使用解释器模式可以将复杂的解析逻辑分解成更小的、易于理解的组件。

实例:

假设我们要实现一个简单的表达式计算器,可以解析和计算加减乘除运算:

// 表达式接口
interface Expression {
    int interpret();
}

// 具体表达式类
class NumberExpression implements Expression {
    private int number;

    public NumberExpression(int number) {
        this.number = number;
    }

    @Override
    public int interpret() {
        return number;
    }
}

class AddExpression implements Expression {
    private Expression left;
    private Expression right;

    public AddExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret() {
        return left.interpret() + right.interpret();
    }
}

class SubtractExpression implements Expression {
    private Expression left;
    private Expression right;

    public SubtractExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret() {
        return left.interpret() - right.interpret();
    }
}

// 表达式解析器类
class ExpressionParser {
    public Expression parse(String expression) {
        String[] parts = expression.split(" ");
        Expression result = new NumberExpression(Integer.parseInt(parts[0]));

        for (int i = 1; i < parts.length; i += 2) {
            String operator = parts[i];
            int number = Integer.parseInt(parts[i + 1]);

            if (operator.equals("+")) {
                result = new AddExpression(result, new NumberExpression(number));
            } else if (operator.equals("-")) {
                result = new SubtractExpression(result, new NumberExpression(number));
            }
        }
        return result;
    }
}

public class InterpreterExample {
    public static void main(String[] args) {
        ExpressionParser parser = new ExpressionParser();
        Expression expression = parser.parse("1 + 2 - 3");
        int result = expression.interpret();
        System.out.println("Result: " + result); // Result: 0
    }
}

4. 迭代器模式(Iterator)

定义: 迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而无需暴露该对象的内部表示。

优势:

  • 访问聚合对象更方便: 迭代器提供统一的访问接口,简化了访问操作。
  • 易于扩展: 可以方便地添加新的迭代器,而无需修改聚合对象本身。
  • 提高代码可读性: 迭代器模式将遍历逻辑从聚合对象中分离出来,提高代码可读性。

实例:

假设我们要实现一个学生列表,可以遍历列表中的每个学生:

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

// 具体迭代器类
class StudentIterator implements Iterator {
    private Student[] students;
    private int index;

    public StudentIterator(Student[] students) {
        this.students = students;
    }

    @Override
    public boolean hasNext() {
        return index < students.length;
    }

    @Override
    public Student next() {
        return students[index++];
    }
}

// 学生类
class Student {
    private String name;

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

    public String getName() {
        return name;
    }
}

// 学生列表类
class StudentList {
    private Student[] students;

    public StudentList(Student[] students) {
        this.students = students;
    }

    public Iterator getIterator() {
        return new StudentIterator(students);
    }
}

public class IteratorExample {
    public static void main(String[] args) {
        Student[] students = {
                new Student("Alice"),
                new Student("Bob"),
                new Student("Charlie")
        };

        StudentList studentList = new StudentList(students);
        Iterator iterator = studentList.getIterator();

        while (iterator.hasNext()) {
            Student student = (Student) iterator.next();
            System.out.println(student.getName());
        }
    }
}

5. 中介者模式(Mediator)

定义: 中介者模式定义一个对象来封装一系列对象之间的交互。中介者使各对象不需要显式地相互引用,从而可以松散地耦合。

优势:

  • 降低耦合度: 对象之间无需直接通信,降低耦合度,提高代码可维护性。
  • 简化交互逻辑: 中介者可以集中处理对象之间的交互逻辑,简化代码逻辑。
  • 易于扩展: 可以方便地添加新的对象,而无需修改其他对象代码。

实例:

假设我们要实现一个聊天室,用户可以互相发送消息,但无需直接引用其他用户:

// 聊天室接口
interface ChatRoom {
    void sendMessage(String message, User sender);
}

// 具体聊天室类
class ConcreteChatRoom implements ChatRoom {
    @Override
    public void sendMessage(String message, User sender) {
        for (User user : User.getUsers()) {
            if (user != sender) {
                user.receiveMessage(sender, message);
            }
        }
    }
}

// 用户接口
interface User {
    void sendMessage(String message);
    void receiveMessage(User sender, String message);
}

// 具体用户类
class ConcreteUser implements User {
    private String name;
    private ChatRoom chatRoom;

    public ConcreteUser(String name, ChatRoom chatRoom) {
        this.name = name;
        this.chatRoom = chatRoom;
    }

    @Override
    public void sendMessage(String message) {
        chatRoom.sendMessage(message, this);
    }

    @Override
    public void receiveMessage(User sender, String message) {
        System.out.println(sender.getName() + "->" + name + ": " + message);
    }

    public String getName() {
        return name;
    }
}

public class MediatorExample {
    public static void main(String[] args) {
        ChatRoom chatRoom = new ConcreteChatRoom();
        User user1 = new ConcreteUser("Alice", chatRoom);
        User user2 = new ConcreteUser("Bob", chatRoom);

        user1.sendMessage("Hello, Bob!");
        user2.sendMessage("Hi, Alice!");
    }
}

6. 备忘录模式(Memento)

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

优势:

  • 可撤销操作: 可以方便地撤销对对象的修改,恢复到之前的状态。
  • 保护封装性: 备忘录模式不会暴露对象的内部状态,保持封装性。
  • 可扩展性强: 可以方便地添加新的状态保存功能,而无需修改原始对象。

实例:

假设我们要实现一个游戏存档功能,可以保存游戏中的玩家状态,以便以后恢复:

// 备忘录接口
interface Memento {
}

// 具体备忘录类
class PlayerMemento implements Memento {
    private int health;
    private int level;

    public PlayerMemento(int health, int level) {
        this.health = health;
        this.level = level;
    }

    public int getHealth() {
        return health;
    }

    public int getLevel() {
        return level;
    }
}

// 玩家接口
interface Player {
    Memento saveState();
    void restoreState(Memento memento);
}

// 具体玩家类
class ConcretePlayer implements Player {
    private int health;
    private int level;

    public ConcretePlayer(int health, int level) {
        this.health = health;
        this.level = level;
    }

    @Override
    public Memento saveState() {
        return new PlayerMemento(health, level);
    }

    @Override
    public void restoreState(Memento memento) {
        PlayerMemento savedState = (PlayerMemento) memento;
        this.health = savedState.getHealth();
        this.level = savedState.getLevel();
    }

    public int getHealth() {
        return health;
    }

    public int getLevel() {
        return level;
    }
}

public class MementoExample {
    public static void main(String[] args) {
        Player player = new ConcretePlayer(100, 1);
        Memento savedState = player.saveState(); // 保存游戏状态

        // 进行游戏操作,玩家状态发生改变
        player.health -= 20;
        player.level += 1;

        System.out.println("Current health: " + player.getHealth());
        System.out.println("Current level: " + player.getLevel());

        player.restoreState(savedState); // 恢复到之前的状态
        System.out.println("Restored health: " + player.getHealth());
        System.out.println("Restored level: " + player.getLevel());
    }
}

总结:

行为型模式可以有效地提高代码的可扩展性、可复用性和可维护性。选择合适的行为型模式,可以使你的代码更加清晰、灵活、易于维护。在实际开发中,需要根据具体的场景选择合适的模式。

  • 25
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

斯陀含

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值