备忘录模式

基本理解

  • 这个模式有三个关键角色:原发器(Originator)、备忘录(Memento)、看管人(caretaker)。三者的基本关系是:原发器创建一个包含其状态的备忘录,并传给看管人。看管人不知道如何与备忘录交互,但会把备忘录放在一个安全之处保管好。
  • 备忘录(Memento):在 不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象回复到原先保存的状态。
  • Originator(发起人):负责创建一个备忘录,用以记录当前时刻它的内部状态,并且可使用恢复备忘录内部状态。Originator可根据需要决定Memento存储Originator的哪些内部状态。
  • Memento(备忘录):负责存储Originator对象的内部状态,并可防止Originator以外的其他对象访问备忘录。备忘录有两个接口,CareTaker

    只能看到备忘录的窄接口,它只能将备忘录传给其他对象。originator能够看到一个宽接口,允许它访问返回到先前状态所需的所有数据。
  • Caretaker(管理者):负责保存好备忘录,不能对备忘录的内容进行操作或检查。
  • 就是把要保存的细节给封装在了Memento中,哪一天要更改保存的细节也不用影响客户端了。

备忘录使用场合

  • 备忘录模式比较适用于功能比较复杂的,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时,Orignator可以根据保存的Memento信息还原到前一状态。
  • 如果在某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储撤销操作的状态。有的时候一些对象的内部信息必须要保存在对象以外的地方,但是必须要由对象自己读取,这时,使用备忘录可以把复杂的对象内部信息对其他的对象屏蔽起来。
  • 用于获取状态的接口会暴露实现接口,需要将其屏蔽起来。
  • 它一般应用于游戏、文字处理程序的设计中,这种程序需要保存当前上下文的复杂状态的快照并在以后恢复处理。

作用

  • 当角色的状态改变时,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。

Cocoa Touch框架中的备忘录模式

  • Cocoa Touch框架在归档、属性列表序列化和核心数据采用了备忘录模式。

    • Cocoa的归档是对对象以及其属性还有同其他对象间的关系进行编码,形成一个文档,该文档既可保存与文件系统中,也可在进程或网络间传送。对象与其他对象的关系被看做对象图的网络。

    • 归档过程把对象保存为一种与架构无关的字节流,保持对象的标识以及对象之间的关系。对象的类型也同数据一起保存。从字节流解码出来的对象通常用于对象编码时相同的类进行实例化。使用NSCoder的具体类NSKeyedArchiver和NSKeyedUnarchiver,使用基于键的归档技术,被编码与解码的对象必须遵守NSCoding协议并实现以下方法:

      -(id)initWithCoder:(NSCoder *)coder;

      -(void)encodeWithCoder:(NSCoder *)coder;

例子

该例子就是通过备忘录模式来保存Student的实例stu1更改名字和地址之前的原名字和地址。然后stu1恢复原来的名字和地址。具体代码如下:

Caretaker.h

//
// Caretaker.h
// memoDemo
//
// Created by zhanggui on 15/8/8.
// Copyright (c) 2015年 zhanggui. All rights reserved.
// #import <Foundation/Foundation.h>
@class Memo;
@interface Caretaker : NSObject @property(nonatomic,strong) Memo *memo;
@end

Caretaker.m

//
// Caretaker.m
// memoDemo
//
// Created by zhanggui on 15/8/8.
// Copyright (c) 2015年 zhanggui. All rights reserved.
// #import "Caretaker.h" @implementation Caretaker @end

上面这个是看管人。

Memo.h

//
// Memo.h
// memoDemo
//
// Created by zhanggui on 15/8/8.
// Copyright (c) 2015年 zhanggui. All rights reserved.
// #import <Foundation/Foundation.h> @interface Memo : NSObject
{
NSString *tempname;
NSString *tempaddress;
} -(Memo *)initWithName:(NSString *)name andWithAddress:(NSString *)address; -(NSString *)getName; -(NSString *)getAddress;
@end

Memo.m

//
// Memo.m
// memoDemo
//
// Created by zhanggui on 15/8/8.
// Copyright (c) 2015年 zhanggui. All rights reserved.
// #import "Memo.h" @implementation Memo -(Memo *)initWithName:(NSString *)name andWithAddress:(NSString *)address
{
tempname = name;
tempaddress = address;
return self;
} -(NSString *)getAddress
{
return tempaddress;
}
-(NSString *)getName
{
return tempname;
}
@end

上面这个是备忘录。

Student.h

//
// Student.h
// memoDemo
//
// Created by zhanggui on 15/8/8.
// Copyright (c) 2015年 zhanggui. All rights reserved.
// #import <Foundation/Foundation.h>
@class Memo;
@interface Student : NSObject @property(nonatomic,strong)NSString *myName;
@property(nonatomic,strong)NSString *address; -(Memo *)createMemo;
-(void)setMemo:(Memo *)memo; -(void)display;
@end

Student.m

//
// Student.m
// memoDemo
//
// Created by zhanggui on 15/8/8.
// Copyright (c) 2015年 zhanggui. All rights reserved.
// #import "Student.h"
#import "Memo.h"
@implementation Student -(Memo *)createMemo {
return [[Memo alloc] initWithName:_myName andWithAddress:_address];
} -(void)setMemo:(Memo *)memo
{
_myName = [memo getName];
_address = [memo getAddress];
} -(void)display
{
NSLog(@"State is name:%@;address:%@",_myName,_address);
}
@end

上面这个是Student。然后看一下具体的调用:

