美文网首页
『ios』设计模式—备忘录模式

『ios』设计模式—备忘录模式

作者: butterflyer | 来源:发表于2021-08-18 20:19 被阅读0次

    这个模式的产生是用来解决一种场景,为了允许用户取消不确定或者错误的操作,能够恢复到他原先的状态,使得他有"后悔药"可吃。
    备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。
    看到这个场景我们可能想到的是,把用户的状态存下来。那么如何再不破坏封装性的前提下,设计一个备忘中心来统一的调度呢?

    那么接下来我们就需要来设计一个MementoCenter备忘中心。

    首先我们定义一个协议MementoCenterPotocol,里面包含了两个方法,一个是currentState的方法,一个是recoverFromState状态。

    @protocol MementoCenterPotocol <NSObject>
    
    - (id)currentState;
    
    - (void)recoverFromState:(id)state;
    
    @end
    

    再来设计单独的类,MementoCenter,包含saveMementoObject和mementoObjectWithKey的方法,这个类是用来存储和取出备忘状态的类。

    @implementation MementoCenter
    
    + (void)saveMementoObject:(id<MementoCenterPotocol>)object withKey:(NSString *)key {
        NSParameterAssert(object);
        NSParameterAssert(key);
        
        //获取data,通过potocol确定object的那些property需要存储
        id data = [object currentState];
        NSData *tmpData = [FastCoder dataWithRootObject:data];
        
        //存储data
        if (tmpData) {
            [[NSUserDefaults standardUserDefaults] setObject:tmpData forKey:key];
        }
    }
    
    + (id)mementoObjectWithKey:(NSString *)key {
        NSParameterAssert(key);
        
        id data = nil;
        NSData *tmpData = [[NSUserDefaults standardUserDefaults] objectForKey:key];
        
        if (tmpData) {
            data = [FastCoder objectWithData:tmpData];
        }
        return data;
    }
    
    @end
    
    

    然后我们需要给nsobject加一个分类,目的是为了给所有的nsobject对象都添加这个备忘的功能,需要保证
    所有的调用的这两个方法的对象都遵循了MementoCenterPotocol的协议。

    @implementation NSObject (MementoCenter)
    
    - (void)saveStateWithKey:(NSString *)key {
        NSParameterAssert(key);
        
        id <MementoCenterPotocol> obj = (id <MementoCenterPotocol>)self;
        if ([obj respondsToSelector:@selector(currentState)]) {
            [MementoCenter saveMementoObject:obj withKey:key];
        }
    }
    
    - (void)recoverFromStateWithKey:(NSString *)key {
        NSParameterAssert(key);
        
        id <MementoCenterPotocol> obj = (id <MementoCenterPotocol>)self;
        if ([obj respondsToSelector:@selector(recoverFromStateWithKey:)]) {
            id state = [MementoCenter mementoObjectWithKey:key];
            if (state) {
                [obj recoverFromState:state];
            }
        }
    }
    
    @end
    
    

    最后一步就是来使用他了。我们来对一个view进行备忘和恢复操作,设计一个view,并且遵守MementoCenterPotocol

    @interface DemoView : UIView <MementoCenterPotocol>
    
    @end
    @implementation CustomView
    
    //返回demoView的frame
    - (id)currentState {
        return @{@"frame" : NSStringFromCGRect(self.frame)};
    }
    //恢复CustomView的frame
    - (void)recoverFromState:(id)state {
        NSDictionary *data = state;
        [UIView animateWithDuration:3.f animations:^{
            
            self.frame = CGRectFromString(data[@"frame"]);
        }];
    }
    @end
    
    

    使用,先存储当前状态,再恢复状态。

    - (void)test1 {
        _demoView.frame     = CGRectMake(100, 100, 100, 100);
        [_demoView saveStateWithKey:@"demoView"];
        NSLog(@"%@", _demoView);
    }
    
    - (void)test2 {
        //注意log
        NSLog(@"%@", _demoView);
        NSLog(@"*******************");
        [_demoView recoverFromStateWithKey:@"demoView"];
        NSLog(@"%@", _demoView);
    }
    

    相关文章

      网友评论

          本文标题:『ios』设计模式—备忘录模式

          本文链接:https://www.haomeiwen.com/subject/bmhnbltx.html