前言
目前正在出一个设计模式专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~
本节给大家讲一下设计模式中的备忘录模式,并结合实际业务场景给大家讲解如何使用~
本专题的所有案例代码主要以Java语言为主, 好了, 废话不多说直接开整吧~
备忘录模式
备忘录模式(Memento pattern)是一种行为设计模式,它允许在不破坏封装性的前提下捕获和恢复对象的内部状态。该模式为对象提供了一个能够保存状态的接口,从而可以在以后的时间点回复对象以前的状态。
在备忘录模式中,有三个角色:
Originator(发起人):负责创建一个备忘录 Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态。Originator 可以根据需要决定 Memento 存储自己的哪些内部状态。Memento(备忘录):存储 Originator 内部状态的对象。备忘录提供了两个接口:Caretaker只能看到备忘录的窄接口,它只能将备忘录传递给其他对象;Originator可以看到备忘录的宽接口,允许它访问返回到先前状态所需的所有数据。Caretaker(管理者):负责保存好备忘录。
public class Caretaker {
private List<Memento> mementoList = new ArrayList<>();
public void add(Memento state) {
mementoList.add(state);
}
public Memento get(int index) {
return mementoList.get(index);
}
}
public class Memento {
private final 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 saveStateToMemento() {
return new Memento(state);
}
public void getStateFromMemento(Memento memento) {
state = memento.getState();
}
}
public class MementoPatternDemo {
public static void main(String[] args) {
Originator originator = new Originator();
Caretaker caretaker = new Caretaker();
originator.setState("State #1");
originator.setState("State #2");
caretaker.add(originator.saveStateToMemento());
originator.setState("State #3");
caretaker.add(originator.saveStateToMemento());
originator.setState("State #4");
System.out.println("Current State: " + originator.getState());
originator.getStateFromMemento(caretaker.get(0));
System.out.println("First saved State: " + originator.getState());
originator.getStateFromMemento(caretaker.get(1));
System.out.println("Second saved State: " + originator.getState());
}
}
// Current State: State #4
// First saved State: State #2
// Second saved State: State #3
最佳实践
电商平台业务使用备忘录模式的场景可以是购物车功能。
在购物车功能中,用户可将需要购买的商品放入购物车中,并可以对购物车进行添加、删除、修改等操作。而当用户在进行操作时,需要保证购物车的状态能够被正确保存和还原,以免出现错误情况。这时候,备忘录模式便可以派上用场。
首先,需要定义备忘录类 CartMemento,用于保存购物车状态的类,其中包含购物车的商品列表。
public class CartMemento {
private List<CartItem> itemList;
public CartMemento(List<CartItem> itemList) {
this.itemList = itemList;
}
public List<CartItem> getItemList() {
return itemList;
}
}
接下来,定义购物车类 Cart,可以对购物车进行添加、删除、修改等操作。并定义了 CartMemento 的创建和还原方法。
public class Cart {
private List<CartItem> itemList;
public Cart() {
itemList = new ArrayList<>();
}
public void addItem(CartItem item) {
itemList.add(item);
}
public void removeItem(CartItem item) {
itemList.remove(item);
}
public void updateItem(CartItem item) {
for (CartItem cartItem : itemList) {
if(cartItem.getId() == item.getId()) {
cartItem.setCount(item.getCount());
break;
}
}
}
public CartMemento saveToMemento() {
return new CartMemento(new ArrayList<>(itemList));
}
public void restoreFromMemento(CartMemento memento) {
itemList = memento.getItemList();
}
}
最后,定义 Caretaker 类作为管理者,负责保存和还原购物车的状态。其中 saveStateToMemento() 方法用于保存购物车状态,而 getStateFromMemento() 方法用于还原购物车状态。
public class Caretaker {
private CartMemento cartMemento;
public void saveStateToMemento(Cart cart) {
cartMemento = cart.saveToMemento();
}
public void getStateFromMemento(Cart cart) {
cart.restoreFromMemento(cartMemento);
}
}
在购物车功能中,当用户进行操作时,可以通过 Cart 类的 saveToMemento() 方法保存购物车状态,Caretaker 类的 saveStateToMemento() 方法保存备忘录,而在需要恢复购物车状态时,可以通过 Cart 类的 restoreFromMemento() 方法将购物车状态还原为之前保存的状态,Caretaker 类的 getStateFromMemento() 方法获取备忘录并进行状态还原。
下面来测试一下:
public class MementoPatternDemo {
public static void main(String[] args) {
// 创建购物车和管理者
Cart cart = new Cart();
Caretaker caretaker = new Caretaker();
// 向购物车添加商品
cart.addItem(new CartItem(1, 10));
cart.addItem(new CartItem(2, 20));
System.out.println("添加商品到购物车: ");
cart.getItemList().forEach(item -> System.out.println(item.getId() + ": " + item.getCount()));
// 保存购物车状态
caretaker.saveStateToMemento(cart);
// 向购物车添加新的商品
cart.addItem(new CartItem(3, 30));
System.out.println("再次添加商品到购物车: ");
cart.getItemList().forEach(item -> System.out.println(item.getId() + ": " + item.getCount()));
// 恢复购物车之前的状态
caretaker.getStateFromMemento(cart);
System.out.println("恢复购物车状态: ");
cart.getItemList().forEach(item -> System.out.println(item.getId() + ": " + item.getCount()));
// 添加商品到购物车:
// 1: 10
// 2: 20
// 再次添加商品到购物车:
// 1: 10
// 2: 20
// 3: 30
// 恢复购物车状态:
// 1: 10
// 2: 20
}
}
结束语
设计模式其实并不难,大家在学习的时候一定要在理解的基础上去写代码,不要去背代码。下节给大家讲观察者模式~
本着把自己知道的都告诉大家,如果本文对您有所帮助,点赞+关注鼓励一下呗~
相关文章
- 一起来学设计模式之认识设计模式
- 一起来学设计模式之单例模式
- 一起来学设计模式之工厂模式
- 一起来学设计模式之建造者模式
- 一起来学设计模式之原型模式
- 一起来学设计模式之适配器模式
- 一起来学设计模式之桥接模式
- 一起来学设计模式之组合模式
- 一起来学设计模式之装饰器模式
- 一起来学设计模式之外观模式
- 一起来学设计模式之享元模式
- 一起来学设计模式之代理模式
- 一起来学设计模式之责任链模式
- 一起来学设计模式之命令模式
- 一起来学设计模式之解释器模式
- 一起来学设计模式之迭代器模式
- 一起来学设计模式之中介者模式
项目源码(源码已更新 欢迎star⭐️)
Kafka 专题学习
- 一起来学kafka之Kafka集群搭建
- 一起来学kafka之整合SpringBoot基本使用
- 一起来学kafka之整合SpringBoot深入使用(一)
- 一起来学kafka之整合SpringBoot深入使用(二)
- 一起来学kafka之整合SpringBoot深入使用(三)
项目源码(源码已更新 欢迎star⭐️)
ElasticSearch 专题学习
项目源码(源码已更新 欢迎star⭐️)
往期并发编程内容推荐
- Java多线程专题之线程与进程概述
- Java多线程专题之线程类和接口入门
- Java多线程专题之进阶学习Thread(含源码分析)
- Java多线程专题之Callable、Future与FutureTask(含源码分析)
- 面试官: 有了解过线程组和线程优先级吗
- 面试官: 说一下线程的生命周期过程
- 面试官: 说一下线程间的通信
- 面试官: 说一下Java的共享内存模型
- 面试官: 有了解过指令重排吗,什么是happens-before
- 面试官: 有了解过volatile关键字吗 说说看
- 面试官: 有了解过Synchronized吗 说说看
- Java多线程专题之Lock锁的使用
- 面试官: 有了解过ReentrantLock的底层实现吗?说说看
- 面试官: 有了解过CAS和原子操作吗?说说看
- Java多线程专题之线程池的基本使用
- 面试官: 有了解过线程池的工作原理吗?说说看
- 面试官: 线程池是如何做到线程复用的?有了解过吗,说说看
- 面试官: 阻塞队列有了解过吗?说说看
- 面试官: 阻塞队列的底层实现有了解过吗? 说说看
- 面试官: 同步容器和并发容器有用过吗? 说说看
- 面试官: CopyOnWrite容器有了解过吗? 说说看
- 面试官: Semaphore在项目中有使用过吗?说说看(源码剖析)
- 面试官: Exchanger在项目中有使用过吗?说说看(源码剖析)
- 面试官: CountDownLatch有了解过吗?说说看(源码剖析)
- 面试官: CyclicBarrier有了解过吗?说说看(源码剖析)
- 面试官: Phaser有了解过吗?说说看
- 面试官: Fork/Join 有了解过吗?说说看(含源码分析)
- 面试官: Stream并行流有了解过吗?说说看