日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
詳解command設(shè)計模式,解耦操作和回滾

今天我們介紹的設(shè)計模式叫做命令模式(command),在這個模式下,我們可以實現(xiàn)do和undo的解耦,讓使用方不用關(guān)心內(nèi)部的實現(xiàn)細節(jié)。

成都創(chuàng)新互聯(lián)于2013年成立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元桃山做網(wǎng)站,已為上家服務(wù),為桃山各地企業(yè)和個人服務(wù),聯(lián)系電話:13518219792

command模式

這個模式我們在日常當(dāng)中經(jīng)常使用,舉一個很簡單的例子,比如說我們發(fā)布代碼。發(fā)布了之后發(fā)現(xiàn)不小心發(fā)布上去了一個bug,這個時候我們應(yīng)該做什么?很簡單,就是回滾,把線上的代碼回滾到這一次發(fā)布之前的代碼。這樣我們這次發(fā)布帶來的改動就會被消除,那么就避免了bug的產(chǎn)生。

那么,對于一個發(fā)布系統(tǒng)來說,它需要做什么?其實也就是兩個功能,一個是發(fā)布另外一個是回滾。這兩個操作是互相可逆的,對于它的使用者來說,是不會關(guān)心它的內(nèi)部是如何實現(xiàn)的,我們只需要在頁面上按按鈕就好了。

我們來回顧一下這個過程,我們點擊發(fā)布,可以把最新的代碼發(fā)布上線。發(fā)布之后發(fā)現(xiàn)問題,再點擊回滾,系統(tǒng)再自動恢復(fù)到發(fā)布之前的狀態(tài)。發(fā)布和回滾彼此是可逆的,當(dāng)我們消除掉bug之后,再次點擊發(fā)布,又可以再次發(fā)布最新的代碼了。

command模式就是做的這個事情,也就是對do和undo的封裝。我們來看一個很簡單的例子,對文件改名。比如說我們要把系統(tǒng)當(dāng)中的文件改名,從A.txt改成B.txt。這個功能很簡單,系統(tǒng)為我們提供了現(xiàn)成的函數(shù),叫做os.rename(),我們只需要把A和B兩個文件的地址傳入其中即可。

假如我們發(fā)現(xiàn)改名字改錯了,想回滾怎么辦呢?會發(fā)現(xiàn)我們改動之前的名字已經(jīng)忘了,不知道怎么回滾了。這個時候就可以使用command模式,我們來看代碼:

 
 
 
  1. import os 
  2.  
  3. class MoveFileCommand: 
  4.  
  5.     def __init__(self, src, dest): 
  6.         self.src = src 
  7.         self.dest = dest 
  8.  
  9.     def execute(self): 
  10.         self.rename(self.src, self.dest) 
  11.  
  12.     def undo(self): 
  13.         self.rename(self.dest, self.src) 
  14.  
  15.     def rename(self, src, dest): 
  16.         print('renaming from {} to {}'.format(src, dest)) 
  17.         os.rename(src, dest) 

在execute方法當(dāng)中,我們把文件從src變成了dest,如果想要回滾,它又會再次調(diào)用rename。將文件名從dest回滾到src。這樣的話,作為使用方就可以完全不用理解api內(nèi)部的實現(xiàn)邏輯了,不然的話為了防止改錯了的情況,還需要做很多適配。

menu item

有了command模式之后我們可以在外面在封裝一層用來ui交互上,我們很常見的一種UI交互方式就是按鈕。某一個按鈕點一下之后會出現(xiàn)一個按過的標(biāo)記,并且實現(xiàn)一個什么功能。再按一次標(biāo)記消失,功能也隨之關(guān)閉。

我隨便找了一個例子,比如下圖菜單當(dāng)中的show minimap,show breadcrumbs這些都是這樣的功能。點一下出現(xiàn)縮略圖,再點一下縮略圖消失。

如果你寫過UI頁面的話,一般來說我們會先定義一個Menu Item的類,表示菜單當(dāng)中的所有的item的基類。不同的選項表示不同的item,我們進一步分析會發(fā)現(xiàn)有些item我們需要這樣雙擊關(guān)閉的機制,而有些item是沒有的。比如上面的Run、Output這些item都是點一次執(zhí)行一次的。

我們當(dāng)然可以把上面介紹的Command對象直接當(dāng)做item,但是這樣不利于整個菜單的統(tǒng)一,所以我們還會在外面包一層。比如所有MenuItem的父類應(yīng)該是這樣的:

 
 
 
  1. class MenuItemBaseClass: 
  2.     def __init__(self): 
  3.         pass 
  4.      
  5.     def pressed(self): 
  6.         pass 
  7.      
  8.     def unpress(self): 
  9.         pass 

有了這個基類之后,我們就可以實現(xiàn)一個可回滾的類,將command的對象作為類成員變量,再在其中實現(xiàn)unpress方法:

 
 
 
  1. class RedoableMenu(MenuItemBaseClass): 
  2.     def __init__(self, command): 
  3.         self_command = command 
  4.          
  5.     def pressed(self): 
  6.         self._command.execute() 
  7.          
  8.     def unpress(self): 
  9.         self._command.undo() 

這樣我們的UI就和command解耦了,如果我們想要實現(xiàn)不同的可以回滾的功能, 只需要實現(xiàn)不同的command創(chuàng)建實例就可以了。對于整個UI的使用沒有任何影響,UI組件當(dāng)中用到的所有類都是統(tǒng)一的??赡茉赑ython這種弱類型語言當(dāng)中看不太出來,因為我們一個list說是menu基類的list,但是其實裝什么都行。但如果是強類型語言,那么這種抽象和封裝就是非常有必要的了。


分享題目:詳解command設(shè)計模式,解耦操作和回滾
URL地址:http://www.5511xx.com/article/ccdcehp.html