38备忘录模式(Memento Pattern)

对象状态的回溯:
    对象状态的变化无端,如何回溯/恢复对象在某个点的状态?
                        
动机:
    在软件构建过程中,某些对象的状态在转换过程中,可能由于某种需要,要求程序能够回溯到对象之前处于某个点时的状态。如果使用一些公有接口来让其他对象得到对象的状态,便会暴露对象的细节实现。
    如何实现对象状态的良好保存与恢复?但同时又不会因此而破坏对象本身的封装性。
意图:
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后可以将该对象恢复到原先保存的状态。

          
适用性:
    1.必须保存一个对象某一个时刻的(部分)状态,这样以后需要时它才能恢复到先前的状态。
    2.如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。

代码实现:

 1     class Memento
 2     {
 3         private string name;
 4         private string phone;
 5         private double budget;
 6 
 7         //Constructor
 8         public Memento(string name, string phone, double budget)
 9         {
10             this.name = name;
11             this.phone = phone;
12             this.budget = budget;
13         }
14         //Properties
15         public string Name
16         {
17             get { return name; }
18             set { name = value; }
19         }
20         public string Phone
21         {
22             get { return phone; }
23             set { phone = value; }
24         }
25         public double Budget
26         {
27             get { return budget; }
28             set { budget = value; }
29         }
30     }

 

 1     class ProspectMemory
 2     {
 3         private Memento memento;
 4 
 5         //Property
 6         public Memento Memento
 7         {
 8             set { memento = value; }
 9             get { return memento; }
10         }
11     }

 

 1   //Originator
 2     class SalesProspect
 3     {
 4         private string name;
 5         private string phone;
 6         private double budget;
 7 
 8         //Properties
 9         public string Name
10         {
11             get { return name; }
12             set { name = value; Console.WriteLine("Name:" + name); }
13         }
14         public string Phone
15         {
16             get { return phone; }
17             set { phone = value; Console.WriteLine("Phone:" + phone); }
18         }
19         public double Budget
20         {
21             get { return Budget; }
22             set { budget = value; Console.WriteLine("Budget:" + budget); }
23         }
24         public Memento SaveMemento()
25         {
26             Console.WriteLine("\nSaving state --\n");
27             return new Memento(name, phone, budget);
28         }
29         public void RestoreMemento(Memento memento)
30         {
31             Console.WriteLine("\nRestoring state --\n");
32             this.Name = memento.Name;
33             this.Phone = memento.Phone;
34             this.Budget = memento.Budget;
35         }
36     }

 

 1    class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             SalesProspect s = new SalesProspect();
 6             s.Name = "xiaoming";
 7             s.Phone = "(010)65236523";
 8             s.Budget = 28000.0;
 9 
10             //Store internal state
11             ProspectMemory m = new ProspectMemory();
12             m.Memento = s.SaveMemento();
13 
14             //Continue changing originator
15             s.Name = "deke";
16             s.Phone = "(029)85423657";
17             s.Budget = 80000.0;
18 
19             //Restore saved state 
20             s.RestoreMemento(m.Memento);
21 
22             //Wait for user 
23             Console.Read();
24         }
25     }


Memento需要注意的几个要点:
    1.备忘录(Memento)存储原发器(Originator)对象的内部状态,在需要时恢复原发器状态。Memento模式适用于“由原发器管理,却又必须存储在原发器之外的信息”。
    2.在实现Memento模式中,要防止原发器以外的对象访问备忘录对象。备忘录对象有两个接口,一个为原发器的宽接口;一个为其他对象使用的窄接口。
    3.在实现Memento模式时,要考虑拷贝对象状态的效率问题,如果对象开销比较大,可以采用某种增量式改变来改进Memento模式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/438628.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python剪切文件如何恢复_用python实现的可以拷贝或剪切一个文件列表中的所有文件...

# coding:utf-8import osimport sysdef cut_and_paste_file(source, destination):source: file path 中文destination: directory pathdef format_path(path):if not os.path.isabs(path):path os.path.join(os.getcwd(), path)return pathdef mk_dir(path):if not os.path.e…

39策略模式(Strategy Pattern)

算法与对象的耦合: 对象可能经常需要使用多种不同的算法,但是如果变化频繁,会将类型变得脆弱... 动机: 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将…

python选择表单_如何使用Python在表单中选择选项?

