设计模式 - 备忘录模式

备忘录模式:将对象的状态保存下来,以实现数据对象的还原和回滚操作。
核心:备份和恢复,回档机制
角色:

  • Originator发起人:被备份的对象(备份数据来源),由Originator决定备份范围,执行备份的创建和恢复
  • Memonte备份/存档
  • Caretaker管理类:管理所有的备份

白箱模式备忘录

白箱备忘录的设计下,客户端直接获取到Memonte对象,可以看见Memonte的功能列表,甚至通过反射修改Memonte中的数据(存在安全问题)

// Originator对象,作为被备份的对象,同时需要负责创建备份和从备份恢复
public class Originator {
    private String state;

    public Originator(String state){ this.state = state;}

    public String getState() { return state;}

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

    // 创建备份
    public Memonte createMonte(){
        return new Memonte(this.state);
    }

    // 从备份恢复
    public void restoreMemonte(Memonte memonte){
        this.state = memonte.getState();
    };

    public void show(){ System.out.println("State = " + this.state);}
}
// 备份,存储Originator中所需备份的状态
public class Memonte {
    private String state;

    public Memonte(String state){ this.state = state;}

    public String getState() { return this.state;}
}
// 备份管理器,存储所有的备份,可以有不同的数据结构实现。(栈式的后进先出,Map类型的备份点订点恢复,双指针数组实现固定大小备忘录)
public class Caretaker {
    public Memonte getMemonte() {
        return STACK.pop();
    }

    public void addMemonte(Memonte memonte) {
        STACK.push(memonte);
    }

    private final Stack<Memonte> STACK = new Stack<>();
}

黑箱模式备忘录

// Originator对象,作为被备份的对象,同时需要负责创建备份和从备份恢复,
// 黑箱模式:通过私有内部类,实现访问限制(只有Originator对象才可访问Memonte相关功能接口)
public class Originator {
    private String state;

    public Originator(String state){ this.state = state;}

    public String getState() { return state;}

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

    public IMemonte createMonte(){ return new Memonte(this.state);}

    public void restoreMemonte(IMemonte memonte){ this.state = ((Memonte)memonte).getState();};

    public void show(){ System.out.println("State = " + this.state);}

    // 黑箱备忘录,private权限的Memonte对象,相应的接口仅在Originator类内部可用
    private class Memonte implements IMemonte{
        private String state;

        private Memonte(String state){ this.state = state;}

        private String getState() { return this.state;}
    }
}
// 空白接口,作为对外开放的数据接口,客户端只能持有和传递该对象,而无法对该对象只需如何操作
public interface IMemonte {}
// 备份管理器,存储所有的备份,可以有不同的数据结构实现。(栈式的后进先出,Map类型的备份点订点恢复,双指针数组实现固定大小备忘录)
public class Caretaker {
    public IMemonte getMemonte() {
        return memonte;
    }

    public void setMemonte(IMemonte memonte) {
        this.memonte = memonte;
    }

    private IMemonte memonte;
}

Test

public class Test {
    public static void main(String[] args) {
        Caretaker caretaker = new Caretaker();
        Originator originator = new Originator("Stop");         // 1. Stop

        // 首次备份
        caretaker.addMemonte(originator.createMonte(););

        // 更改状态后再次备份
        originator.setState("Start");                           // 2. Start
        caretaker.addMemonte(originator.createMonte());

        originator.setState("Run");                             // 3. Run

        // 恢复备份
        originator.restoreMemonte(caretaker.getMemonte());      // 4. Start
        originator.restoreMemonte(caretaker.getMemonte());      // 5. Stop
    }
}

双接口设计

双接口设计 - 为一个类提供两个接口:

  • ①宽接口:具有所有的功能列表
  • ②窄接口:只有可对外可见的功能列表或者为空接口。
    双接口设计作用:宽接口对内提供所需的功能列表,窄接口对外使客户端对该对象的操作权限尽可能小
posted @ 2020-12-01 21:16  祁奇  阅读(99)  评论(0编辑  收藏  举报