標籤:
備忘錄模式:在不破壞封裝的前提下,捕獲一個對象的內部狀態,並在該對象之外儲存這個狀態。這樣以後就可將該對象恢複到原先儲存的狀態。
Originator(原發器):記錄當前時刻的內部狀態,負責定義哪些屬於需要備份的狀態,負責建立memento,負責從memento恢複狀態。
Memento(備忘錄):負責儲存Originator的內部狀態,在需要時提供給Originator內部狀態。
Caretaker(看管人):將Memento儲存在安全的地方,並負責提取。
一句話概括:Originator建立一個包含其狀態的Memento交給Caretaker保管,Caretaker不知如何與Memento互動,只負責把Memento在安全的地方儲存好。
Objective-C代碼實現:
Originator:
//// NimoOriginator.h// MementoDemo//// Created by Tony on 15/8/12.// Copyright (c) 2015年 NimoWorks. All rights reserved.////發起人:記錄當前時刻的內部狀態,負責定義哪些屬於備份範圍的狀態,負責建立和恢複備忘錄資料。#import <Foundation/Foundation.h>@class NimoMemento;@interface NimoOriginator : NSObject@property (nonatomic, copy) NSString* state;- (NimoMemento *)createMemento;- (void)restoreMemento:(NimoMemento *)memento;@end
//// NimoOriginator.m// MementoDemo//// Created by Tony on 15/8/12.// Copyright (c) 2015年 NimoWorks. All rights reserved.//#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:
//// NimoMemento.h// MementoDemo//// Created by Tony on 15/8/12.// Copyright (c) 2015年 NimoWorks. All rights reserved.//備忘錄:負責儲存發起人對象的內部狀態,在需要的時候提供發起人需要的內部狀態。#import <Foundation/Foundation.h>@interface NimoMemento : NSObject@property (nonatomic, copy, readonly) NSString *state;- (id)initWithState:(NSString *)state;@end
//// NimoMemento.m// MementoDemo//// Created by Tony on 15/8/12.// Copyright (c) 2015年 NimoWorks. All rights reserved.//#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:
//// NimoCaretaker.h// MementoDemo//// Created by Tony on 15/8/12.// Copyright (c) 2015年 NimoWorks. All rights reserved.//管理角色:對備忘錄進行管理,儲存和提供備忘錄。#import <Foundation/Foundation.h>@class NimoMemento;@interface NimoCaretaker : NSObject@property (nonatomic, assign) NimoMemento *memento;@end
//// NimoCaretaker.m// MementoDemo//// Created by Tony on 15/8/12.// Copyright (c) 2015年 NimoWorks. All rights reserved.//#import "NimoCaretaker.h"@implementation NimoCaretaker@end
Client:
//// main.m// MementoDemo//// Created by Tony on 15/8/12.// Copyright (c) 2015年 NimoWorks. All rights reserved.//#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;}
運行:
2015-08-12 20:27:39.184 MementoDemo[1160:34914] State:Old2015-08-12 20:27:39.186 MementoDemo[1160:34914] State:New2015-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//// Created by Tony on 15/8/13.// Copyright (c) 2015年 NimoWorks. All rights reserved.//#import "NimoMemento.h"@interface NimoMemento ()@property (nonatomic, copy, readwrite) NSString *state;- (id)initWithState:(NSString *)state;@end
如此,只在Originator與Menmento中#import NimoMemento+Private.h,便實現了介面的私人化。
iOS設計模式---備忘錄模式