下面是一些基本用法示例:>>> import mechanize>>> br mechanize.Browser()>>> br.open(http://www.w3schools.com/html/html_forms.asp)表单有一个name属性;但有时它是空的:>>> [f.name for f in br.fo…

40访问者模式(Visitor Pattern)

类层次结构的变化: 类层次结构中可能经常由于引入新的操作,从而将类型变得脆弱... 动机: 在软件构建过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接…

ssh中c3p0连接mysql_ssh 中使用c3p0 的连接池配置 | 学步园

applicationContext.xml 文件:xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xmlns:jee"http://www.springframework.org/schema/jee"xsi:schemaLocation"http://www.springframework.org/schema/beans http://www.springframewor…

41状态模式(State Pattern)

对象状态影响对象行为: 对象拥有不同的状态,往往会行使不同的行为... 动机: 在软件构建过程中,某些对象的状态如果改变以及其行为也会随之而发生变化,比如文档处于只读状态,其支…

python中空格属于字符吗_举例说明python中空格是属于字符

python中空格属于字符吗?答案是肯定的,空格在Python中也是属于字符的。案例:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。#!/usr/bin/python# -*- coding: UTF-8 -*-import strings raw_input(input a st…

python如何引发和处理异常_在python3.6中,如何捕捉异常并引发异常以便稍后处理?...

假设我有两个例外:class FooError (Exception):def __init__(self, *args, **kwargs):default_message A foo error has occurred!if not (args or kwargs): args (default_message,)super().__init__(*args, **kwargs)class BarError (Exception):def __init__(s…

2字节十六进制浮点数 qt_Qt之8个字节转化为double小数

首先要理解double的存储方式,具体可查找相关的博客本文实现的是将8个字节(存储为16进制的字符串)转化为对应的double类型double MainWindow::qByteArraytodouble(QString qstr){QByteArray byte;StringToHex(qstr,byte);double result;memcpy(&result, byte.dat…

【转】如何将域中的AD数据导入SharePoint

最近刚装好sharepoint2010,想要研究一下,第一件想做的事就是想把AD中的用户信息导入到SharePoint中。 那现在就来看看我是怎么操作的: 1.打开管理中心 sharepoint是通过“用户配置文件同步服务”来实现同步,所以第一步要开启这个…

Apsara Clouder专项技能认证:实现调用API接口

一.API 简介 1.API 的概念 API(Application Programming Interface应用程序编程接口)是一些预定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码或理解内部工作机制的细节 2.API 的特点 API 是一个明确定义的接口,可以为其…

druid加密mysql_Druid 数据库用户密码加密 代码实现

标签:druid-1.0.16.jar 阿里巴巴的开源数据连接池 jar包明文密码私钥(privateKey)加密加密密码加密密码公钥(publicKey)解密明文密码程序代码如下:package com.t1;import com.alibaba.druid.filter.config.ConfigTools;public class DruidTest {public s…

select switch语句总是搞混,总结如下

select switch语句总是搞混,总结如下 类C:c c c# java : 比较 switch(expression) { case constant-expression : statement(s); break; /* optional */ case constant-expression : statement(s); brea…

java路径怎么找_Java路径怎么找

有一种情况是装好java了,配置好java环境(在Linux里面比较复杂)了,但忘了路径了?!解决:先要申明一下which java是定位不到安装路径的。which java定位到的是java程序的执行路径。网上的资料都是人云亦云,完全…

【转】什么是CORS

CORS 全称是跨域资源共享(Cross-Origin Resource Sharing),是一种 AJAX 跨域请求资源的方式,支持现代浏览器,IE支持10以上。 CORS与JSONP的使用目的相同,但是比JSONP更强大。JSONP只支持GET请求&#xff0c…

java web 连接linux_如何将javaweb项目部署到linux下

以下是对将javaweb项目部署到linux下的方法进行了详细的分析介绍一般都在windows下开发的现在部署到linux下将项目达成war包(用eclipse项目右键>Export>选择war file)将tomcat(用winSCP当然你也可以用secureCRT用securCRT需要建立sftp(即上传文件的目录)用put tomcat命令…

第一节:复习委托,并且通过委托的异步调用开启一个新线程和异步回调、异步等待

一. 再谈委托 1. 委托是一个关键字为delegate的自定义类型,通过委托可以把方法以参数的形式传递给另外一个方法,实现插件式的开发模式; 同时调用委托的时候,委托所包含的所有方法都会被实现。 2. 委托的发展历史:new…

linux 修改 java 内存_Linux 和 Windows修改Java虚拟机内存大小

因为内存溢出问题1. Linux下直接修改%tomcat_home%/bin/catalina.sh文件在注释下紧接一行也就是脚本正文开始之前 加上Java_OPTS-server -Xms512m -Xmx1024m -XX:PermSize128m -XX:MaxPermSize512m如果报-x没有定义,则用declare -x JAVA_OPTS"-Xms512m -Xmx1024"初始…

第二节:深入剖析Thread的五大方法、数据槽、内存栅栏

一. Thread及其五大方法 Thread是.Net最早的多线程处理方式,它出现在.Net1.0时代,虽然现在已逐渐被微软所抛弃,微软强烈推荐使用Task(后面章节介绍),但从多线程完整性的角度上来说,我们有必要了解下N年前多线程的是怎么…

java redis 生成唯一id_Redis在集群环境中生成唯一ID

概述设计目标:每秒最大生成10万个ID,ID单调递增且唯一。Reidis可以不需要持久化ID。要求:集群时钟不能倒退。总体思路:集群中每个节点预生成生成ID;然后与redis的已经存在的ID做比较。如果大于,则取节点生成的ID&#…