memento模式

场景

(1)类,计算出来一份中间数据 (2)这个类,之后需要基于这份中间数据再执行另外两次操作,每次操作都要基于这份中间数据去执行 (3)第一次基于中间数据操作过后,会对中间数据做出修改 (4)要求是第二次再执行操作的时候,需要基于未修改之前的中间数据来执行

1.备忘录模式

  1. package com.example.demo.pattern.memento;
  2. /**
  3. * @author chenchao
  4. * @date 2021/11/9
  5. */
  6. public class MementoPatternDemo {
  7. public static void main(String[] args) {
  8. Originator originator = new Originator();
  9. // 准备好了中间数据
  10. originator.prepare();
  11. // 将中间数据保存到备忘录中去
  12. Memento memento = originator.createMemento();
  13. // 将备忘录保存到备忘录管理器中去
  14. Caretaker caretaker = new Caretaker();
  15. caretaker.saveMemento(memento);
  16. // 基于中间数据执行了A方法,但是此时中间数据已经改变了
  17. originator.executeA();
  18. // 从备忘录管理器中获取备忘录
  19. memento = caretaker.retrieveMemento();
  20. // 将备忘录中保存好的中间数据重新设置到原发器中去,就将中间数据恢复成了之前备忘的状态
  21. originator.setMemento(memento);
  22. // 接着再次执行方法B
  23. originator.executeB();
  24. // 面临的场景
  25. // 你的系统会生产出来一份中间数据,这份中间数据要么是没法一直在内存里保留,要么是可能会被修改
  26. // 所以逼得你迫不得已,必须得通过备忘录的方式,将中间数据暂存一份儿
  27. // 在一堆操作过后,可能之前内存中的中间数据都弄丢了,也可能中间数据被人篡改了
  28. // 接下来,你需要从备忘录中恢复我们的中间数据
  29. // 基于恢复后的中间数据,再次执行后面的操作
  30. }
  31. public interface Memento {
  32. }
  33. public static class Originator {
  34. private String state;
  35. public void prepare() {
  36. this.state = "中间数据";
  37. }
  38. public void executeA() {
  39. System.out.println("基于中间数据【" + state +"】执行了A方法的逻辑");
  40. // 将state所代表的中间数据做出了修改
  41. state += ",A方法的结果数据";
  42. }
  43. public void executeB() {
  44. System.out.println("基于中间数据【" + state +"】执行了B方法的逻辑");
  45. state += ",B方法的结果数据";
  46. }
  47. public Memento createMemento() {
  48. return new MementoImpl(state);
  49. }
  50. public void setMemento(Memento memento) {
  51. MementoImpl mementoImpl = (MementoImpl)memento;
  52. this.state = mementoImpl.getState();
  53. }
  54. private static class MementoImpl implements Memento {
  55. private String state;
  56. public MementoImpl(String state) {
  57. this.state = state;
  58. }
  59. public String getState() {
  60. return state;
  61. }
  62. }
  63. }
  64. public static class Caretaker {
  65. private Memento memento;
  66. public void saveMemento(Memento memento) {
  67. this.memento = memento;
  68. }
  69. public Memento retrieveMemento() {
  70. return this.memento;
  71. }
  72. }
  73. }

2.说明

备忘录模式看起来有点复杂,其实不复杂,说白了,就是一个类一开始生产了一些数据,这些数据可能会被改变,但是需要将这些中间数据保存起来,给后面不同的操作使用这些中间数据

所以备忘录,顾名思义,就是用备忘录来保存中间数据,后面随时可以获取备忘录里的数据并且恢复这些数据

复杂业务场景,和真实项目的好处,业务足够复杂,才能支撑我们将各种各样的技术运用到项目实践中,纯真实复杂业务项目的驱动,大量的技术,还是理论,demo练习,学完,达不到架构师的水平,demo

广告系统,N个子系统,某一个子系统跟下游的子系统之间是基于MQ去通信的。但是此时要考虑说MQ如果挂了怎么办,写消息到MQ的子系统,一旦发现MQ挂了,将数据写入磁盘,暂存。后面MQ恢复了,再从磁盘里恢复这个数据。

这个模式其实使用场景很少见,属于冷门模式