首页 > 代码库 > 设计模式 - 备忘录
设计模式 - 备忘录
设计模式 - 备忘录
备忘录模式很简单,就是存储对象,然后支持恢复对象到之前的某个状态,玩过游戏的,一定懂得存档一说,备忘录就是对对象的存档与管理。
效果:
这个需要配合FastCoder使用,请自行到Github上去搜索源码FastCoder源码^_^!
源码:
Model.h 与 Model.m
//// Model.h// MementoPattern//// Created by YouXianMing on 15/1/3.// Copyright (c) 2015年 YouXianMing. All rights reserved.//#import <Foundation/Foundation.h>@interface Model : NSObject@property (nonatomic, strong) NSString *name;@property (nonatomic, strong) NSString *age;/** * 初始化方法 * * @param key 用来标示对象唯一性 * * @return 对象 */- (instancetype)initWithKey:(NSString *)key;/** * 从某个状态恢复 * * @param slot 状态槽位(第几个存档位置) * @param key 标示字符串(保证存档唯一) * * @return 存档的对象,如果对象不存在,则重新创建 */+ (id)recoverFromSlot:(NSInteger)slot key:(NSString *)key;/** * 存储到slot当中(按照数组的顺序) */- (void)store;@end
//// Model.m// MementoPattern//// Created by YouXianMing on 15/1/3.// Copyright (c) 2015年 YouXianMing. All rights reserved.//#import "Model.h"#import "FastCoder.h"#import "NSString+File.h"@interface Model ()@property (nonatomic, strong) NSString *key;@property (nonatomic, strong) NSMutableArray *slotInfoArray;@end@implementation Model- (instancetype)init{ self = [super init]; if (self) { self.key = @"Default"; } return self;}- (instancetype)initWithKey:(NSString *)key { Model *model = [Model new]; model.key = key; return model;}+ (id)recoverFromSlot:(NSInteger)slot key:(NSString *)key { if (key == nil) { key = @"Default"; } NSString *arrayPath = [[@"/Documents" path] stringByAppendingString:[NSString stringWithFormat:@"/%@_array", key]]; NSString *objectPath = [[@"/Documents" path] stringByAppendingString:[NSString stringWithFormat:@"/%@_%ld", key, (long)slot]]; id object = nil; NSArray *array = [FastCoder objectWithData:[self dataWithPath:arrayPath]]; if (array.count > slot && slot >= 0) { object = [FastCoder objectWithData:[self dataWithPath:objectPath]]; } return object;}- (void)store { if (self == nil) { return; } self.slotInfoArray = [FastCoder objectWithData:[self dataWithPath:[self arrayPath]]]; if (self.slotInfoArray.count == 0) { [[FastCoder dataWithRootObject:self] writeToFile:[self filePathAtSlot:0] atomically:YES]; self.slotInfoArray = [NSMutableArray array]; [self.slotInfoArray addObject:@""]; [[FastCoder dataWithRootObject:self.slotInfoArray] writeToFile:[self arrayPath] atomically:YES]; } else { [[FastCoder dataWithRootObject:self] writeToFile:[self filePathAtSlot:self.slotInfoArray.count] atomically:YES]; [self.slotInfoArray addObject:@""]; [[FastCoder dataWithRootObject:self.slotInfoArray] writeToFile:[self arrayPath] atomically:YES]; } NSLog(@"store sucess!");}#pragma mark - private method- (NSString *)filePathAtSlot:(NSInteger)slot { NSString *path = [[@"/Documents" path] stringByAppendingString:[NSString stringWithFormat:@"/%@_%ld", self.key, (long)slot]]; return path;}- (NSString *)arrayPath { NSString *path = [[@"/Documents" path] stringByAppendingString:[NSString stringWithFormat:@"/%@_array", self.key]]; return path;}- (NSData *)dataWithPath:(NSString *)path { return [NSData dataWithContentsOfFile:path];}+ (NSData *)dataWithPath:(NSString *)path { return [NSData dataWithContentsOfFile:path];}@end
NSString+File.h 与 NSString+File.m
//// NSString+File.h// Category//// Created by YouXianMing on 14-8-29.// Copyright (c) 2014年 YouXianMing. All rights reserved.//#import <Foundation/Foundation.h>@interface NSString (File)// 沙盒路径- (NSString *)path;/* /Documents /Library/Caches /Library/Preferences /tmp */// bundle文件- (NSString *)bundleFile;// 检测文件或者文件夹是否存在- (BOOL)exist;// 创建文件夹- (BOOL)createFolder;// 是否是文件夹- (BOOL)isDirectory;// 复制到这个路径- (BOOL)copyTo:(NSString *)path;// 移动到这个路径- (BOOL)moveTo:(NSString *)path;// 删除文件- (BOOL)remove;// 遍历出文件夹中的文件- (NSArray *)enumeratorFolder;// 遍历出文件夹并在block中查看- (void)enumeratorFolderEach:(void (^)(NSString *path))block;// 文件信息- (NSDictionary *)fileInfo;// 文件大小- (int)fileSize;@end
//// NSString+File.m// Category//// Created by YouXianMing on 14-8-29.// Copyright (c) 2014年 YouXianMing. All rights reserved.//#import "NSString+File.h"@implementation NSString (File)- (NSString *)path{ return [NSHomeDirectory() stringByAppendingPathComponent:self];}- (NSString *)bundleFile{ return [[NSBundle mainBundle] pathForResource:self ofType:nil];}- (BOOL)exist{ return [[NSFileManager defaultManager] fileExistsAtPath:[NSHomeDirectory() stringByAppendingPathComponent:self] isDirectory:NO];}- (BOOL)createFolder{ return [[NSFileManager defaultManager] createDirectoryAtPath:[NSHomeDirectory() stringByAppendingPathComponent:self] withIntermediateDirectories:YES attributes:nil error:nil];}- (BOOL)isDirectory{ BOOL isDirectory = NO; [[NSFileManager defaultManager] fileExistsAtPath:[NSHomeDirectory() stringByAppendingPathComponent:self] isDirectory:&isDirectory]; return isDirectory;}- (BOOL)copyTo:(NSString *)path{ return [[NSFileManager defaultManager] copyItemAtPath:[NSHomeDirectory() stringByAppendingPathComponent:self] toPath:[NSHomeDirectory() stringByAppendingPathComponent:path] error:nil];}- (BOOL)moveTo:(NSString *)path{ return [[NSFileManager defaultManager] moveItemAtPath:[NSHomeDirectory() stringByAppendingPathComponent:self] toPath:[NSHomeDirectory() stringByAppendingPathComponent:path] error:nil];}- (BOOL)remove{ return [[NSFileManager defaultManager] removeItemAtPath:[NSHomeDirectory() stringByAppendingPathComponent:self] error:nil];}- (NSArray *)enumeratorFolder{ if ([self isDirectory]) { NSMutableArray *storeArray = [NSMutableArray array]; NSString *docsDir = [NSHomeDirectory() stringByAppendingPathComponent:self]; NSFileManager *localFileManager = [[NSFileManager alloc] init]; NSDirectoryEnumerator *dirEnum = [localFileManager enumeratorAtPath:docsDir]; NSString *file; while ((file = [dirEnum nextObject])) { [storeArray addObject:[[NSHomeDirectory() stringByAppendingPathComponent:self] stringByAppendingPathComponent:file]]; } return storeArray; } else { return nil; }}- (void)enumeratorFolderEach:(void (^)(NSString *path))block{ if ([self isDirectory]) { NSMutableArray *storeArray = [NSMutableArray array]; NSString *docsDir = [NSHomeDirectory() stringByAppendingPathComponent:self]; NSFileManager *localFileManager = [[NSFileManager alloc] init]; NSDirectoryEnumerator *dirEnum = [localFileManager enumeratorAtPath:docsDir]; NSString *file; while ((file = [dirEnum nextObject])) { [storeArray addObject:[self stringByAppendingPathComponent:file]]; } [storeArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { block(obj); }]; }}- (NSDictionary *)fileInfo{ return [[NSFileManager defaultManager] attributesOfItemAtPath:[NSHomeDirectory() stringByAppendingPathComponent:self] error:nil];}- (int)fileSize{ return [[[[NSFileManager defaultManager] attributesOfItemAtPath:[NSHomeDirectory() stringByAppendingPathComponent:self] error:nil] objectForKey:@"NSFileSize"] intValue];}@end
控制器源码:
//// ViewController.m// MementoPattern//// Created by YouXianMing on 15/1/3.// Copyright (c) 2015年 YouXianMing. All rights reserved.//#import "ViewController.h"#import "NSString+File.h"#import "Model.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; Model *model_01 = [Model new]; model_01.name = @"YouXianMing"; model_01.age = @"27"; [model_01 store]; // 存快照 Model *model_02 = [Model new]; model_02.name = @"QiuLiang"; model_02.age = @"28"; [model_02 store]; // 存快照 Model *model_03 = [Model new]; model_03.name = @"XiaoMing"; model_03.age = @"100"; [model_03 store]; // 存快照// Model *test_model_01 = [Model recoverFromSlot:0 key:nil];// NSLog(@"%@ %@", test_model_01.name, test_model_01.age);// // Model *test_model_02 = [Model recoverFromSlot:1 key:nil];// NSLog(@"%@ %@", test_model_02.name, test_model_02.age);// // Model *test_model_03 = [Model recoverFromSlot:2 key:nil];// NSLog(@"%@ %@", test_model_03.name, test_model_03.age);}@end
几个关键的地方:
原理其实非常简单,就是将对象写文件,然后从文件从恢复出对象,但一定要有管理的功能,本例中并没有处理如何删除存档,其实存档可以做成堆栈或者队列模式,这个因需求而已,本处本人只是抛砖引玉,简单介绍下备忘录设计模式!
设计模式 - 备忘录
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。