• iOS设计模式之备忘录模式


    备忘录模式

    基本理解

    • 这个模式有三个关键角色:原发器(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不行用自己的新名字和地址了,所有就通过备忘录来还原自己的姓名和地址。

    附:

  • 相关阅读:
    PowerDesigner生成sql及说明文档
    Visual Studio 2005 Team System & UML
    检查数据库数据字段命名规范与合法性的脚本
    常用的快速Web原型图设计工具
    用户需求说明书模板
    数据库设计说明书
    Visual SourceSafe 命名约定和限制
    需求管理工具DOORS介绍
    C#编码命名规则
    数据库对象命名规范
  • 原文地址:https://www.cnblogs.com/zhanggui/p/4712560.html
Copyright © 2020-2023  润新知