设计模式--备忘录模式
世界上没有后悔药,但是我们在进行软件设计时要给用户后悔的选择,我们对一些日常性或者关键性的操作需要为用户提供诸如撤销的操作。其实这个操作就是由备忘录(Memento)模式提供的。
目录
一、模式初识
1.什么是备忘录(Memento)模式?
备忘录(Memento)模式的关键要在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以利用保存的状态实施回复操作。
2.备忘录(Memento)模式的基本结构是怎样的?
废话不多说直接上UML图--->
对的兄弟萌,它就这个熊样。
3.每个成员的含义又是如何的?
①Originator(原发器):创建一个备忘录,记录当前状态,也可用备忘录来恢复其内部状态。
②Memento(备忘录):存储原发器的内部状态。
③Caretaker(负责人/管理者):可以存储一个或多个备忘录对象,它只负责存储对象,而不能修改对象,也无须知道对象的实现细节。多对象存储可以用到数组、链表、泛型等。
二、模式深入
1.优点:
①使用备忘录模式可以把复杂的发起人内部信息对其他的对象封闭起来,从而可以恰当的保持封装的边界。
②本模式简化发起人类。发起人无需管理内部状态,客户端可以自行管理他们需要的这些状态的版本。
③使用暂存在备忘录中的状态信息,完成状态复原。
2.缺点:
①如果发起人角色的状态需要完整的存储到备忘录中,那么在备忘录中的资源消耗会很大。
②当管理者角色将一个备忘录。
3.使用场景:如果必须保存一个对象在某一时刻的全部或者部分状态,方便在以后需要的时候,可以把该对象恢复到向前的状态,可以使用备忘录模式。
4.本质:保存和恢复内部状态
5.备忘录模式可以和原型模式组合使用
在原发器对象(发起人)创建备忘录的对象的时候,如果原发器对象中全部或者大部分的状态都需要保存,一个简洁的方式就是直接克隆一个原发器对象。
三、模式实例
象棋中悔棋的实现(C#)
UML图如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 备忘录模式
{
class Chessman
{
private string label;
private int x;
private int y;
public Chessman(string label, int x, int y)
{
this.label = label;
this.x = x;
this.y = y;
}
public string Label
{
get { return label; }
set { label = value; }
}
public int X
{
get { return x; }
set { x = value; }
}
public int Y
{
get { return y; }
set { y = value; }
}
public ChessmanMemento save()
{
return (new ChessmanMemento(label, x, y));
}
public void restore(ChessmanMemento memento)
{
this.label = memento.Label;
this.x = memento.X;
this.y = memento.Y;
}
public void show()
{
Console.WriteLine("棋子当前状态:");
Console.WriteLine("棋子:{0}",this.Label);
Console.WriteLine("X位置:{0}",this.X);
Console.WriteLine("Y位置:{0}",this.Y);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 备忘录模式
{
class ChessmanMemento
{
private string label;
private int x;
private int y;
public ChessmanMemento(string label,int x,int y)
{
this.label = label;
this.x = x;
this.y = y;
}
public string Label
{
get { return label; }
set { label = value; }
}
public int X
{
get { return x; }
set { x = value; }
}
public int Y
{
get { return y; }
set { y = value; }
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 备忘录模式
{
class ChessmanCaretaker
{
private ChessmanMemento memento;
public ChessmanMemento Memento
{
get { return memento; }
set { memento = value; }
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 备忘录模式
{
class Program
{
static void Main(string[] args)
{
Chessman chess = new Chessman("象", 100, 20);
chess.show();
ChessmanCaretaker care = new ChessmanCaretaker();
care.Memento = chess.save();
chess.X = 0;
chess.Y = 10;
chess.show();
chess.restore(care.Memento);
chess.show();
Console.ReadLine();
}
}
}