设计模式:备忘录模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

上一篇《中介者模式》                                                              下一篇《状态模式》

简介:

备忘录模式,它是一种软件设计模式,它允许在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

备忘录模式的使用场景:
1、需要保存和恢复对象的状态,但不希望通过暴露对象内部细节来实现。例如,在游戏存档、一些编辑工具中的“撤销”操作,或者浏览器中的后退功能中,用户希望保存和恢复对象的状态,但并不需要访问或修改对象的内部状态。
2、需要实现撤销操作。例如,在Word中编写文档,如果想要撤销之前的输入/删除操作,可以使用Ctrl+Z执行“撤销”操作。在这种情况下,备忘录模式可以保存文档的某个状态,以便用户在需要时恢复到该状态。
3、需要实现状态恢复。例如,在游戏中,玩家可能需要保存游戏的状态,以便在需要时恢复到之前的状态。备忘录模式可以保存游戏的状态,并在需要时恢复该状态。

总之,备忘录模式适用于需要保存和恢复对象状态的情况,包括但不限于以上场景。需要注意的是,使用备忘录模式需要消耗一定的内存资源,因此在使用时需要考虑内存消耗的问题。

备忘录模式的创建步骤:
1、创建发起人(Originator)类,该类中定义了创建备忘录(Memento)的接口,用于创建、使用和释放备忘录。
2、创建备忘录(Memento)类,该类中定义了需要保存的数据,并且这些数据必须是不可变的。
3、创建管理者(Caretaker)类,该类中保存备忘录(Memento),并且不应该对备忘录的内容进行操作或检查。
4、在发起人(Originator)类中定义一个恢复状态的方法,该方法用于从备忘录(Memento)中恢复对象的状态。
5、在发起人(Originator)类中定义一个创建备忘录(Memento)的方法,该方法用于创建一个新的备忘录(Memento),并将当前对象的状态保存到备忘录中。
6、在发起人(Originator)类中使用备忘录(Memento)的方法,该方法用于使用备忘录(Memento)来恢复对象的状态。
7、在发起人(Originator)类中定义一个释放备忘录(Memento)的方法,该方法用于释放备忘录(Memento),以便管理者(Caretaker)可以保存或使用它。
8、在管理者(Caretaker)类中定义一个保存备忘录(Memento)的方法,该方法用于保存发起人(Originator)创建的备忘录(Memento)。
9、在管理者(Caretaker)类中定义一个恢复备忘录(Memento)的方法,该方法用于恢复发起人(Originator)对象的状态。

以上是备忘录模式的基本创建步骤,在使用时可以根据需要进行适当的修改和扩展。

备忘录模式的优点,主要包括:
1、保存对象状态:备忘录模式可以保存对象的状态,以便在需要时恢复该状态。这对于需要撤销操作或者恢复历史状态的应用场景非常有用。
2、封装性:备忘录模式实现了内部状态的封装,只有创建备忘录的发起人才能访问备忘录中的状态信息,其他对象无法访问,增强了数据的安全性。
3、简化发起人:备忘录模式简化了发起人,发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则。

备忘录模式的缺点,主要包括:
1、资源消耗过大:如果需要保存的原发器类的成员变量太多,就不可避免需要占用大量的存储空间,每保存一次对象的状态都需要消耗一定的系统资源。
2、实现复杂度较高:备忘录模式需要实现发起人、备忘录、管理者等多个角色,并且需要维护备忘录的创建、存储、恢复等操作,因此实现起来相对比较复杂。
3、可能引入数据不一致的问题:由于备忘录模式需要保存和恢复对象的状态,如果在使用过程中出现异常或者并发操作,就可能导致数据不一致的问题。
4、可能引入性能问题:由于备忘录模式需要保存和恢复对象的状态,如果频繁地使用备忘录模式,可能会对系统的性能造成一定的影响。

因此,在使用备忘录模式时需要注意权衡利弊,根据实际需求和资源消耗来决定是否使用。同时,也需要在实现过程中注意保证数据的完整性和一致性,避免出现异常或并发操作对数据造成影响。


示例:

一、C#备忘录模式

以下是一个示例,展示了如何在C#中实现备忘录模式:

using System;  
  
// 发起人类  
public class Originator  
{  
    private string state;  
  
    public void SetState(string state)  
    {  
        this.state = state;  
    }  
  
    public Memento CreateMemento()  
    {  
        return new Memento(this.state);  
    }  
  
    public void RestoreFromMemento(Memento memento)  
    {  
        this.state = memento.State;  
    }  
}  
  
// 备忘录类  
public class Memento  
{  
    private string state;  
  
    public Memento(string state)  
    {  
        this.state = state;  
    }  
  
    public string State  
    {  
        get { return this.state; }  
    }  
}  
  
// 管理者类  
public class Caretaker  
{  
    private Memento memento;  
  
    public void SetMemento(Memento memento)  
    {  
        this.memento = memento;  
    }  
  
    public Memento GetMemento()  
    {  
        return this.memento;  
    }  
}  
  
