設計模式組合實戰--命令模式+模板方法模式的組合

我最近在作某一個開源產品的項目,項目組的開發方式是敏捷開發+TDD。 java

項目場景:開發一套開源的持續集成環境,集成SVN、Jira、Hudson/Jenkins、Git、Trac、Sonar等,這些平臺都是假設部署在Linux上,用java程序在各個平臺上實現「建立項目」、「建立用戶」、「分配角色權限」等功能。例如,經過編寫java程序,在trac上建立一個項目,分配這個用戶的某些權限 sql

我用測試先行的方式,先寫測試樣例,用最原始的方式爲每一個方法(createProject,createRole)編寫單元測試,這裏說一下,在部署了Trac的Linux服務器上建立項目或角色等,都是經過Linux安裝了Trac提供的命令實現功能,例如建立項目就是"trac-admin /usr/share/trac/projects/project1 initenv project1 sqlite:db/trac.db",建立角色並分配到某個默認權限的命令是"trac-admin /usr/share/trac/projects/project1 permission add role1 WIKI_ADMIN"。SVN也會有相似的實現方式,但其餘平臺可能未必是如此,多是經過服務器提供的接口來實現的。 設計模式

java鏈接Linux遠程執行命令是使用第三方的jar,叫作"com.trilead.ssh2",經過創建Connection做爲鏈接,用Session執行命令 服務器

在編寫了單元測試併成功實現功能後,發現其實這兩個功能的實現方式都是相同的,只是限於命令的不一樣而已(事實上,經過TDD測試先行,有些時候會爲開發實現帶來不少方便之處,這裏省略一萬字……),爲了讓功能最大重用,分離變化點,把全部的執行都當作命令實現類(例如Trac建立項目叫作TracCreateProjectCommand類,Trac建立角色叫作TracCreateRoleCommand,如此類推),各自實現一個Command接口,命令接口的執行經過一個叫作CommandExecutor的類來負責,這樣,一個有雛形的基於命令模式的設計模式初步呈現。 ssh

通過屢次代碼實現和對應的單元測試後,再對各個Command接口實現類進行進一步封裝,例如全部Trac相關的使用TracCommand抽象類執行操做,該類實現Command接口,同時做爲TracCreateProjectCommand和TracCreateRoleCommand類的父類,該父類用於做爲這兩個子類的模板,封裝了java遠程SSH2的實現,子類只須要實現對應的返回命令方法便可。 單元測試

通過如此的封裝後,從總體角度來看,外部調用CommandExecutor執行一條Command接口實現子類,執行對應的功能,此調用過程的設計理念是一個典型的命令模式。而命令實現類內部的模板實現方式,則是典型的模板方法模式 測試

最終的類圖結構以下 spa

相關文章
相關標籤/搜索