由于blog各种垃圾评论太多,而且本人审核评论周期较长,所以懒得管理评论了,就把评论功能关闭,有问题可以直接qq骚扰我

设计模式—备忘录模式

JAVA 西门飞冰 177℃
[隐藏]

1.定义

备忘录模式Memento是⼀种⾏为设计模式, 允许在不暴露对象实现细节 的情况下保存和恢复对象之前的状态。

很多时候我们总是需要记录⼀个对象的内部状态,这样做的⽬的就是为 了允许⽤户取消不确定或者错误的操作,能够恢复到他原先的状态,使 得他有”后悔药”可吃。

2.对象结构

image-20221002222931832

3.示例代码

需求:有一个电商的平台,商品前后的信息变化,需要给他记录下来,作为历史信息存档。

商品原始对象:标准java类

public class Goods{
    // 商品标题
    private String title;
    // 商品描述
    private String description;
    // 商品价格
    private float price;

    public Goods() {
    }

    public Goods(String title, String description, float price) {
        this.title = title;
        this.description = description;
        this.price = price;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Goods{" +
                "title='" + title + '\'' +
                ", description='" + description + '\'' +
                ", price=" + price +
                '}';
    }
}

备忘录接口:

public interface Memento<T> {
    public T getSnapshot();
}

备忘录实现类:构造⽅法内部实现对象的深度复制,即存储当时对象状态

导入依赖:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.3</version>
</dependency>

执行者:内部持有原始对象的应用,同时提供创建、还原备忘录的方法

public class Originator<T> {
    //内部持有类的引用
    private T object = null;    // 最原始的版本数据

    public Originator(T object){
        this.object = object;
    }

    // 创建镜像的过程
    public MementoImpl createMemento() {
        return new MementoImpl(object);
    }

    // 将发起人恢复到备忘录对象所记载的状态
    public T restoreMemmento(Memento memmento) {
        this.object = (T)memmento.getSnapshot();
        return object;
    }

    public T getObject() {
        return object;
    }
}

备忘录管理者:用于管理不断变化的对象状态

public class Caretaker {
    // 对象变化拥有多个不同的备忘录
    private List<Memento> memmentoList = new ArrayList<>();

    // 获取历史变化清单
    public List<Memento> getMementoList() {
        return this.memmentoList;
    }
    
     // 添加一个新的备忘录
    public void addMememtos(Memento memento) {
        this.memmentoList.add(memento);
    }
}

客户端:

public class Client {
    public static void main(String[] args) {
        //创建执行者,用于管理原始对象
        Originator<Goods> originator = new Originator(new Goods("小熊洗碗机", "...", 2389));
        //创建备忘录,留存最原始的记录
        Memento<Goods> memento = originator.createMemento();
        //创建管理者,用于管理备忘录的变化
        Caretaker caretaker = new Caretaker();
        //增加备忘录列表
        caretaker.addMememtos(memento);
        Goods goods = originator.getObject();
        goods.setPrice(2208);
        caretaker.addMememtos(originator.createMemento());
        goods.setPrice(1998);
        goods.setDescription("双十一大促,低价1998");
        caretaker.addMememtos(originator.createMemento());
        //查看数据历史变化
        int i = 0;
        for (Memento m : caretaker.getMementoList()) {
            System.out.println(i + ":" + m.getSnapshot());
            i++;
        }
        Memento<Goods> m = caretaker.getMementoList().get(0);
        Goods o = originator.restoreMemmento(m);
        System.out.println("数据已恢复至指定节点状态");
        System.out.println(originator.getObject());
    }
}

4.优点

1、给⽤户提供了⼀种可以恢复状态的机制,可以使⽤户能够⽐较⽅便地回到某个历史的状态。

2、实现了信息的封装,使得⽤户不需要关⼼状态的保存细节。

3、提供统⼀的历史回滚操作模式,不再⾯向⽬标对象操作

5.缺点

消耗资源。如果类的成员变量过多,势必会占⽤⽐较⼤的资源,⽽且每⼀次保存都会消耗⼀定的内存。

6.使用场景

需要保存/恢复数据的相关状态场景。

提供⼀个可回滚的操作。

为了节约内存,备忘录模式可以和原型模式配合使用

转载请注明:西门飞冰的博客 » 设计模式—备忘录模式

喜欢 (0)or分享 (0)