// 客户端代码  
public class Client  
{  
    static void Main(string[] args)  
    {  
        Originator originator = new Originator();  
        originator.SetState("原始状态"); // 设置原始状态  
        Memento memento = originator.CreateMemento(); // 创建备忘录  
        originator.SetState("修改后的状态"); // 修改状态  
        Caretaker caretaker = new Caretaker(); // 创建管理者对象  
        caretaker.SetMemento(memento); // 将备忘录交给管理者保存  
        Console.WriteLine("当前状态:" + originator.State); // 输出当前状态(修改后的状态)  
        originator.RestoreFromMemento(caretaker.GetMemento()); // 从管理者中恢复到之前的状态(原始状态)  
        Console.WriteLine("恢复后的状态:" + originator.State); // 输出恢复后的状态(原始状态)  
    }  
}

二、java备忘录模式

备忘录模式通常通过以下方式实现:

import java.util.ArrayList;  
import java.util.List;  
  
// 发起人类  
public class Originator {  
    private List<String> states = new ArrayList<>();  
  
    public void setState(String state) {  
        states.add(state);  
    }  
  
    public Memento createMemento() {  
        return new Memento(states);  
    }  
  
    public void restoreFromMemento(Memento memento) {  
        states = memento.getStates();  
    }  
}  
  
// 备忘录类  
public class Memento {  
    private List<String> states;  
  
    public Memento(List<String> states) {  
        this.states = states;  
    }  
  
    public List<String> getStates() {  
        return states;  
    }  
}  
  
// 管理者类  
public class Caretaker {  
    private Memento memento;  
  
    public void setMemento(Memento memento) {  
        this.memento = memento;  
    }  
  
    public Memento getMemento() {  
        return memento;  
    }  
}  
  
// 客户端代码  
public class Client {  
    public static void main(String[] args) {  
        Originator originator = new Originator();  
        originator.setState("原始状态"); // 设置原始状态  
        Memento memento = originator.createMemento(); // 创建备忘录  
        originator.setState("修改后的状态"); // 修改状态  
        Caretaker caretaker = new Caretaker(); // 创建管理者对象  
        caretaker.setMemento(memento); // 将备忘录交给管理者保存  
        System.out.println("当前状态:" + originator.getState()); // 输出当前状态(修改后的状态)  
        originator.restoreFromMemento(caretaker.getMemento()); // 从管理者中恢复到之前的状态(原始状态)  
        System.out.println("恢复后的状态:" + originator.getState()); // 输出恢复后的状态(原始状态)  
    }  
}

三、javascript备忘录模式

在JavaScript中,备忘录实现方式如下:

// 发起人类  
class Originator {  
  constructor() {  
    this.states = [];  
  }  
  
  setState(state) {  
    this.states.push(state);  
  }  
  
  createMemento() {  
    return { states: this.states.slice() };  
  }  
  
  restoreFromMemento(memento) {  
    this.states = memento.states;  
  }  
}  
  
// 备忘录类  
class Memento {  
  constructor(states) {  
    this.states = states;  
  }  
  
  getStates() {  
    return this.states;  
  }  
}  
  
// 管理者类  
class Caretaker {  
  constructor() {  
    this.memento = null;  
  }  
  
  setMemento(memento) {  
    this.memento = memento;  
  }  
  
  getMemento() {  
    return this.memento;  
  }  
}  
  
// 客户端代码  
const originator = new Originator();  
originator.setState('原始状态'); // 设置原始状态  
const memento = originator.createMemento(); // 创建备忘录  
originator.setState('修改后的状态'); // 修改状态  
const caretaker = new Caretaker(); // 创建管理者对象  
caretaker.setMemento(memento); // 将备忘录交给管理者保存  
console.log('当前状态:', originator.states); // 输出当前状态(修改后的状态)  
originator.restoreFromMemento(caretaker.getMemento()); // 从管理者中恢复到之前的状态(原始状态)  
console.log('恢复后的状态:', originator.states); // 输出恢复后的状态(原始状态)

四、C++备忘录模式

以下是在C++中实现备忘录模式:

#include <iostream>  
#include <string>  
#include <vector>  
  
// 发起人类  
class Originator {  
public:  
  std::vector<std::string> states;  
  
  void setState(const std::string& state) {  
    states.push_back(state);  
  }  
  
  Memento* createMemento() {  
    return new Memento(states);  
  }  
  
  void restoreFromMemento(Memento* memento) {  
    states = memento->states;  
  }  
};  
  
// 备忘录类  
class Memento {  
public:  
  std::vector<std::string> states;  
  
  Memento(const std::vector<std::string>& states) : states(states) {}  
};  
  
// 管理者类  
class Caretaker {  
public:  
  Memento* memento;  
  
  Caretaker() : memento(nullptr) {}  
  
  void setMemento(Memento* memento) {  
    this->memento = memento;  
  }  
  
  Memento* getMemento() {  
    return memento;  
  }  
};  
  
