本文共 6620 字,大约阅读时间需要 22 分钟。
备忘录模式能记录一个对象的内部状态,当用户后悔时能撤销当前操作,使数据恢复到它原先的状态。
备忘录(Memento)模式的定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。该模式又叫快照模式。备忘录模式是一种对象行为型模式,其主要优点如下。
提供了一种可以恢复状态的机制。当用户需要时能够比较方便地将数据恢复到某个历史的状态。 实现了内部状态的封装。除了创建它的发起人之外,其他对象都不能够访问这些状态信息。 简化了发起人类。发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则。其主要缺点是:资源消耗大。如果要保存的内部状态信息过多或者特别频繁,将会占用比较大的内存资源。
备忘录模式参与者:
◊ Memento
° 为创建对象的各个部件指定抽象接口
° 防止Originator意外的其他对象访问备忘录。备忘录实际上有两个接口,Caretaker只能看到备忘录的窄接口,它只能将备忘录传递给其他对象。Originator能够看到一个宽接口,允许它访问返回到先前状态所需的所有数据。理想的情况是只允许生成备忘录的那个Originator访问本备忘录的内部状态。
◊ Originator
° 创建一个备忘录,记录当前时刻的内部状态。
° 使用备忘录恢复内部状态。
◊ Caretaker
° 负责保存备忘录
° 不能对备忘录的内容进行操作或检查
在备忘录模式中,Caretaker负责把Originator创建的Memento进行备份,当需要的时候,Originator可以再使用Caretaker中保存的Memento进行恢复,Originator中的所有状态被恢复到备份操作之前的状态。
01代码实现:using System;namespace ConsoleApp1{ class Program { static void Main(string[] args) { Originator originator=new Originator(); //设置初始状态"ON" originator.SetState("初始状态为:"+"ON"); //显示状态 originator.Show(); // 保存初始状态 Caretaker caretaker=new Caretaker(); caretaker.SetMemento(originator.CreateMemento()); //改变初始状态"ON"为"OFF" originator.SetState("改变状态为:"+"OFF"); originator.Show(); //恢复初始状态 originator.SetState(caretaker.GetMemento().GetState()); Console.Write("恢复原始状态:"); originator.Show(); Console.ReadKey(); } } ////// 备忘录类 /// public class Memento { private string state; public Memento(string state) { this.state = state; } public string GetState() { return state; } } ////// 发起人 /// class Originator { //属性 private string state; public string GetState() { return state; } public void SetState(string state) { this.state = state; } //创建备忘录 public Memento CreateMemento() { return new Memento(state); } //恢复备忘录,将Memento导入并将相关数据恢复 public void ResumeMemento(Memento memento) { state = memento.GetState(); } //显示数据 public void Show() { Console.WriteLine(state); } } ////// 管理类 /// class Caretaker { public Memento memento; public Memento GetMemento() { return memento; } public void SetMemento(Memento memento) { this.memento = memento; } }}
02代码实现:
class Program { static void Main(string[] args) { Originator originator=new Originator(); originator.SetState("100"); originator.ShowState(); //保存状态 Caretaker caretaker=new Caretaker(); caretaker.SetMemento(originator.CreateMemento()); //设置新的状态 originator.SetState("200"); originator.ShowState(); //恢复状态 originator.SetMemento(caretaker.GetMemento()); originator.ShowState(); Console.ReadKey(); } } //备忘录 class Memento { private string state; public Memento(string state) { this.state = state; } public string GetState() { return state; } } //发起人 class Originator { private string state; public void SetState(string state) { this.state = state; } public void ShowState() { Console.WriteLine("当前的状态:"+this.state); } //创建备忘录保存状态 public Memento CreateMemento() { return new Memento(state); } //恢复备忘录 public void SetMemento(Memento memento) { state = memento.GetState(); } } //管理者 class Caretaker { private Memento memento; public void SetMemento(Memento memento) { this.memento = memento; } public Memento GetMemento() { return memento; } }
示例:
游戏的某个场景,一游戏角色有生命力、攻击力、防御力等数据,在打boss前后一定会不一样,我们允许玩家如果感觉与boss决斗的效果不理想可以让游戏恢复到决斗前。03例子:
using System;namespace 备忘录模式例子{ ////// 用程序模拟一个场景:游戏的某个场景,一游戏角色有生命力、攻击力、防御力等数据 /// 在打boss前后一定会不一样,我们允许玩家如果感觉与boss决斗的效果不理想可以让游戏恢复到决斗前 /// class Program { static void Main(string[] args) { // 游戏角色初始状态 GameRole role =new GameRole(); role.GetInitState(); role.Show(); RoleStateCaretake caretake=new RoleStateCaretake(); //保存初始状态 caretake.SetRoleStateMemento(role.SaveState()); //改变状态 role.Fight(); role.Show(); //恢复之前的状态 role.RecoveryState(caretake.GetMemento()); role.Show(); Console.ReadKey(); } } //游戏角色类 class GameRole { private int hp;//生命力 private int attack;// 攻击力 public void Show() { Console.Write("角色当前状态:"); Console.WriteLine("hp:"+hp); Console.WriteLine("attaak:"+attack); } //初始状态 public void GetInitState() { hp = 100; attack = 100; } //属性改变 public void Fight() { hp = 0; attack = 0; } // 保存角色状态,将两个值通过实例化:角色状态存储箱返回 public RoleStateMemento SaveState() { return new RoleStateMemento(hp,attack); } //恢复状态 public void RecoveryState(RoleStateMemento memento) { hp = memento.GetHP(); attack = memento.GetAttack(); } } //角色状态存储箱类 class RoleStateMemento { private int hp;//生命力 private int attack;//攻击力 // 将生命力、攻击力存入状态存储箱对象中 public RoleStateMemento(int hp,int attack) { this.hp = hp; this.attack = attack; } public int GetHP() { return hp; } public int GetAttack() { return attack; } } //角色状态管理者 class RoleStateCaretake { private RoleStateMemento roleStateMemento; public RoleStateMemento GetMemento() { return roleStateMemento; } public void SetRoleStateMemento(RoleStateMemento roleStateMemento) { this.roleStateMemento = roleStateMemento; } }}
转载地址:http://gjrxo.baihongyu.com/