您好,欢迎来到12图资源库!分享精神,快乐你我!我们只是素材的搬运工!!
  • 首 页
  • 当前位置:首页 > 开发 > WEB开发 >
    详解command设计形式,解耦操作和回滚
    时间:2020-10-16 21:17 来源:网络整理 作者:网络 浏览:收藏 挑错 推荐 打印

    明天我们引见的设计形式叫做命令形式(command),在这个形式下,我们可以完成do和undo的解耦,让运用方不用关心外部的完成细节。

    command形式

    这个形式我们在日常当中常常运用,举一个很复杂的例子,比如说我们发布代码。发布了之后发现不小心发布上去了一个bug,这个时分我们应该做什么?很复杂,就是回滚,把线上的代码回滚到这一次发布之前的代码。这样我们这次发布带来的改动就会被消弭,那么就避免了bug的产生。

    那么,关于一个发布系统来说,它需求做什么?其实也就是两个功用,一个是发布另外一个是回滚。这两个操作是相互可逆的,关于它的运用者来说,是不会关心它的外部是如何完成的,我们只需求在页面上按按钮就好了。

    我们来回忆一下这个进程,我们点击发布,可以把最新的代码发布上线。发布之后发现成绩,再点击回滚,系统再自动恢复到发布之前的形状。发布和回滚彼此是可逆的,当我们消弭掉bug之后,再次点击发布,又可以再次发布最新的代码了。

    command形式就是做的这个事情,也就是对do和undo的封装。我们来看一个很复杂的例子,对文件改名。比如说我们要把系统当中的文件改名,从A.txt改成B.txt。这个功用很复杂,系统为我们提供了现成的函数,叫做os.rename(),我们只需求把A和B两个文件的地址传入其中即可。

    假设我们发现改名字改错了,想回滚怎样办呢?会发现我们改动之前的名字曾经忘了,不知道怎样回滚了。这个时分就可以运用command形式,我们来看代码:

    import os 

     

    class MoveFileCommand: 

     

        def __init__(self, src, dest): 

            self.src = src 

            self.dest = dest 

     

        def execute(self): 

            self.rename(self.src, self.dest) 

     

        def undo(self): 

            self.rename(self.dest, self.src) 

     

        def rename(self, src, dest): 

            print('renaming from {} to {}'.format(src, dest)) 

            os.rename(src, dest) 

    在execute办法当中,我们把文件从src变成了dest,假设想要回滚,它又会再次调用rename。将文件名从dest回滚到src。这样的话,作为运用方就可以完全不用了解api外部的完成逻辑了,不然的话为了避免改错了的状况,还需求做很多适配。

    menu item

    有了command形式之后我们可以在外面在封装一层用来ui交互上,我们很常见的一种UI交互方式就是按钮。某一个按钮点一下之后会出现一个按过的标记,并且完成一个什么功用。再按一次标记消逝,功用也随之封锁。

    我随意找了一个例子,比如下图菜单当中的show minimap,show breadcrumbs这些都是这样的功用。点一下出现缩略图,再点一下缩略图消逝。

    详解command设计形式,解耦操作和回滚

    假设你写过UI页面的话,普通来说我们会先定义一个Menu Item的类,表示菜单当中的一切的item的基类。不同的选项表示不同的item,我们进一步剖析会发现有些item我们需求这样双击封锁的机制,而有些item是没有的。比如下面的Run、Output这些item都是点一次执行一次的。

    我们当然可以把下面引见的Command对象直接当做item,但是这样不利于整个菜单的一致,所以我们还会在外面包一层。比如一切MenuItem的父类应该是这样的:

    class MenuItemBaseClass: 

        def __init__(self): 

            pass 

         

        def pressed(self): 

            pass 

         

        def unpress(self): 

            pass 

    有了这个基类之后,我们就可以完成一个可回滚的类,将command的对象作为类成员变量,再在其中完成unpress办法:

    class RedoableMenu(MenuItemBaseClass): 

        def __init__(self, command): 

            self_command = command 

             

        def pressed(self): 

            self._command.execute() 

             

        def unpress(self): 

            self._command.undo() 

    (责任编辑:admin)