设计模式系列:搞懂备忘录模式,提供后悔药

备忘录(Memento)模式的定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后在需要时能将该对象恢复到原先保存的状态。属于行为型模式。

备忘录模式的结构:备忘录模式主要包括以下3个角色。

  1. 发起人(Originator):记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能。
  2. 备忘录(Memento):负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。
  3. 管理者(Caretaker):对备忘录进行管理,提供保存和获取备忘录的功能,但无法访问与修改备忘录的内容。

备忘录模式的通用实现:

//备忘录
public class Memento {
    private String state;

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

    public String getState() {
        return state;
    }
}

//发起人
public class Originator {
    private String state;

    public void setState(String state) {
        this.state = state;
    }
    public String getState() {
        return state;
    }
    public Memento createMemento() {
        return new Memento(state);
    }
    public void restoreMemento(Memento memento) {
        this.setState(memento.getState());
    }
}

//管理者
public class Caretaker {
    private Memento memento;

    public void setMemento(Memento memento) {
        this.memento = memento;
    }

    public Memento getMemento() {
        return memento;
    }
}

//测试类
public class MementoTest {
    public static void main(String[] args) {
        Originator originator = new Originator();
        Caretaker caretaker = new Caretaker();
        originator.setState("S0");
        System.out.println("初始状态:" + originator.getState());
        //备份状态
        Memento memento = originator.createMemento();
        caretaker.setMemento(memento);
        originator.setState("S1");
        System.out.println("新的状态:" + originator.getState());
        //恢复状态
        originator.restoreMemento(caretaker.getMemento());
        System.out.println("恢复状态:" + originator.getState());
    }
}

备忘录模式的结构图:

备忘录模式的应用实例:公司发布招聘需求后会面试多个候选人,从中挑选最合适的人员录用,我们可以利使用备忘录模式来模拟这一场景。候选人是备忘录,公司是发起人,人才库是管理者。

//候选人(备忘录)
public class Candidate {
    private String name;

    private Double salary;

    public Candidate(String name,Double salary){
        this.name = name;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

    public Double getSalary() {
        return salary;
    }
}

//发起人
public class Company {
    private String employeeName;

    private Double salary;

    public String getEmployeeName() {
        return employeeName;
    }

    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }

    public Double getSalary() {
        return salary;
    }

    public void setSalary(Double salary) {
        this.salary = salary;
    }

    public Candidate createMemento() {
        System.out.println("候选人"+employeeName+"进入人才库!");
        return new Candidate(employeeName,salary);
    }

    public void restoreMemento(Candidate candidate) {
        this.setEmployeeName(candidate.getName());
        this.setSalary(candidate.getSalary());
    }
}

//管理者
public class TalentPool {
    private Map<String,Candidate> candidateMap = new HashMap<>();

    public void addCandidate(Candidate candidate) {
        candidateMap.put(candidate.getName(),candidate);
    }

    public Candidate getCandidate(String name) {
        return candidateMap.get(name);
    }
}

//测试类
public class Test {
    public static void main(String[] args) {
        Company company = new Company();
        TalentPool talentPool = new TalentPool();
        //候选人1
        company.setEmployeeName("张三");
        company.setSalary(15000.00);
        Candidate candidate1 = company.createMemento();
        talentPool.addCandidate(candidate1);
        //候选人2
        company.setEmployeeName("李四");
        company.setSalary(18000.00);
        Candidate candidate2 = company.createMemento();
        talentPool.addCandidate(candidate2);
        //候选人3
        company.setEmployeeName("王五");
        company.setSalary(20000.00);
        Candidate candidate3 = company.createMemento();
        talentPool.addCandidate(candidate3);
        //恢复候选人2
        company.restoreMemento(talentPool.getCandidate("李四"));
        System.out.println("确定录用候选人:"+company.getEmployeeName()+",薪水:"+company.getSalary());
    }
}

备忘录模式的优点:

  • 提供了状态回滚的机制。当用户需要时能够比较方便地将数据恢复到某个历史的状态。
  • 实现了内部状态的封装。除了创建它的发起人之外,其他对象都不能够访问这些状态信息。
  • 简化了发起人的职责。发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则。

备忘录模式的缺点是:资源消耗大。如果要保存的内部状态信息过多或者特别频繁,将会占用比较大的内存资源。

备忘录模式的应用场景:

  1. 需要保存与恢复数据的场景。
  2. 希望在对象外保存状态,且除了自己其他类无法访问状态保存的具体内容。
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

风雨编码路

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

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

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

打赏作者

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

抵扣说明:

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

余额充值