行为型设计模式(三)状态模式 & 备忘录模式

行为型设计模式(三)状态模式 & 备忘录模式_第1张图片

状态模式 State

1、什么是状态模式

状态模式允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类,将对象的行为包装在不同的状态类中,对象在运行时根据内部状态的改变而改变它的行为。

2、为什么使用状态模式

  1. 封装了转换规则:状态模式将每个状态的行为封装在一个类中,使得转换规则更加清晰,易于理解和维护。
  2. 减少条件语句:状态模式减少了对象中大量的条件语句,提高了代码的可读性和可维护性。
  3. 状态切换更加灵活:状态模式使得状态切换变得更加灵活,可以在运行时动态地改变对象的状态。

3、如何使用状态模式

设计实现一个电梯状态:开门、关门、上升、下降等

// 状态接口
interface ElevatorState {
    void open();
    void close();
    void up();
    void down();
}

// 具体状态1:开门
class OpenState implements ElevatorState {
    @Override
    public void open() {
        System.out.println("The door is already open.");
    }

    @Override
    public void close() {
        System.out.println("Closing the door.");
    }

    @Override
    public void up() {
        System.out.println("Cannot go up while the door is open.");
    }

    @Override
    public void down() {
        System.out.println("Cannot go down while the door is open.");
    }
}

// 具体状态2:关门
class CloseState implements ElevatorState {
    @Override
    public void open() {
        System.out.println("Opening the door.");
    }

    @Override
    public void close() {
        System.out.println("The door is already closed.");
    }

    @Override
    public void up() {
        System.out.println("Going up.");
    }

    @Override
    public void down() {
        System.out.println("Going down.");
    }
}

// 上下文类,维护当前状态
class ElevatorContext {
    private ElevatorState currentState;

    // 设置当前状态
    void setCurrentState(ElevatorState currentState) {
        this.currentState = currentState;
    }

    // 调用状态的方法
    void open() {
        currentState.open();
    }

    void close() {
        currentState.close();
    }

    void up() {
        currentState.up();
    }

    void down() {
        currentState.down();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        ElevatorContext elevator = new ElevatorContext();

        // 初始状态为关门
        elevator.setCurrentState(new CloseState());

        // 执行操作
        elevator.open();
        elevator.up();
        elevator.close();
        elevator.down();
    }
}

4、是否存在缺陷和不足

  1. 状态模式引入了多个状态类,有可能增加系统中类的数量。
  2. 如果状态切换的逻辑比较复杂,会增加状态模式的复杂度。

5、如何缓解缺陷和不足

  1. 如果实际业务场景中,存在相似的状态行为,建议考虑合并相似行为的状态,减少状态类的数量。
  2. 尽量简化状态切换的逻辑,保持状态模式的清晰性。

备忘录模式 Memento

1、什么是备忘录模式

备忘录模式允许对象在不暴露内部状态的情况下保存和恢复状态,通过将对象的状态保存到备忘录对象中,以便后续需要时恢复到该状态。

2、为什么使用备忘录模式

  1. 封装了对象状态:备忘录模式将对象的状态封装到备忘录中,使得对象的状态对外部是不可见的。
  2. 支持撤销和恢复:备忘录模式支持将对象恢复到之前的状态,从而实现撤销的功能。

3、如何使用备忘录模式

设计实现一个文本编辑器,用户可以输入文本并且可以随时保存编辑器的状态

// 备忘录类
class EditorMemento {
    private final String content;

    EditorMemento(String content) {
        this.content = content;
    }

    String getContent() {
        return content;
    }
}

// 原发器类
class TextEditor {
    private StringBuilder content = new StringBuilder();

    // 创建备忘录
    EditorMemento createMemento() {
        return new EditorMemento(content.toString());
    }

    // 恢复备忘录
    void restoreMemento(EditorMemento memento) {
        this.content = new StringBuilder(memento.getContent());
    }

    // 修改文本内容
    void addText(String text) {
        content.append(text);
    }

    // 获取当前文本内容
    String getContent() {
        return content.toString();
    }
}

// 负责人类
class EditorHistory {
    private Stack history = new Stack<>();

    // 将备忘录保存到历史记录中
    void save(EditorMemento memento) {
        history.push(memento);
    }

    // 从历史记录中获取最近的备忘录
    EditorMemento undo() {
        if (!history.isEmpty()) {
            return history.pop();
        }
        return null;
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        TextEditor editor = new TextEditor();
        EditorHistory history = new EditorHistory();

        // 输入文本
        editor.addText("Hello, ");
        System.out.println("Current Content: " + editor.getContent());

        // 保存备忘录
        history.save(editor.createMemento());

        // 输入更多文本
        editor.addText("World!");
        System.out.println("Current Content: " + editor.getContent());

        // 撤销操作,恢复到之前的状态
        editor.restoreMemento(history.undo());
        System.out.println("After Undo: " + editor.getContent());
    }
}

4、是否存在缺陷和不足

  1. 如果备忘录对象占用大量内存,可能会导致资源消耗较大。
  2. 如果原发器类的内部状态包含对其他对象的引用,备忘录模式无法完全保护这些对象的封装性。

5、如何缓解缺陷和不足

  1. 精简备忘录:如果备忘录对象占用大量内存,可以考虑设计更加精简的备忘录对象,只保存必要的状态。
  2. 深拷贝:如果原发器类的内部状态包含对其他对象的引用,可以使用深拷贝技术来复制这些对象,保护对象的封装性。

你可能感兴趣的:(技术专项能力,设计模式,状态模式,备忘录模式)