服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - 设计模式中的Memento备忘录模式的在iOS App开发中的运用

设计模式中的Memento备忘录模式的在iOS App开发中的运用

2021-01-12 15:36TonyGo IOS

这篇文章主要介绍了设计模式中的Memento备忘录模式的在iOS App开发中的运用,Memento着重于捕获和具体化当前对象的内部状态,需要的朋友可以参考下

备忘录模式。顾名思义,备忘录模式的初衷就是为了返回上一个状态而设计的。从名字看起来一目了然,好吧,还是老样子,先给出定义。

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

定义看起来搞的很专业,其实就是保存上一个状态,以便日后恢复用。好比是在玩游戏,在打大boss之前担心第一次打不过,先存个盘,万一玩儿完了,还可以恢复状态重新pk。

下面给出类结构图。

设计模式中的Memento备忘录模式的在iOS App开发中的运用

originator(原发器):记录当前时刻的内部状态,负责定义哪些属于需要备份的状态,负责创建memento,负责从memento恢复状态。

memento(备忘录):负责存储originator的内部状态,在需要时提供给originator内部状态。

caretaker(看管人):将memento保存在安全的地方,并负责提取。

一句话概括:originator创建一个包含其状态的memento交给caretaker保管,caretaker不知如何与memento交互,只负责把memento在安全的地方保存好。
从上面这张图来看,关系比较简单吧。那么备忘录模式一般都用在什么场合呢?

memento模式比较适用于功能比较复杂的,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时,originator可以根据保存的memento信息还原到前一状态。有时候一些对象的内部信息必须保存在对象以外的地方,但是必须要由对象自己读取,这时,使用备忘录可以把复杂的对象内部信息对其他的对象屏蔽起来。当然了,最大的作用还是在于当角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态进行复原。好啦,其实翻来覆去就是为了恢复数据用的,车轱辘话就不多说了,下面给大家简单展示一下实现的代码吧。

objective-c代码实现:

originator:

复制代码 代码如下:

//发起人:记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据。
 
#import <foundation/foundation.h>
@class nimomemento;
 
@interface nimooriginator : nsobject
 
@property (nonatomic, copy) nsstring* state;
 
- (nimomemento *)creatememento;
- (void)restorememento:(nimomemento *)memento;
 
@end

 

复制代码 代码如下:

#import "nimooriginator.h"
#import "nimomemento.h"
 
@implementation nimooriginator
 
- (nimomemento *)creatememento
{
    nimomemento *memento = [[nimomemento alloc] initwithstate:_state];
    return memento;
}
 
- (void)restorememento:(nimomemento *)memento
{
    _state = memento.state;
}
 
- (nsstring *)description
{
    return [nsstring stringwithformat:@"state:%@", _state];
}
 
@end


memento:

复制代码 代码如下:

//备忘录:负责存储发起人对象的内部状态,在需要的时候提供发起人需要的内部状态。
 
#import <foundation/foundation.h>
 
@interface nimomemento : nsobject
 
@property (nonatomic, copy, readonly) nsstring *state;
- (id)initwithstate:(nsstring *)state;
 
@end

 

复制代码 代码如下:

#import "nimomemento.h"
 
@interface nimomemento()
 
@property (nonatomic, copy, readwrite) nsstring *state;
 
 
@end

 

复制代码 代码如下:

 

@implementation nimomemento
 
- (id)initwithstate:(nsstring *)state
{
    if (self = [super init]) {
        _state = [state copy];
    }
    
    return self;
}
 
@end


caretaker:

复制代码 代码如下:

//管理角色:对备忘录进行管理,保存和提供备忘录。
 
#import <foundation/foundation.h>
@class nimomemento;
 
@interface nimocaretaker : nsobject
 
@property (nonatomic, assign) nimomemento *memento;
 
@end

 

复制代码 代码如下:


//
//  nimocaretaker.m
//  mementodemo
//

 

#import "nimocaretaker.h"
 
