木灵鱼儿

木灵鱼儿

阅读:1116

最后更新:2022/07/01/ 1:36:10

行为模式:备忘录模式

简介

备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。该模式又叫快照模式。

其实就是一种设计历史记录的方式,在ps中,每次操作的记录都会进行一次记录,用户可以自己选择需要回退到哪条记录,而备忘录模式,是一种能记录一个对象的内部状态,可以通过方法获取到之前保存的内部状态数据,从而进行恢复。

这里面最复杂的就是需要设计好需要记录的状态数据,然后通过谁去保存,谁去控制保存的数据,谁去主动进行创建备忘录数据和读取备忘录数据。

所以他会有三个角色:

  1. 备忘录角色:专门存储内部状态数据的类,这个类的实例被管理者管理,被发起者创建和读取
  2. 管理者角色:负责专门管理备忘录实例的,提供保存和获取的功能,但是不能对备忘录实例的数据进行操作,需要保证数据的正确性
  3. 发起者角色:指的是需要保存历史数据的对象,它会创建备忘录实例,也会通过管理者读取之前的数据,以及其他业务实现。

备忘录模式的核心是设计备忘录类以及用于管理备忘录的管理者类。

代码实现

interface MemoState {
  name: string;
  status: number;
}

//备忘录类
class Memo {
  private state: MemoState;

  constructor(state: MemoState) {
    this.state = state;
  }

  public getState(): MemoState {
    return this.state;
  }

  public setState(state: MemoState): void {
    this.state = state;
  }
}

//备忘录管理类
class MemoManager {
  private list: Array<Memo> = [];

  //添加备忘录
  public add(memo: Memo): void {
    this.list.push(memo);
  }

  //获取备忘录
  public getState(index: number): Memo {
    return this.list[index];
  }

  //获取备忘录数量
  public getLength(): number {
    return this.list.length;
  }
}

//发起者
class Originator {
  private name: string = "发起者";
  private status: number = 0;

  //创建备忘录
  public createMomo(): Memo {
    return new Memo({
      name: this.name,
      status: this.status,
    });
  }

  //读取备忘录进行还原
  public restore(memo: Memo): void {
    const state = memo.getState();
    this.name = state.name;
    this.status = state.status;
  }

  //更改name
  public setName(name: string): void {
    this.name = name;
  }

  //更改status
  public setStatus(status: number): void {
    this.status = status;
  }

  //打印输出
  public print(): void {
    console.log(`${this.name}的状态是${this.status}`);
  }
}

//客户调用
class Client {
  constructor() {
    const originator = new Originator();
    const manager = new MemoManager();

    //创建第一次备份数据并保存
    manager.add(originator.createMomo());

    //更改name
    originator.setName("更改了名字");
    //更改status
    originator.setStatus(1);
    //打印输出
    originator.print();

    //创建第二次备份数据并保存
    manager.add(originator.createMomo());

    //更改name
    originator.setName("再次更改了名字");
    //更改status
    originator.setStatus(2);
    //打印输出
    originator.print();

    //恢复到首次备份数据
    originator.restore(manager.getState(0));
    //打印输出
    originator.print();

    //恢复到第二次备份数据
    originator.restore(manager.getState(1));
    //打印输出
    originator.print();
  }
}

new Client();

三个角色之间的其实也可以依赖于抽象,这个自己设计下就行了,还是要根据具体业务来做会更明白一些。

我们可以看到打印输出的时候,可以看到恢复到了指定的备份状态,事实上,如果我们是针对一个数据对象的备份,其实可以不写一个备忘录的类,而是通过深度克隆的方式进行备份,这样的话第一更加省事,不用封装备忘录类,第二是数据还原更加方便,克隆也就是之前的原型模式,他们可以组合使用。

应用场景

  1. 需要保存与恢复数据的场景,如玩游戏时的中间结果的存档功能。
  2. 需要提供一个可回滚操作的场景,如 Word、记事本、Photoshop,Eclipse 等软件在编辑时按 Ctrl+Z 组合键,还有数据库中事务操作。

版权申明

本文系作者 @木灵鱼儿 原创发布在木灵鱼儿 - 有梦就能远航站点。未经许可,禁止转载。

关于作者

站点职位 博主
获得点赞 1
文章被阅读 1116

相关文章