三九宝宝网宝宝百科性格养成

C#基础Memento备忘录模式行为型模式

11月11日 编辑 39baobao.com

[一年级英语下册单元试题1A PRACTICE 8]Vocabulary (30 marks) (A) Fill in the blanks with the appropriate words. (10*1 = 10 marks) bouquet fruiterer nest receipt parcel hurry spider badminton portrait...+阅读

在软件构建过程中,某些对象的状态在转换过程中,可能由于某种需要,要求程序能够回溯到对象之前处于某个点时的状态.如果使用一些共有接口来让其他对象得到对象的状态,便会暴露对象的细节实现。我们需要实现对象状态的良好保存与恢复,但同时不会因此而破坏对象本身的封装性。

Examda提示:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。

我们首先看看不适用设计模式来解决对象状态恢复的情况。

public class Rectangle : ICloneable

{

int x;

int y;

int width;

int height;

public void SetValue(Rectangle r)

{

this.x = r.x;

this.y = r.y;

this.width = r.width;

this.height = r.height;

}

public Rectangle(int x, int y, int width, int height)

{

this.x = x;

this.y = y;

this.width = width;

this.height = height;

}

public void MoveTo(Point p)

{

....

}

public void ChangeWidth(int width)

{

}

public void ChangeHeight(int height)

{

}

public void Draw(Graphics graphic)

{

}

&emspregion ICloneable 成员

public object Clone()

{

return this.MemberwiseClone();

}

&emspendregion

}

public class GraphicsSystem

{

原发器对象:

有必要对自身内部状态进行保存,然后在某个点处又需要恢复内部状态的对象

Rectangle r = new Rectangle(0, 0, 10, 10);

备忘录对象:

保存原发器对象的内部状态,但不提供原发器对象支持的操作

Rectangle rSed = new Rectangle(0, 0, 10, 10);

public void Process()

{

rSed = r.Clone();

....

}

public void Sed_Click(object sender, EventArgs e)

{

r.SetValue(rSed);

....

}

}

class Program

{

static void Main(string[] args)

{

Rectangle r = new Rectangle(0, 0, 10, 10);

GraphicsSystem g = new GraphicsSystem();

g.Process(r);

}

}

上面的代码中Rectangle类实现了ICloneable接口,这个接口利用浅拷贝返回一个新的Rectangle对象

在GraphicsSystem类中,我们定义了一个原发器对象r,和备忘录对象rSed,在Process的时候,我们将原发器对象进行克隆保存在rSed引用中。在Sed_Click方法中,将备忘录对象rSed保存的值还原给原发器对象r。但这样来做,备忘录对象提过了原发器对象的一些操作,那么我们现在需要将备忘录对象抽象出来。

public class Rectangle

{

int x;

int y;

int width;

int height;

public void SetValue(Rectangle r)

{

this.x = r.x;

this.y = r.y;

this.width = r.width;

this.height = r.height;

}

public Rectangle(int x, int y, int width, int height)

{

this.x = x;

this.y = y;

this.width = width;

this.height = height;

}

public void MoveTo(Point p)

{

....

}

public void ChangeWidth(int width)

{

}

public void ChangeHeight(int height)

{

}

public void Draw(Graphics graphic)

{

}

internal RectangleMemento Creatememento()

{

RectangleMemento memento = new RectangleMemento();

memento.SetState(this.x, this.y, this.width, this.height);

return memento;

}

internal void SetMemento(RectangleMemento memento)

{

this.x = memento.x;

this.y = memento.y;

this.width = memento.width;

this.height = memento.height;

}

}

internal class RectangleMemento

{

internal int x;

internal int y;

internal int width;

internal int height;

internal void SetState(int x, int y, int width, int height)

{

this.x = x;

this.y = y;

this.width = width;

this.height = height;

}

}

public class GraphicsSystem

{

原发器对象:

有必要对自身内部状态进行保存,然后在某个点处又需要恢复内部状态的对象

Rectangle r = new Rectangle(0, 0, 10, 10);

备忘录对象:

保存原发器对象的内部状态,但不提供原发器对象支持的操作

RectangleMemento rSed = new RectangleMemento();

public void Process(Rectangle r)

{

rSed = r.Creatememento();

....

}

public void Sed_Click(object sender, EventArgs e)

{

r.SetMemento(rSed);

....

}

}

在上面这段代码中,我们将备忘录对象抽象出来为RectangleMemento类,这个类只保存了原发器对象基本的值,但没有提供其他的操作,并且,我们将RectangleMemento类和内部成员全部申明为internal只能让程序集本身调用,保证了RectangleMemento对象的封装性。

实现要点:

备忘录存储原发器(Originator)对象的内部状态,在需要时恢复原发器状态。Memento模式适用于由原发器管理,却又必须存储在原发器之外的信息

在实现Memento模式中,要防止原发器以外的对象方位备忘录对象,备忘录对象有两个接口,一个为原发器使用的宽接口,一个为其他对象使用的窄接口