@implementation nimocaretaker
 
@end

 

复制代码 代码如下:

client:
 
#import <foundation/foundation.h>
#import "nimooriginator.h"
#import "nimomemento.h"
#import "nimocaretaker.h"
 
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        nimooriginator *originator = [[nimooriginator alloc] init];
        originator.state = @"old";
        nslog(@"%@", originator);
        nimomemento *memento = originator.creatememento;
        
        nimocaretaker *caretaker = [[nimocaretaker alloc] init];
        caretaker.memento = memento;
        originator.state = @"new";
        nslog(@"%@", originator);
        
        [originator restorememento:[caretaker memento]];
        nslog(@"%@", originator);
    }
    return 0;
}


运行:

 

?
1
2
3
2015-08-12 20:27:39.184 mementodemo[1160:34914] state:old
2015-08-12 20:27:39.186 mementodemo[1160:34914] state:new
2015-08-12 20:27:39.186 mementodemo[1160:34914] state:old

以上通用代码运行后虽然能得到期望的结果,但是并不完美,在menmento类的实现中,我们把state属性以及initwithstate初始化方法暴露在了公共接口中,这两者本应只提供给originator与menmento(即对originator与menmento提供宽接口,对caretaker等其他对象提供窄接口)。在c++等其他面向对象语言中,一般使用private或friend进行声明。但在objective-c中一切都是公有的,所以需要额外的技巧来实现。

通过类扩展将state属性以及initwithstate初始化方法从主接口头文件nimomemento.h中分离:

复制代码 代码如下:

//
//  nimomemento+private.h
//  mementodemo
//
 
#import "nimomemento.h"
 
@interface nimomemento ()
 
@property (nonatomic, copy, readwrite) nsstring *state;
- (id)initwithstate:(nsstring *)state;
 
@end


如此,只在originator与menmento中#import nimomemento+private.h,便实现了接口的私有化。

延伸 · 阅读

精彩推荐
  • IOSiOS布局渲染之UIView方法的调用时机详解

    iOS布局渲染之UIView方法的调用时机详解

    在你刚开始开发 iOS 应用时,最难避免或者是调试的就是和布局相关的问题,下面这篇文章主要给大家介绍了关于iOS布局渲染之UIView方法调用时机的相关资料...

    windtersharp7642021-05-04
  • IOSiOS通过逆向理解Block的内存模型

    iOS通过逆向理解Block的内存模型

    自从对 iOS 的逆向初窥门径后,我也经常通过它来分析一些比较大的应用,参考一下这些应用中某些功能的实现。这个探索的过程乐趣多多,不仅能满足自...

    Swiftyper12832021-03-03
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

    这篇文章主要介绍了iOS 雷达效果实例详解的相关资料,需要的朋友可以参考下...

    SimpleWorld11022021-01-28
  • IOS关于iOS自适应cell行高的那些事儿

    关于iOS自适应cell行高的那些事儿

    这篇文章主要给大家介绍了关于iOS自适应cell行高的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    daisy6092021-05-17
  • IOS解析iOS开发中的FirstResponder第一响应对象

    解析iOS开发中的FirstResponder第一响应对象

    这篇文章主要介绍了解析iOS开发中的FirstResponder第一响应对象,包括View的FirstResponder的释放问题,需要的朋友可以参考下...

    一片枫叶4662020-12-25
  • IOSIOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解

    这篇文章主要介绍了IOS开发之字典转字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握这样的方法,需要的朋友可以参考下...

    苦练内功5832021-04-01
  • IOSIOS 屏幕适配方案实现缩放window的示例代码

    IOS 屏幕适配方案实现缩放window的示例代码

    这篇文章主要介绍了IOS 屏幕适配方案实现缩放window的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    xiari5772021-06-01
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

    iOS中tableview 两级cell的展开与收回的示例代码

    本篇文章主要介绍了iOS中tableview 两级cell的展开与收回的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    J_Kang3862021-04-22