iOS 设计模式的应用 ㉑ 备忘录模式

前言

    备忘录定义为"作为某人或某事的提醒物或纪念品而保留下来的物品"。每当我们需要记下一个事情时,就会把它写到某个地方。存放的时间长短由信息本身决定,当信息失效以后,我们就会丢弃它。

    在面向对象的设计模式中,借用类似的思想,来保存对象的状态并在后来进行恢复。状态本身被创建为一种对象形式。它封装了原始对象的内部状态。从这一思想设计而来的一种设计模式叫做备忘录模式

什么是备忘录模式

    备忘录模式在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。在响应某些事件时,应用程序需要保存自身的状态。

备忘录模式结构的类图.png

    这个模式有三个角色:原发器(origninator)、备忘录(Menmento) 和看管人(Caretaker)。其思想非常简单。原发器创建一个包含其状态的备忘录,并传给看管人。看管人负责把备忘录放在安全之处保管好。当看管人请求 Origninator 对象保存其状态时,Origninator对象将使用其内部状态创建一个新的 Memento 实例。然后看管人保管 Meomento 对象。在这个过程中,Originator 对象不知道这个 Memento 对象如何被保存。看管人也不知道 Memento 对象是什么。

什么时候使用备忘录模式

  1. 需要保存/恢复数据的相关状态场景。
  2. 提供一个可回滚的操作。

备忘录模式的优缺点

备忘录模式的优点

  1. 给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。
  2. 实现了信息的封装,使得用户不需要关心状态的保存细节。

备忘录模式的缺点

消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。

Cocoa 中的备忘录

Archiver

    归档将程序中的对象与这些对象的属性(属性和关系)一起转换为可以存储在文件系统中或在进程之间或通过网络传输的存档。档案记录了程序的对象图作为独立于体系结构的字节流,保留对象的身份和它们之间的关系。因为对象的类型与其数据一起存储,所以从字节流解码的对象通常使用与最初编码的对象相同的类来实例化。被编码和解码的对象必须符合NSCoding协议,该协议的方法在归档期间被调用。

Property List 序列化

    Property List 是对象图的简单结构化序列化,它仅使用以下类的对象:NSDictionaryNSArrayNSStringNSDataNSDateNSNumber。这些对象通常称为 property list objects。Cocoa 框架类提供了一些序列化这些属性列表对象的方法,并为记录对象内容及其层次关系的数据流定义了特殊格式。NSPropertyListSerialization类提供了将 property list 对象序列化为 XML 格式或优化的二进制格式的类方法。

Core Data

    Core Data 是一个 Cocoa 框架,它定义了用于管理对象图并使它们持久化的架构。在 Core Data 架构中,一个中心对象称为托管对象上下文管理应用程序中的各种模型对象对象图。托管对象上下文下方是该对象图的持久性堆栈——在模型对象和外部数据存储(例如 XML 文件或关系数据库)之间进行中介的框架对象的集合。持久性堆栈对象在存储中的数据和托管数据上下文中的相应对象之间进行映射,并且当有多个数据存储时,将它们作为单个聚合存储呈现给托管对象上下文。

备忘录模式的实现

    备忘录模式使用三个类 MementoOriginatorCareTaker

Memento 包含了要被恢复的对象的状态。

@interface Memento : NSObject

@property (nonatomic,strong,readonly) NSString *state;

- (instancetype)initWithState:(NSString *)state;

@end
@implementation Memento

- (instancetype)initWithState:(NSString *)state
{
    self = [super init];
    if (self) {
        _state = state;
    }
    return self;
}

@end

Originator 创建并在 Memento 对象中存储状态。

@interface Originator : NSObject

@property (nonatomic, strong) NSString *state;

@end
@implementation Originator

- (Memento *)saveStateToMemento{
    return [[Memento alloc] initWithState:_state];
}

- (void)getStateFromMemento:(Memento *)memento{
    _state = memento.state;
}

@end

Caretaker 对象负责从 Memento 中恢复对象的状态。

@interface CareTaker : NSObject

- (void)addMemento:(Memento *)memento;

- (Memento *)getMementoWithIndex:(int)index;


@end
@implementation CareTaker{
    NSMutableArray <Memento *> * _mementoList;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        _mementoList = [NSMutableArray array];
    }
    return self;
}

- (void)addMemento:(Memento *)memento{
    [_mementoList addObject:memento];
}

- (Memento *)getMementoWithIndex:(int)index{
    if (index < _mementoList.count) {
        return [_mementoList objectAtIndex:index];
    }
    return nil;
}

@end

总结

    很多时候我们总是需要记录一个对象的内部状态,可以通过一个备忘录类专门存储对象状态,以便在适当的时候恢复对象。保存程序的状态不需要什么特别奇妙的方法,任何简单有效的方法都可以,但是同时,保存信息应该只对原始程序有意义。原始程序应该是能够解码它所保存文档中的信息的唯一实体。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,919评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,567评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,316评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,294评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,318评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,245评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,120评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,964评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,376评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,592评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,764评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,460评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,070评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,697评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,846评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,819评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,665评论 2 354

推荐阅读更多精彩内容