在实现Memento模式时,要考虑拷贝对象状态的效率问题,如果对象开销比较大,可以采用某种增量式改变来跟进Memnto模式

在上面的例子中Rectangle对于RectangleMemento看到是宽接口,即SetState方法,而GraphicsSystem看到的是窄接口,即RectangleMemento的构造函数和Creatememento、SetMemento方法。 当一个对象比较大的时候,在.中如DataSet,要保存对象的状态可能会造成效率问题,占用比较大的内存。

下面一段代码演示了通过使用序列化的方式来实现Memento模式

[Serializable]

public class Rectangle

{

int x;

int y;

int width;

int height;

public void SetValue(Rectangle r)

{

this.x = r.x;

this.y = r.y;

this.width = r.width;

this.height = r.height;

}

public Rectangle(int x, int y, int width, int height)

{

this.x = x;

this.y = y;

this.width = width;

this.height = height;

}

public void MoveTo(Point p)

{

....

}

public void ChangeWidth(int width)

{

}

public void ChangeHeight(int height)

{

}

public void Draw(Graphics graphic)

{

}

public GeneralMementor CreateMemento()

{

GeneralMementor memento = new GeneralMementor();

memento.SetState(this);

return memento;

}

public void SetMemento(GeneralMementor memento)

{

Rectangle r = memento.GetState() as Rectangle;

SetValue(r);

}

}

public class GeneralMementor

{

MemoryStream rSed = new MemoryStream();

internal void SetState(object obj)

{

BinaryFormatter bf = new BinaryFormatter();

bf.Serialize(rSed, obj);

}

internal object GetState()

{

BinaryFormatter bf = new BinaryFormatter();

rSed.Seek(0, SeekOrigin.End);

object obj = bf.Deserialize(rSed);

return obj;

}

}

public class GraphicsSystem

{

原发器对象:

有必要对自身内部状态进行保存,然后在某个点处又需要恢复内部状态的对象

Rectangle r = new Rectangle(0, 0, 10, 10);

GeneralMementor memntor = null;

备忘录对象:

保存原发器对象的内部状态,但不提供原发器对象支持的操作

public void Process(Rectangle r)

{

memntor = r.CreateMemento();

....

}

public void Sed_Click(object sender, EventArgs e)

{

r.SetMemento(memntor);

....

}

}

上面的代码中我们可以看到将Rectangle原发器保存在内存流里,在恢复的时候,将内存流里的对象进行还原,我们可以更进一步的抽象,可以将对象保存在任何的流里,这里就不做演示了。

以下为关联文档:

新标准二年级英语上册Unit1 Wheres the cat小学二年级英语上册:Unit1-- Where's the cat?(新标准) 1. Listen, point and find "Where's …?" 第2页 Look at the cats. Where? On the bed. Oh yes. How many cats?...

三年级下学期 Recycle 2 第二课时第二课时 【课题】Recycle 2 【教学重点】复习本单元所学水果类、动物类、玩具类、颜色类的词汇以及一些常见的形容词。 【教学难点】主动复习意识的培养和认读能力。 【教...

2012年EEC英语六年级英语上册期末试题一、听录音, 选择正确答案,选项写在题前括号中。(5分) ( )1. A. yesterday B. today C. day ( )2. A. same B. some C. time ( )3. A. subject B. safari C. shout ( )4. A....

一年级英语下册单元试题1A PRACTICE 9Vocabulary (30 marks) (A) Fill in the blanks with the correct words. (12*1 = 12 marks) violin chimpanzee baking helmet terrapins dining canary glutton cobbler p...

2012年eec英语四年级英语上册期末试题PartⅠ、口语测试(10分) 1、 自述chant或自我介绍。 2、 自选小对话表演,可以找搭档,3人以内。 Part Ⅱ、听力测试(10分) 一、选出你听到的单词。(5分) ( ) 1. A、orange B、apple C...

英语一年级下册Unit 11Clothes测试题听录音,圈出正确的单词。(16分) 1、A、dress B、square 2、A、socks B、shirt 3、A、pants B、panda 4、A、shoes B、fish 5、A、watermelon B、juice 6、A、sweater B、clothe...

三年级下学期 Recycle 2 第一课时【课题】 Recycle Two 【教学重点】 听懂、会说Let’s act 部分的故事。 复习有关表述自己喜爱吃某种食品、询问某物或某人在哪里以及含有简单形容词的句子等会话。 【...

三年级下学期 Recycle 1 第三课时【课题】Recycle 1, 第三课时 【教学重点】Make a window card. 【教学难点】英文歌曲的歌词。 【教具准备】 1.1-3单元课文中的某一幅图片 2.单词卡片和单词图片 3.教材相配套...

三年级下学期 Recycle 1 第一课时教学建议 第一课时 一 教材分析 Lets act部分通过给学生展示出一个熟悉的对话情景来再现1-3单元中所学的会话,使学生能够更自然、更好地对Whos...? He/She is...Where are you...

推荐阅读
图文推荐