备忘录行为模式学习

81 阅读2分钟

###备忘录模式

最近在做需求,有很多tab点击,选中某几个tab,可以拉取符合条件的数据显示在table中,实现一个相当于分页的功能。

偶然看到一种备忘录设计模式,觉得可能适用在这。 下面介绍一下备忘录模式: 备忘录模式定义 备忘录模式属于一种行为设计模式,在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保护这个状态,这样以后就可以将该对象恢复到原先保存的状态。相当于ctrl+Z,后悔药。

备忘录模式角色划分 角色一:(Originator):负责创建一个备忘录,可以记录或者恢复内部状态 角色二:(Memento):备忘录角色,用于存储角色一的内部状态,在需要的时候提供这些内部状态给角色一。 角色三:(Caretaker):负责存储备忘录,但是不能访问和修改备忘录的内容

备忘录模式的结构图

备忘录模式的实现代码:

 //角色一,Originator
class Originator {
    constructor() {
        this.content = null;
    }
 
    setContent(content) {
        this.content = content;
    }
 
    getContent() {
        return this.content;
    }
 
    saveContentToMemento() {
        return new Memento(this.content);
    }
 
    getConentFromMemento(memento) {
        this.content = memento.getContent();
    }
} //角色二Memento
class Memento {
    constructor(content) {
        this.content = content;
    }
         setContent(content) {
        this.content = content;
    }
    getContent() {
        return this.content;
    }
}

//角色三 Caretaker
class Caretaker {
    constructor() {
        this.list = [];
    }
        
    add(memento) {
        this.list.push(memento);
    }
 
    get(index) {
        return this.list[index];
    }
 
    getList() {
        return this.list
    }
}



// 测试代码
let originator = new Originator()
let careTaker = new CarTaker()
 
originator.setContent('111')
originator.setContent('222')
 
careTaker.add(originator.saveContentToMemento())  // 将当前222内容备份
originator.setContent('333')
careTaker.add(originator.saveContentToMemento())  // 将当前333内容备份
originator.setContent('444')
 
console.log(originator.getContent()) //444
originator.getConentFromMemento(careTaker.get(1)) // ctrl+z 333
console.log(originator.getContent()) //333 
originator.getConentFromMemento(careTaker.get(0)) // 撤销 222
console.log(originator.getContent()) //222

应用场景:

1.分页时数据缓存,减少请求数据的时间和流量 2.内容懒加载时的缓存,例如图片懒加载,内容数据懒加载。 3.用户撤销,保存 4.浏览路由的缓存

前端实现: 综合上述应用场景,可以抽象出一个公共的方法实现数据缓存:

const dataCatch = (params, fn, cb)=> {
// 缓存对象
const map = {};
// 基础函数
return function(params, fn, cb) {
// 判断是否在缓存下
if(map[params]) {
// 从缓存中读取并传递给业务函数
fn(map[params])
}else {
// 没有缓存则将控制权转移给外部回调函数,并传递相应参数
cb && cb(params).then((res => {
map[params] = res.data;
})).catch(err => console.log(err))
}
}
}()

// 使用
dataCatch(params, showView, asyncFn)