在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
存储Originator对象的内部状态。 纪念品可以根据其发起人的自由裁量权,尽可能多地或尽可能少地存储发起人的内部状态。
防止除发起者以外的对象访问。 memento有两个有效的接口。 看管人看到了纪念品的一个狭窄的接口——它只能把纪念品传递给其他物体。 相比之下,发起者看到的是一个广泛的接口,一个允许它访问所有必要的数据来恢复自己到之前的状态。 理想情况下,只有产生纪念品的发起者才能访问纪念品的内部状态。
创建一个包含当前内部状态快照的纪念品。
使用纪念品恢复其内部状态
using UnityEngine;
using System.Collections;
public class MementoStructure : MonoBehaviour
{
void Start ( )
{
Originator o = new Originator();
o.State = "On";
// Store internal state
Caretaker c = new Caretaker();
c.Memento = o.CreateMemento();
// Continue changing originator
o.State = "Off";
// Restore saved state
o.SetMemento(c.Memento);
}
}
///
/// The 'Originator' class
///
class Originator
{
private string _state;
// Property
public string State
{
get {
return _state; }
set
{
_state = value;
Debug.Log("State = " + _state);
}
}
// Creates memento
public Memento CreateMemento()
{
return (new Memento(_state));
}
// Restores original state
public void SetMemento(Memento memento)
{
Debug.Log("Restoring state...");
State = memento.State;
}
}
///
/// The 'Memento' class
///
class Memento
{
private string _state;
// Constructor
public Memento(string state)
{
this._state = state;
}
// Gets or sets state
public string State
{
get {
return _state; }
}
}
///
/// The 'Caretaker' class
///
class Caretaker
{
private Memento _memento;
// Gets or sets memento
public Memento Memento
{
set {
_memento = value; }
get {
return _memento; }
}
}
using UnityEngine;
using System.Collections;
//这段真实的代码演示了Memento模式,它暂时保存并恢复SalesProspect的内部状态。
namespace MementoExample1
{
public class MementoExample1 : MonoBehaviour
{
void Start()
{
SalesProspect s = new SalesProspect();
s.Name = "Bruce";
s.Phone = "(412) 256-6666";
s.Budget = 25000.0;
// Store internal state
ProspectMemory m = new ProspectMemory();
m.Memento = s.SaveMemento();
// Continue changing originator
s.Name = "Oliver";
s.Phone = "(310) 209-8888";
s.Budget = 1000000.0;
// Restore saved state
s.RestoreMemento(m.Memento);
}
}
///
/// The 'Originator' class
///
class SalesProspect
{
private string _name;
private string _phone;
private double _budget;
// Gets or sets name
public string Name
{
get {
return _name; }
set
{
_name = value;
Debug.Log("Name: " + _name);
}
}
// Gets or sets phone
public string Phone
{
get {
return _phone; }
set
{
_phone = value;
Debug.Log("Phone: " + _phone);
}
}
// Gets or sets budget
public double Budget
{
get {
return _budget; }
set
{
_budget = value;
Debug.Log("Budget: " + _budget);
}
}
// Stores memento
public Memento SaveMemento()
{
Debug.Log("\nSaving state --\n");
return new Memento(_name, _phone, _budget);
}
// Restores memento
public void RestoreMemento(Memento memento)
{
Debug.Log("\nRestoring state --\n");
this.Name = memento.Name;
this.Phone = memento.Phone;
this.Budget = memento.Budget;
}
}
///
/// The 'Memento' class
///
class Memento
{
private string _name;
private string _phone;
private double _budget;
// Constructor
public Memento(string name, string phone, double budget)
{
this._name = name;
this._phone = phone;
this._budget = budget;
}
// Gets or sets name
public string Name
{
get {
return _name; }
set {
_name = value; }
}
// Gets or set phone
public string Phone
{
get {
return _phone; }
set {
_phone = value; }
}
// Gets or sets budget
public double Budget
{
get {
return _budget; }
set {
_budget = value; }
}
}
///
/// The 'Caretaker' class
///
class ProspectMemory
{
private Memento _memento;
// Property
public Memento Memento
{
set {
_memento = value; }
get {
return _memento; }
}
}
}
/*
提供一种方便地存储对象以前状态的方法
*
*纪念品:存储在不同状态下的基本对象
*
* originator:设置和获取当前目标纪念品的值。 创建新的备忘录并将当前值赋给它们
*
*看守:持有一个列表,包含所有之前的版本的纪念品。 它可以存储和检索存储的纪念品
*
* */
namespace MementoExample2
{
public class MementoExample2 : MonoBehaviour
{
Caretaker caretaker = new Caretaker();
Originator originator = new Originator();
int savedFiles = 0, currentArticle = 0;
void Start()
{
// here we do some virtual typing and saving texts:
Save("Tex1: Hello World, this is text example 1");
Save("Text2: Ok here comes example number 2.");
Save("Text3: And example number 3. Just testing.");
Save("Text4: ....");
// Here we do some virtual button pressing
Debug.Log("Pressing Undo");
Undo();
Debug.Log("Pressing Undo");
Undo();
Debug.Log("Pressing Undo");
Undo();
Debug.Log("Pressing Redo");
Redo();
}
// these methods below might get called when someone is pressing a button
// you could easily implement it with unitys new ui system :)
public void Save(string text)
{
originator.Set(text);
caretaker.Add(originator.StoreInMemento());
savedFiles = caretaker.GetCountOfSavedArticles();
currentArticle = savedFiles;
}
public string Undo()
{
if (currentArticle > 0)
currentArticle -= 1;
Memento prev = caretaker.Get(currentArticle);
string prevArticle = originator.RestoreFromMemento(prev);
return prevArticle;
}
public string Redo()
{
if (currentArticle < savedFiles)
currentArticle += 1;
Memento next = caretaker.Get(currentArticle);
string nextArticle = originator.RestoreFromMemento(next);
return nextArticle;
}
}
///
/// the basic object that is stored in different states
///
public class Memento
{
public string article {
get; protected set; }
// Base Memento class that in this case just stores article strings!:)
public Memento(string article)
{
this.article = article;
}
}
///
/// sets and gets values from the currently targeted memento. Creates new memenots and assigns current values to them.
///
public class Originator
{
public string article {
get; protected set; }
public void Set(string article)
{
Debug.Log("From Originator: Current Version of article is: [\"" + article + "\"]");
this.article = article;
}
public Memento StoreInMemento()
{
Debug.Log("From Originator: Saving in Memento: [\"" + this.article + "\"]");
return new Memento(this.article);
}
public string RestoreFromMemento(Memento memento)
{
article = memento.article;
Debug.Log("From Originator: Previous Article saved in Memento: [\"" + article + "\"]");
return article;
}
}
///
/// holds an list that contains all previous versions of the memento. it can store and retrieve stored mementos
///
public class Caretaker
{
List<Memento> savedArticles = new List<Memento>();
public void Add(Memento m)
{
savedArticles.Add(m);
}
public Memento Get(int i)
{
return savedArticles[i];
}
public int GetCountOfSavedArticles()
{
return savedArticles.Count;
}
}
}