设计模式之14 - 命令模式Command

        Command是我们最常用的模式之一,主要用在 撤消/重做功能Undo | Redo,其中有代表的是二维/三维的图形操作,它为用户提供了必要的,可修改的操作接口,大大提高了软件的灵活性。Undo | Redo机制一般需要借助堆栈(或者队列,链表)等数据结构,通过记录每一步的操作来实现。

        图形操作一般是通过图元属性的更改完成(比如move),这种操作称为可逆操作,只需要记录改变之前的图元属性即可。而不规则图元的变化,可能 需要记录整体的描述信息无法用属性参数描述,称之为不可逆

        不扯闲篇,直接进主题。


一. 图元组织结构

        图元是描述对象的基本单位,可以抽象为对象属性的变化量,比如我们将图元的操作表述为 Create、Delete、Move、Rotate等。这些操作描述为统一的Graphics上层接口,即描述为命令Command),图元类组织如下:

        

        对于一个系统命令,根据不同的操作调用图元对象执行命令,然后进行操作的记录和处理:

•   New & Delete:

        为了对数据进行管理,我们需要增加一个id项,用于识别当前的数据对象

        添加删除标记位,删除时只是修改可见性(从Undo | Redo考虑),在Command真正出栈的时候才真正执行删除。

•   Modify操作:

        对于可逆操作需要通过记录参数确定,比如Move的(dx,dy)Rotate对应角度等,仅需要简单的记录其参数值就能够进行描述,对于旋转、平移等频繁的连续微操作需要考虑命令的合并

        对于非可逆操作,可以通过对象记录来完成,建立对象的MemList链表(限定步数的用数组即可),用来记录每一步的变化情况。

        

•   复制、剪切、粘贴:

        需要维护一个剪贴板,记录保存一组数据对象的信息即可。复制和剪切时,将数据信息写入,粘贴的时候读取,并执行相应的操作。


二. Command命令抽象

        Command类 封装了操作类型、操作对象列表、参数列表、标签等命令属性和Execute(),Unexecute(),Combine()等抽象方法。

        

        用户请求操作发生后,需要根据用户的操作生成命令,而区分命令种类的属性就是操作类型,操作类型分为new,delete和modify三种基本操作,基于三种基本操作的复合操作(multi-operate),以及系统操作(other)。
        我们通常要处理微操作的合并(比如鼠标拖动),以避免不必要的命令过多ShowTag标记下一步是否要进行合并操作
        

 三. Command管理

        Manager类是管理Command对象的核心类,是应用程序或者物体模型与Undo机制间的桥梁,其中:

        a)nMaxStep变量表示允许Undo | Redo的次数,nCount变量表示当前记录个数,nCurrent变量表示当前的Undo的位置(从0开始计数);

        b)函数Undo()和Redo()用于响应来自系统菜单,快捷键或者工具条的Undo和Redo命令;

        c)函数SetMaxStep()用于设置允许Undo | Redo的次数;

        d)Undo_Available和Redo_Available判断Undo | Redo操作是否有效;Undo操作执行当前CommandRecord的UnExecute()操作,Redo操作执行上面CommandRecord的Execute()操作。

        

       Manager类 维护一个CommandList(一般用dequeue实现),栈内元素是一个个的操作(命令),当命令满时,自动删除最下面的元素,因此操作所能恢复的步数不会超过设定的堆栈长度。

        

        Undo Redo过程除了要执行上面的堆栈操作以外,还需要执行以下命令:

a)查找当前命令所影响的图元链表(GraphList),如果是Undo命令,将链表中的每一个图元恢复到当前状态的上一状态。如果是Redo命令,恢复到当前的下一个状态,并把恢复后的状态结点标记为current。

b)如果用户点了保存或者在Undo后执行了新操作,那么系统将删除保存的堆栈命令以及这些命令对应的图元状态信息。

示例代码 可以从作者Github下载:https://github.com/linolzhang/Command

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值