前言

现在正在出一个规划形式专题系列教程, 篇幅会较多, 喜欢的话,给个重视❤️ ~

本节给我们讲一下规划形式中的备忘录形式,并结合实际业务场景给我们讲解怎么运用~

本专题的一切案例代码主要以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⭐️)

  • java-design-mode-all: https://github.com/qiuChengleiy/java-design-mode-all

Kafka 专题学习

  • 一起来学kafka之Kafka集群建立
  • 一起来学kafka之整合SpringBoot根本运用
  • 一起来学kafka之整合SpringBoot深化运用(一)
  • 一起来学kafka之整合SpringBoot深化运用(二)
  • 一起来学kafka之整合SpringBoot深化运用(三)

项目源码(源码已更新 欢迎star⭐️)

  • springboot-kafka-all: https://github.com/qiuChengleiy/springboot-kafka-all

ElasticSearch 专题学习

  • 运用docker建立es集群

  • 一起来学ElasticSearch(一)

  • 一起来学ElasticSearch(二)

  • 一起来学ElasticSearch(三)

  • 一起来学ElasticSearch(四)

  • 一起来学ElasticSearch(五)

  • 一起来学ElasticSearch(六)

  • 一起来学ElasticSearch(七)

  • 一起来学ElasticSearch(八)

  • 一起来学ElasticSearch(九)

  • 一起来学ElasticSearch(十)

  • 一起来学ElasticSearch之整合SpringBoot(一)

  • 一起来学ElasticSearch之整合SpringBoot(二)

  • 一起来学ElasticSearch之整合SpringBoot(三)

项目源码(源码已更新 欢迎star⭐️)

  • springboot-es-all: https://github.com/qiuChengleiy/springboot-es-all

往期并发编程内容引荐

  • 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并行流有了解过吗?说说看

引荐 SpringBoot & SpringCloud (源码已更新 欢迎star⭐️)

  • springboot-all

  • 地址: github.com/qiuChenglei…

  • SpringBoot系列教程合集

  • 一起来学SpringCloud合集

  • SpringCloud整合 Oauth2+Gateway+Jwt+Nacos 完成授权码形式的服务认证(一)

  • SpringCloud整合 Oauth2+Gateway+Jwt+Nacos 完成授权码形式的服务认证(二)

博客(阅读体会较佳)

  • 我的博客(阅读体会较佳)
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。