首页 > 代码库 > 设计模式 - 备忘录

设计模式 - 备忘录

设计模式 - 备忘录

技术分享

备忘录模式很简单,就是存储对象,然后支持恢复对象到之前的某个状态,玩过游戏的,一定懂得存档一说,备忘录就是对对象的存档与管理。

效果:

技术分享

这个需要配合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

几个关键的地方:

技术分享

原理其实非常简单,就是将对象写文件,然后从文件从恢复出对象,但一定要有管理的功能,本例中并没有处理如何删除存档,其实存档可以做成堆栈或者队列模式,这个因需求而已,本处本人只是抛砖引玉,简单介绍下备忘录设计模式!

 

设计模式 - 备忘录