設(shè)計(jì)模式中的Memento備忘錄模式的在iOS App開(kāi)發(fā)中的運(yùn)用
備忘錄模式。顧名思義,備忘錄模式的初衷就是為了返回上一個(gè)狀態(tài)而設(shè)計(jì)的。從名字看起來(lái)一目了然,好吧,還是老樣子,先給出定義。
備忘錄(Memento):在不破壞封裝性的前提下,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài),并在該對(duì)象之外保存這個(gè)狀態(tài)。這樣以后就可將該對(duì)象恢復(fù)到原先保存的狀態(tài)。
定義看起來(lái)搞的很專業(yè),其實(shí)就是保存上一個(gè)狀態(tài),以便日后恢復(fù)用。好比是在玩游戲,在打大Boss之前擔(dān)心第一次打不過(guò),先存?zhèn)€盤(pán),萬(wàn)一玩兒完了,還可以恢復(fù)狀態(tài)重新PK。
下面給出類結(jié)構(gòu)圖。

Originator(原發(fā)器):記錄當(dāng)前時(shí)刻的內(nèi)部狀態(tài),負(fù)責(zé)定義哪些屬于需要備份的狀態(tài),負(fù)責(zé)創(chuàng)建memento,負(fù)責(zé)從memento恢復(fù)狀態(tài)。
Memento(備忘錄):負(fù)責(zé)存儲(chǔ)Originator的內(nèi)部狀態(tài),在需要時(shí)提供給Originator內(nèi)部狀態(tài)。
Caretaker(看管人):將Memento保存在安全的地方,并負(fù)責(zé)提取。
一句話概括:Originator創(chuàng)建一個(gè)包含其狀態(tài)的Memento交給Caretaker保管,Caretaker不知如何與Memento交互,只負(fù)責(zé)把Memento在安全的地方保存好。
從上面這張圖來(lái)看,關(guān)系比較簡(jiǎn)單吧。那么備忘錄模式一般都用在什么場(chǎng)合呢?
Memento模式比較適用于功能比較復(fù)雜的,但需要維護(hù)或記錄屬性歷史的類,或者需要保存的屬性只是眾多屬性中的一小部分時(shí),Originator可以根據(jù)保存的Memento信息還原到前一狀態(tài)。有時(shí)候一些對(duì)象的內(nèi)部信息必須保存在對(duì)象以外的地方,但是必須要由對(duì)象自己讀取,這時(shí),使用備忘錄可以把復(fù)雜的對(duì)象內(nèi)部信息對(duì)其他的對(duì)象屏蔽起來(lái)。當(dāng)然了,最大的作用還是在于當(dāng)角色的狀態(tài)改變的時(shí)候,有可能這個(gè)狀態(tài)無(wú)效,這時(shí)候就可以使用暫時(shí)存儲(chǔ)起來(lái)的備忘錄將狀態(tài)進(jìn)行復(fù)原。好啦,其實(shí)翻來(lái)覆去就是為了恢復(fù)數(shù)據(jù)用的,車(chē)轱轆話就不多說(shuō)了,下面給大家簡(jiǎn)單展示一下實(shí)現(xiàn)的代碼吧。
Objective-C代碼實(shí)現(xiàn):
Originator:
//發(fā)起人:記錄當(dāng)前時(shí)刻的內(nèi)部狀態(tài),負(fù)責(zé)定義哪些屬于備份范圍的狀態(tài),負(fù)責(zé)創(chuàng)建和恢復(fù)備忘錄數(shù)據(jù)。
#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:
//備忘錄:負(fù)責(zé)存儲(chǔ)發(fā)起人對(duì)象的內(nèi)部狀態(tài),在需要的時(shí)候提供發(fā)起人需要的內(nèi)部狀態(tài)。
#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:
//管理角色:對(duì)備忘錄進(jìn)行管理,保存和提供備忘錄。
#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;
}
運(yùn)行:
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
以上通用代碼運(yùn)行后雖然能得到期望的結(jié)果,但是并不完美,在Menmento類的實(shí)現(xiàn)中,我們把state屬性以及initWithState初始化方法暴露在了公共接口中,這兩者本應(yīng)只提供給Originator與Menmento(即對(duì)Originator與Menmento提供寬接口,對(duì)Caretaker等其他對(duì)象提供窄接口)。在C++等其他面向?qū)ο笳Z(yǔ)言中,一般使用private或friend進(jìn)行聲明。但在Objective-C中一切都是公有的,所以需要額外的技巧來(lái)實(shí)現(xiàn)。
通過(guò)類擴(kuò)展將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,便實(shí)現(xiàn)了接口的私有化。
- 實(shí)例解析設(shè)計(jì)模式中的外觀模式在iOS App開(kāi)發(fā)中的運(yùn)用
- 設(shè)計(jì)模式開(kāi)發(fā)中的備忘錄模式在iOS應(yīng)用開(kāi)發(fā)中的運(yùn)用實(shí)例
- 深入解析設(shè)計(jì)模式中的裝飾器模式在iOS應(yīng)用開(kāi)發(fā)中的實(shí)現(xiàn)
- iOS應(yīng)用運(yùn)用設(shè)計(jì)模式中的Strategy策略模式的開(kāi)發(fā)實(shí)例
- iOS App設(shè)計(jì)模式開(kāi)發(fā)中策略模式的實(shí)現(xiàn)示例
- 舉例講解iOS應(yīng)用開(kāi)發(fā)中對(duì)設(shè)計(jì)模式中的策略模式的使用
- iOS App使用設(shè)計(jì)模式中的模板方法模式開(kāi)發(fā)的示例
- iOS應(yīng)用設(shè)計(jì)模式開(kāi)發(fā)中對(duì)簡(jiǎn)單工廠和工廠方法模式的運(yùn)用
- 實(shí)例講解iOS應(yīng)用的設(shè)計(jì)模式開(kāi)發(fā)中的Visitor訪問(wèn)者模式
- 詳解iOS應(yīng)用開(kāi)發(fā)中使用設(shè)計(jì)模式中的抽象工廠模式
相關(guān)文章
SIGPIPE(Signal?13,?Code?0)?異常排查及處理
這篇文章主要為大家介紹了SIGPIPE(Signal?13,?Code?0)?異常排查原因解析及處理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
swift3.0網(wǎng)絡(luò)圖片緩存原理簡(jiǎn)析
這篇文章主要為大家簡(jiǎn)析了swift3.0網(wǎng)絡(luò)圖片緩存原理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09
淺談WKWebView 在64位設(shè)備上的白屏問(wèn)題
下面小編就為大家?guī)?lái)一篇淺談WKWebView 在64位設(shè)備上的白屏問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04
iOS?StoreKit?2?新特性盤(pán)點(diǎn)解析
這篇文章主要為大家介紹了iOS?StoreKit?2?新特性盤(pán)點(diǎn)及要點(diǎn)解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
IOS開(kāi)發(fā)代碼分享之用nstimer實(shí)現(xiàn)倒計(jì)時(shí)功能
在制作IOS項(xiàng)目中,我們經(jīng)常要用到倒計(jì)時(shí)功能,今天就分享下使用nstimer實(shí)現(xiàn)的倒計(jì)時(shí)功能的代碼,希望對(duì)大家能有所幫助2014-09-09
iOS開(kāi)發(fā)之UITableView左滑刪除等自定義功能
今天來(lái)給大家介紹下iOS開(kāi)發(fā)中UITableView左滑實(shí)現(xiàn)微信中置頂,刪除等功能。對(duì)大家開(kāi)發(fā)iOS具有一定的參考借鑒價(jià)值,有需要的朋友們一起來(lái)看看吧。2016-09-09
iOS應(yīng)用開(kāi)發(fā)中實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)的簡(jiǎn)單方法筆記
這篇文章主要介紹了iOS應(yīng)用開(kāi)發(fā)中實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)的簡(jiǎn)單方法筆記,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下2016-02-02