//
// ViewController.m
// memoDemo
//
// Created by zhanggui on 15/8/8.
// Copyright (c) 2015年 zhanggui. All rights reserved.
// #import "ViewController.h"
#import "Memo.h"
#import "Caretaker.h"
#import "Student.h"
@interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
Student *stu1 = [[Student alloc] init];
[stu1 setMyName:@"zhangsan"];
[stu1 setAddress:@"he nan xin xiang"];
[stu1 display]; //use caretaker to save old name and address
Caretaker *careTaker = [[Caretaker alloc] init];
[careTaker setMemo:[stu1 createMemo]]; //updated name and address
[stu1 setMyName:@"zhangxiaoqiang"];
[stu1 setAddress:@"bei jing san huan"];
[stu1 display]; //back to old name and address
[stu1 setMemo:[careTaker memo]];
[stu1 display];
} @end

也就是把zhangsan原来的姓名和地址先保存到备忘录中,可是过了一段时间zhangsan不行用自己的新名字和地址了,所有就通过备忘录来还原自己的姓名和地址。

附:

iOS设计模式之备忘录模式的更多相关文章

  1. iOS 设计模式之工厂模式

    iOS 设计模式之工厂模式 分类: 设计模式2014-02-10 18:05 11020人阅读 评论(2) 收藏 举报 ios设计模式 工厂模式我的理解是:他就是为了创建对象的 创建对象的时候,我们一 ...

  2. 乐在其中设计模式(C#) - 备忘录模式(Memento Pattern)

    原文:乐在其中设计模式(C#) - 备忘录模式(Memento Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 备忘录模式(Memento Pattern) 作者:webabc ...

  3. 折腾Java设计模式之备忘录模式

    原文地址:折腾Java设计模式之备忘录模式 备忘录模式 Without violating encapsulation, capture and externalize an object's int ...

  4. C#设计模式:备忘录模式(Memento Pattern)

    一,C#设计模式:备忘录模式(Memento Pattern) 1.发起人角色(Originator):记录当前时刻的内部状态,负责创建和恢复备忘录数据.负责创建一个备忘录Memento,用以记录当前 ...

  5. js设计模式——7.备忘录模式

    js设计模式——7.备忘录模式 /*js设计模式——备忘录模式*/ // 备忘类 class Memento { constructor(content) { this.content = conte ...

  6. java设计模式之备忘录模式

    备忘录模式 备忘录模式是一种软件设计模式:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态.一听到备忘录这个字的时候想起了小小时打的游 ...

  7. 【GOF23设计模式】备忘录模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_备忘录模式.多点备忘.事务操作.回滚数据底层架构 package com.test.memento; /** * 源发器类 ...

  8. [设计模式] 18 备忘录模式Memento Pattern

    在GOF的<设计模式:可复用面向对象软件的基础>一书中对备忘录模式是这样说的:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存 ...

  9. 再起航,我的学习笔记之JavaScript设计模式24(备忘录模式)

    备忘录模式 概念介绍 备忘录模式(Memento): 在不破坏对象的封装性的前提下,在对象之外捕获并保存该对象内部的状态以便日后对象使用或者对象恢复到以前的某个状态. 简易分页 在一般情况下我们需要做 ...

随机推荐

  1. Qt5 从头学(1)-- 环境

    对我来说MFC太过麻烦了,同样是桌面开发工具,Qt就完全不一样了.Qt使用C++语言可以轻松实现"一次编写,到处编译"的跨平台性能,并且可以做出很多炫酷的界面效果.目前支持几乎所有 ...

  2. MFC ADO连接Oracle12c数据库 客户端环境搭建

    ADO连接方式一:Provider=MSDAORA.1; 环境配置如下: 去官网下载ODAC121024Xcopy_32bit.zip安装 安装方式如下: (1)解压文件 (2)用命令行CD到该文件的 ...

  3. 跨域名 Cookie 传递测试

    问题 我打开了 www.aaa.com 里面的一个页面(www.aaa.com/hello.php),其中这个 hello.php 里面包含一个 <img> 标签,里面的 src 来自于 ...

  4. 基于kubernetes构建Docker集群管理详解-转

    http://blog.liuts.com/post/247/ 一.前言        Kubernetes 是Google开源的容器集群管理系统,基于Docker构建一个容器的调度服务,提供资源调度 ...

  5. android小技巧和注意事项

    在listView 或者 gridView 的使用中,通常不仅仅为了展现数据,更多的是操作数据.于是当控件重合在一起时,我们需要添加事件.就会出现一个问题,当点击一个控件和长按这个控件时,常常出现长按 ...

  6. OpenCV开发环境配置-Windows/MinGW/Clion/CMake

    临时更换成了TDM-GCC,和mingw类似,这里只是声明一下. 由于opencv下载下来的.exe安装包实际上是没有mingw(gcc)匹配的/动静态库,因此这些东西需要我们自己使用mingw编译. ...

  7. mobile 更改hosts

    在Android下,/etc是link到/system/etc的,我们需要修改/system/etc/hosts来实现.但是这个文件是只读,不能通过shell直接修改.可以通过连接到PC上使用adb来 ...

  8. ASP.NET高并发解决方案

    一.页面静态化: 二.运用WCF,WEB SERVICE等技术实现分布式业务逻辑处理及数据访问的能力: 三.页面缓存: 四.数据缓存: 五.建立图片文件服务器:

  9. 关于 CommonJS AMD CMD UMD 规范的差异总结

    一.CommonJS 主要是用于服务器端的规范,比如目前的nodeJS. 根据CommonJS规范,一个单独的文件就是一个模块.每一个模块都是一个单独的作用域,也就是说,在一个文件定义的变量(还包括函 ...

  10. C#设计模式——迭代器模式(Iterator Pattern)

    一.概述在软件开发过程中,我们可能会希望在不暴露一个集合对象内部结构的同时,可以让外部代码透明地访问其中包含的元素.迭代器模式可以解决这一问题.二.迭代器模式迭代器模式提供一种方法顺序访问一个集合对象 ...