简介:
备忘录模式,它是一种软件设计模式,它允许在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
备忘录模式的使用场景:
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"; // 输出恢复后的状态(原始状态)
《完结》