美文网首页
英雄联盟中的设计模式-命令模式

英雄联盟中的设计模式-命令模式

作者: 莮亾 | 来源:发表于2017-02-16 20:30 被阅读34次

    将“请求”封装成对象,以便使用不同的请求、队列、或者日志来参数化其他对象。命令模式也支持可撤销的操作。

    每一位召唤师都有QWER4个技能,当我们按下键盘上(或其他外设)的Q按钮后,我们操控的召唤师就会释放Q技能进行攻击。整个过程可以使用命令模式来描述。命令模式可以将请求者与接收者之间解耦。

    命令模式是在特定接收者上绑定一组动作来封装成一个请求(命令对象),而这个请求只暴露出一个execute方法,当此方法被调用的时候,接收者就会负责进行这些动作。而对于外面来看,其他对象不知道究竟是哪个接收者进行了哪些动作,只知道如果调用了execute方法,请求的目的就能达到。

    命令模式还能实现撤销操作,也比较简单,只需让接收者实现命令的相反操作即可。

    1. 简单的命令模式
    @protocol Command <NSObject>
    - (void)execute;    // 执行命令
    - (void)undo;       // 撤销命令
    @end
    
    @implementation Skill_Q {
        Summoner *_summoner;
    }
    - (instancetype)initWithSummoner:(Summoner *)summoner {
        self = [super init];
        if (self) {
            _summoner = summoner;
        }
        return self;
    }
    - (void)execute {
       [_summoner touchSkillWithNumber:@"Q"];
    }
    - (void)undo {
        [_summoner cancelSkillWithNumber:@"Q"];
    }
    @end
    
    外设类图
    @interface OuterDevice : NSObject
    @property (nonatomic, strong, readonly) NSMutableDictionary *commandMap;
    - (void)buttonAddCommand:(id<Command>)command number:(NSString *)number;//给外设按钮增加命令
    - (void)pressedButtonWithNumber:(NSString *)number;//按下按钮
    - (void)undoPressedButtonWithNumber:(NSString *)number;//撤销按下按钮操作
    @end
    
    @implementation OuterDevice
    
    - (instancetype)init {
        self = [super init];
        if (self) {
            _commandMap = [[NSMutableDictionary alloc] init];
        }
        return self;
    }
    
    - (void)buttonAddCommand:(id<Command>)command number:(NSString *)number {
        [_commandMap setObject:command forKey:number];
    }
    - (void)pressedButtonWithNumber:(NSString *)number {
        id<Command> command = [_commandMap objectForKey:number];
        [command execute];
    }
    - (void)undoPressedButtonWithNumber:(NSString *)number {
        id<Command> command = [_commandMap objectForKey:number];
        [command undo];
    }
    @end
    

    可能你觉得接收者不一定要存在,可以让命令对象直接实现execute方法。但是,这样的做法使得调用者与接收者之间的耦合程度增加,而且还不能将接收者当作参数传递给命令。所以,还是将命令对象设计的简单、傻瓜点更合适。
    具体代码传送门

    2. 队列请求

    命令模式可以将一个接收者和一组动作打包,供不同的线程调用,我们可以利用这个特性来创建队列请求操作。比如在队列的一端添加各式各样的命令对象,而线程从队列的另一端中取出命令对象,调用其execute方法便能完成相关任务。线程不必知道具体的命令是什么,这样就达到了解耦。

    3. 日志

    我们还可以利用命令模式将用户的动作记录到日志中,通过序列化把命令对象存储到磁盘中,一旦系统死机,重启后我们就可以将命令对象重新加载并执行,这样就使系统恢复到了上一次死机前的那一刻。

    倾情告白:为交互对象之间的松耦合设计而努力!

    关注微信公众号CodingArtist,可以第一时间得到文章更新通知! _

    相关文章

      网友评论

          本文标题:英雄联盟中的设计模式-命令模式

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