// 客户端代码  
int main() {  
  Originator originator;  
  originator.setState("原始状态"); // 设置原始状态  
  Memento* memento = originator.createMemento(); // 创建备忘录  
  originator.setState("修改后的状态"); // 修改状态  
  Caretaker caretaker; // 创建管理者对象  
  caretaker.setMemento(memento); // 将备忘录交给管理者保存  
  std::cout << "当前状态:" << originator.states.back() << std::endl; // 输出当前状态(修改后的状态)  
  originator.restoreFromMemento(caretaker.getMemento()); // 从管理者中恢复到之前的状态(原始状态)  
  std::cout << "恢复后的状态:" << originator.states.back() << std::endl; // 输出恢复后的状态(原始状态)  
  return 0;  
}

五、python备忘录模式

以下是在python中实现备忘录模式:

from abc import ABC, abstractmethod  
  
class Memento(ABC):  
    @abstractmethod  
    def get_states(self):  
        pass  
  
class Originator:  
    def __init__(self):  
        self.states = []  
      
    def set_state(self, state):  
        self.states.append(state)  
      
    def create_memento(self):  
        return Memento(self.states[:])  
      
    def restore_from_memento(self, memento):  
        self.states = memento.get_states()  
  
class Caretaker:  
    def __init__(self):  
        self.memento = None  
      
    def set_memento(self, memento):  
        self.memento = memento  
      
    def get_memento(self):  
        return self.memento  
  
# 客户端代码  
if __name__ == '__main__':  
    originator = Originator()  
    originator.set_state('原始状态')  # 设置原始状态  
    memento = originator.create_memento()  # 创建备忘录  
    originator.set_state('修改后的状态')  # 修改状态  
    caretaker = Caretaker()  # 创建管理者对象  
    caretaker.set_memento(memento)  # 将备忘录交给管理者保存  
    print('当前状态:', originator.states[-1])  # 输出当前状态(修改后的状态)  
    originator.restore_from_memento(caretaker.get_memento())  # 从管理者中恢复到之前的状态(原始状态)  
    print('恢复后的状态:', originator.states[-1])  # 输出恢复后的状态(原始状态)

六、go备忘录模式

以下是一个示例,展示了如何在go中实现备忘录模式:

package main  
  
import (  
 "fmt"  
)  
  
// Originator 定义了创建备忘录和恢复备忘录的接口  
type Originator struct {  
 text string  
}  
  
func (o *Originator) SetText(text string) {  
 o.text = text  
}  
  
func (o *Originator) CreateMemento() *Memento {  
 return &Memento{text: o.text}  
}  
  
func (o *Originator) RestoreFromMemento(m *Memento) {  
 o.text = m.GetText()  
}  
  
// Memento 用于保存 Originator 的状态  
type Memento struct {  
 text string  
}  
  
func (m *Memento) GetText() string {  
 return m.text  
}  
  
// Caretaker 用于保存和恢复备忘录  
type Caretaker struct {  
 memento *Memento  
}  
  
func (c *Caretaker) SetMemento(m *Memento) {  
 c.memento = m  
}  
  
func (c *Caretaker) GetMemento() *Memento {  
 return c.memento  
}  
  
func main() {  
 originator := &Originator{}  
 originator.SetText("原始状态")  
   
 memento := originator.CreateMemento()  
 originator.SetText("修改后的状态")  
   
 fmt.Println("当前状态:", originator.text) // 输出当前状态(修改后的状态)  
   
 originator.RestoreFromMemento(memento) // 从备忘录中恢复到之前的状态(原始状态)  
 fmt.Println("恢复后的状态:", originator.text) // 输出恢复后的状态(原始状态)  
}

七、PHP备忘录模式

以下是一个示例,展示了如何在PHP中实现备忘录模式:

<?php  
  
// Originator 类定义了创建备忘录和恢复备忘录的接口  
class Originator {  
    private $state;  
  
    public function setState($state) {  
        $this->state = $state;  
    }  
  
    public function createMemento() {  
        return new Memento($this->state);  
    }  
  
    public function restoreFromMemento(Memento $memento) {  
        $this->setState($memento->getState());  
    }  
}  
  
// Memento 类用于保存 Originator 的状态  
class Memento {  
    private $state;  
  
    public function __construct($state) {  
        $this->state = $state;  
    }  
  
    public function getState() {  
        return $this->state;  
    }  
}  
  
// Caretaker 类用于保存和恢复备忘录  
class Caretaker {  
    private $memento;  
  
    public function setMemento(Memento $memento) {  
        $this->memento = $memento;  
    }  
  
    public function getMemento() {  
        return $this->memento;  
    }  
}  
  
// 客户端代码  
$originator = new Originator();  
$originator->setState("原始状态"); // 设置原始状态  
  
$memento = $originator->createMemento(); // 创建备忘录  
$originator->setState("修改后的状态"); // 修改状态  
  
echo "当前状态:" . $originator->getState() . "\n"; // 输出当前状态(修改后的状态)  
  
$originator->restoreFromMemento($memento); // 从备忘录中恢复到之前的状态(原始状态)  
echo "恢复后的状态:" . $originator->getState() . "\n"; // 输出恢复后的状态(原始状态)

《完结》


上一篇《中介者模式》                                                               下一篇《状态模式》

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值