• 设计模式:备忘录模式(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#中实现备忘录模式:

    1. using System;  
    2.   
    3. // 发起人类  
    4. public class Originator  
    5. {  
    6.     private string state;  
    7.   
    8.     public void SetState(string state)  
    9.     {  
    10.         this.state = state;  
    11.     }  
    12.   
    13.     public Memento CreateMemento()  
    14.     {  
    15.         return new Memento(this.state);  
    16.     }  
    17.   
    18.     public void RestoreFromMemento(Memento memento)  
    19.     {  
    20.         this.state = memento.State;  
    21.     }  
    22. }  
    23.   
    24. // 备忘录类  
    25. public class Memento  
    26. {  
    27.     private string state;  
    28.   
    29.     public Memento(string state)  
    30.     {  
    31.         this.state = state;  
    32.     }  
    33.   
    34.     public string State  
    35.     {  
    36.         get { return this.state; }  
    37.     }  
    38. }  
    39.   
    40. // 管理者类  
    41. public class Caretaker  
    42. {  
    43.     private Memento memento;  
    44.   
    45.     public void SetMemento(Memento memento)  
    46.     {  
    47.         this.memento = memento;  
    48.     }  
    49.   
    50.     public Memento GetMemento()  
    51.     {  
    52.         return this.memento;  
    53.     }  
    54. }  
    55.   
    56. // 客户端代码  
    57. public class Client  
    58. {  
    59.     static void Main(string[] args)  
    60.     {  
    61.         Originator originator = new Originator();  
    62.         originator.SetState("原始状态"); // 设置原始状态  
    63.         Memento memento = originator.CreateMemento(); // 创建备忘录  
    64.         originator.SetState("修改后的状态"); // 修改状态  
    65.         Caretaker caretaker = new Caretaker(); // 创建管理者对象  
    66.         caretaker.SetMemento(memento); // 将备忘录交给管理者保存  
    67.         Console.WriteLine("当前状态:" + originator.State); // 输出当前状态(修改后的状态)  
    68.         originator.RestoreFromMemento(caretaker.GetMemento()); // 从管理者中恢复到之前的状态(原始状态)  
    69.         Console.WriteLine("恢复后的状态:" + originator.State); // 输出恢复后的状态(原始状态)  
    70.     }  
    71. }

    二、java备忘录模式

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

    1. import java.util.ArrayList;  
    2. import java.util.List;  
    3.   
    4. // 发起人类  
    5. public class Originator {  
    6.     private List states = new ArrayList<>();  
    7.   
    8.     public void setState(String state) {  
    9.         states.add(state);  
    10.     }  
    11.   
    12.     public Memento createMemento() {  
    13.         return new Memento(states);  
    14.     }  
    15.   
    16.     public void restoreFromMemento(Memento memento) {  
    17.         states = memento.getStates();  
    18.     }  
    19. }  
    20.   
    21. // 备忘录类  
    22. public class Memento {  
    23.     private List states;  
    24.   
    25.     public Memento(List states) {  
    26.         this.states = states;  
    27.     }  
    28.   
    29.     public List getStates() {  
    30.         return states;  
    31.     }  
    32. }  
    33.   
    34. // 管理者类  
    35. public class Caretaker {  
    36.     private Memento memento;  
    37.   
    38.     public void setMemento(Memento memento) {  
    39.         this.memento = memento;  
    40.     }  
    41.   
    42.     public Memento getMemento() {  
    43.         return memento;  
    44.     }  
    45. }  
    46.   
    47. // 客户端代码  
    48. public class Client {  
    49.     public static void main(String[] args) {  
    50.         Originator originator = new Originator();  
    51.         originator.setState("原始状态"); // 设置原始状态  
    52.         Memento memento = originator.createMemento(); // 创建备忘录  
    53.         originator.setState("修改后的状态"); // 修改状态  
    54.         Caretaker caretaker = new Caretaker(); // 创建管理者对象  
    55.         caretaker.setMemento(memento); // 将备忘录交给管理者保存  
    56.         System.out.println("当前状态:" + originator.getState()); // 输出当前状态(修改后的状态)  
    57.         originator.restoreFromMemento(caretaker.getMemento()); // 从管理者中恢复到之前的状态(原始状态)  
    58.         System.out.println("恢复后的状态:" + originator.getState()); // 输出恢复后的状态(原始状态)  
    59.     }  
    60. }

    三、javascript备忘录模式

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

    1. // 发起人类  
    2. class Originator {  
    3.   constructor() {  
    4.     this.states = [];  
    5.   }  
    6.   
    7.   setState(state) {  
    8.     this.states.push(state);  
    9.   }  
    10.   
    11.   createMemento() {  
    12.     return { states: this.states.slice() };  
    13.   }  
    14.   
    15.   restoreFromMemento(memento) {  
    16.     this.states = memento.states;  
    17.   }  
    18. }  
    19.   
    20. // 备忘录类  
    21. class Memento {  
    22.   constructor(states) {  
    23.     this.states = states;  
    24.   }  
    25.   
    26.   getStates() {  
    27.     return this.states;  
    28.   }  
    29. }  
    30.   
    31. // 管理者类  
    32. class Caretaker {  
    33.   constructor() {  
    34.     this.memento = null;  
    35.   }  
    36.   
    37.   setMemento(memento) {  
    38.     this.memento = memento;  
    39.   }  
    40.   
    41.   getMemento() {  
    42.     return this.memento;  
    43.   }  
    44. }  
    45.   
    46. // 客户端代码  
    47. const originator = new Originator();  
    48. originator.setState('原始状态'); // 设置原始状态  
    49. const memento = originator.createMemento(); // 创建备忘录  
    50. originator.setState('修改后的状态'); // 修改状态  
    51. const caretaker = new Caretaker(); // 创建管理者对象  
    52. caretaker.setMemento(memento); // 将备忘录交给管理者保存  
    53. console.log('当前状态:', originator.states); // 输出当前状态(修改后的状态)  
    54. originator.restoreFromMemento(caretaker.getMemento()); // 从管理者中恢复到之前的状态(原始状态)  
    55. console.log('恢复后的状态:', originator.states); // 输出恢复后的状态(原始状态)

    四、C++备忘录模式

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

    1. #include  
    2. #include  
    3. #include  
    4.   
    5. // 发起人类  
    6. class Originator {  
    7. public:  
    8.   std::vector states;  
    9.   
    10.   void setState(const std::string& state) {  
    11.     states.push_back(state);  
    12.   }  
    13.   
    14.   Memento* createMemento() {  
    15.     return new Memento(states);  
    16.   }  
    17.   
    18.   void restoreFromMemento(Memento* memento) {  
    19.     states = memento->states;  
    20.   }  
    21. };  
    22.   
    23. // 备忘录类  
    24. class Memento {  
    25. public:  
    26.   std::vector states;  
    27.   
    28.   Memento(const std::vector& states) : states(states) {}  
    29. };  
    30.   
    31. // 管理者类  
    32. class Caretaker {  
    33. public:  
    34.   Memento* memento;  
    35.   
    36.   Caretaker() : memento(nullptr) {}  
    37.   
    38.   void setMemento(Memento* memento) {  
    39.     this->memento = memento;  
    40.   }  
    41.   
    42.   Memento* getMemento() {  
    43.     return memento;  
    44.   }  
    45. };  
    46.   
    47. // 客户端代码  
    48. int main() {  
    49.   Originator originator;  
    50.   originator.setState("原始状态"); // 设置原始状态  
    51.   Memento* memento = originator.createMemento(); // 创建备忘录  
    52.   originator.setState("修改后的状态"); // 修改状态  
    53.   Caretaker caretaker; // 创建管理者对象  
    54.   caretaker.setMemento(memento); // 将备忘录交给管理者保存  
    55.   std::cout << "当前状态:" << originator.states.back() << std::endl; // 输出当前状态(修改后的状态)  
    56.   originator.restoreFromMemento(caretaker.getMemento()); // 从管理者中恢复到之前的状态(原始状态)  
    57.   std::cout << "恢复后的状态:" << originator.states.back() << std::endl; // 输出恢复后的状态(原始状态)  
    58.   return 0;  
    59. }

    五、python备忘录模式

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

    1. from abc import ABC, abstractmethod  
    2.   
    3. class Memento(ABC):  
    4.     @abstractmethod  
    5.     def get_states(self):  
    6.         pass  
    7.   
    8. class Originator:  
    9.     def __init__(self):  
    10.         self.states = []  
    11.       
    12.     def set_state(self, state):  
    13.         self.states.append(state)  
    14.       
    15.     def create_memento(self):  
    16.         return Memento(self.states[:])  
    17.       
    18.     def restore_from_memento(self, memento):  
    19.         self.states = memento.get_states()  
    20.   
    21. class Caretaker:  
    22.     def __init__(self):  
    23.         self.memento = None  
    24.       
    25.     def set_memento(self, memento):  
    26.         self.memento = memento  
    27.       
    28.     def get_memento(self):  
    29.         return self.memento  
    30.   
    31. # 客户端代码  
    32. if __name__ == '__main__':  
    33.     originator = Originator()  
    34.     originator.set_state('原始状态')  # 设置原始状态  
    35.     memento = originator.create_memento()  # 创建备忘录  
    36.     originator.set_state('修改后的状态')  # 修改状态  
    37.     caretaker = Caretaker()  # 创建管理者对象  
    38.     caretaker.set_memento(memento)  # 将备忘录交给管理者保存  
    39.     print('当前状态:', originator.states[-1])  # 输出当前状态(修改后的状态)  
    40.     originator.restore_from_memento(caretaker.get_memento())  # 从管理者中恢复到之前的状态(原始状态)  
    41.     print('恢复后的状态:', originator.states[-1])  # 输出恢复后的状态(原始状态)

    六、go备忘录模式

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

    1. package main  
    2.   
    3. import (  
    4.  "fmt"  
    5. )  
    6.   
    7. // Originator 定义了创建备忘录和恢复备忘录的接口  
    8. type Originator struct {  
    9.  text string  
    10. }  
    11.   
    12. func (o *Originator) SetText(text string) {  
    13.  o.text = text  
    14. }  
    15.   
    16. func (o *Originator) CreateMemento() *Memento {  
    17.  return &Memento{text: o.text}  
    18. }  
    19.   
    20. func (o *Originator) RestoreFromMemento(m *Memento) {  
    21.  o.text = m.GetText()  
    22. }  
    23.   
    24. // Memento 用于保存 Originator 的状态  
    25. type Memento struct {  
    26.  text string  
    27. }  
    28.   
    29. func (m *Memento) GetText() string {  
    30.  return m.text  
    31. }  
    32.   
    33. // Caretaker 用于保存和恢复备忘录  
    34. type Caretaker struct {  
    35.  memento *Memento  
    36. }  
    37.   
    38. func (c *Caretaker) SetMemento(m *Memento) {  
    39.  c.memento = m  
    40. }  
    41.   
    42. func (c *Caretaker) GetMemento() *Memento {  
    43.  return c.memento  
    44. }  
    45.   
    46. func main() {  
    47.  originator := &Originator{}  
    48.  originator.SetText("原始状态")  
    49.    
    50.  memento := originator.CreateMemento()  
    51.  originator.SetText("修改后的状态")  
    52.    
    53.  fmt.Println("当前状态:", originator.text) // 输出当前状态(修改后的状态)  
    54.    
    55.  originator.RestoreFromMemento(memento) // 从备忘录中恢复到之前的状态(原始状态)  
    56.  fmt.Println("恢复后的状态:", originator.text) // 输出恢复后的状态(原始状态)  
    57. }

    七、PHP备忘录模式

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

    1.  
    2.   
    3. // Originator 类定义了创建备忘录和恢复备忘录的接口  
    4. class Originator {  
    5.     private $state;  
    6.   
    7.     public function setState($state) {  
    8.         $this->state = $state;  
    9.     }  
    10.   
    11.     public function createMemento() {  
    12.         return new Memento($this->state);  
    13.     }  
    14.   
    15.     public function restoreFromMemento(Memento $memento) {  
    16.         $this->setState($memento->getState());  
    17.     }  
    18. }  
    19.   
    20. // Memento 类用于保存 Originator 的状态  
    21. class Memento {  
    22.     private $state;  
    23.   
    24.     public function __construct($state) {  
    25.         $this->state = $state;  
    26.     }  
    27.   
    28.     public function getState() {  
    29.         return $this->state;  
    30.     }  
    31. }  
    32.   
    33. // Caretaker 类用于保存和恢复备忘录  
    34. class Caretaker {  
    35.     private $memento;  
    36.   
    37.     public function setMemento(Memento $memento) {  
    38.         $this->memento = $memento;  
    39.     }  
    40.   
    41.     public function getMemento() {  
    42.         return $this->memento;  
    43.     }  
    44. }  
    45.   
    46. // 客户端代码  
    47. $originator = new Originator();  
    48. $originator->setState("原始状态"); // 设置原始状态  
    49.   
    50. $memento = $originator->createMemento(); // 创建备忘录  
    51. $originator->setState("修改后的状态"); // 修改状态  
    52.   
    53. echo "当前状态:" . $originator->getState() . "\n"; // 输出当前状态(修改后的状态)  
    54.   
    55. $originator->restoreFromMemento($memento); // 从备忘录中恢复到之前的状态(原始状态)  
    56. echo "恢复后的状态:" . $originator->getState() . "\n"; // 输出恢复后的状态(原始状态)

    《完结》


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

  • 相关阅读:
    Python实战项目:打乒乓(源码分享)(文章较短,直接上代码)
    【云原生 · Kubernetes】kubernetes v1.23.3 二进制部署(二)
    Window 安装多个版本的 java 并按需切换
    Zookeeper的数据模型和节点类型
    帷幄匠心面试题 一面
    哈希算法(一)Java实现常用的哈希算法
    面试算法39:直方图最大矩形面积
    2022起重机司机(限桥式起重机)题库及答案
    【前端工程化】webpack使用require.context批量导入模块
    使用mod_rewrite时常用的服务器变量: RewriteRule规则表达式的说明:
  • 原文地址:https://blog.csdn.net/yetyrain/article/details/134012985