敏捷軟體開發(3)---COMMAND 模式 & Active Object 模式

来源:http://www.cnblogs.com/deman/archive/2016/06/03/5553538.html
-Advertisement-
Play Games

COMMAND 模式 command模式非常簡單,簡單到你無法想象的地方。 這就是一個command模式的樣子。也許你會覺得,這有點多此一舉嗎。但是當你使用他的時候,command模式就會閃現光華。 這樣一個場景:經理張三叫leader王二去開發一個項目, 王二就安排李四 去開發這個功能A。 李四何 ...


COMMAND 模式

command模式非常簡單,簡單到你無法想象的地方。

public interface Command {
    void execute();
}

這就是一個command模式的樣子。也許你會覺得,這有點多此一舉嗎。但是當你使用他的時候,command模式就會閃現光華。

這樣一個場景:經理張三叫leader王二去開發一個項目, 王二就安排李四 去開發這個功能A。 李四何時執行,怎麼執行就是他自己的事情了。


 UML圖如上所示: 代碼如下:
public interface CommandInterface {
    void execute();
}
public class ContractCommand implements CommandInterface {
    Member member;

    public ContractCommand(Member member) {
        this.member = member;
    }

    @Override
    public void execute() {
        member.action();
    }
}
public class Member {
    public void action()
    {
        TraceLog.i();
    }
}

Leader,獲取命令,然後執行命令。

public class Leader {
    CommandInterface commandInterface;


    public void setCommandInterface(CommandInterface commandInterface) {
        this.commandInterface = commandInterface;
    }

    public void executeCommand()
    {
        commandInterface.execute();
    }
}
public class Manager {
    public static void main()
    {
        Member m = new Member();
        CommandInterface c = new ContractCommand(m);
        Leader wang2 = new Leader();

        wang2.setCommandInterface(c);
        wang2.executeCommand();
    }
}

manager創建運行的平臺。

這樣命令模式就開啟了。

Active Object

Active Object 模式

一開始蠻難理解這個模式的目的,而且GOF的23中經典模式里也沒有這個模式。

/**
 * @author deman.lu
 * @version on 2016-06-02 14:45
 */
public class ActiveObjectEngine {
    List<CommandInterface> itsCommands = new ArrayList();

    /*need to running in main thread, should check with synchronized*/
    public void addCommand(CommandInterface aCommand)
    {
        itsCommands.add(aCommand);
    }

    public void run()
    {
        /*should running in background*/
        while (itsCommands.size() > 0)
        {
            CommandInterface c = itsCommands.get(0);
            itsCommands.remove(0);
            c.execute();
        }
    }
}

這個就是ActiveObject的engine,2個函數。一個是把一條command添加到表裡面。

另一個是一個迴圈,處理問題。仔細思考,這就是消費者,和生產者問題的變種。

but這裡沒有線程block的地方。先看完全部代碼:

public class SleepCommand implements CommandInterface {
    @Override
    public void execute() {
        Date currentTime = new Date();
        if (!started) {
            started = true;
            this.startTime = currentTime;
            this.engine.addCommand(this);
        } else {
            long elapsedTime = currentTime.getTime() - startTime.getTime();
            if (elapsedTime < SleepTime) {
                this.engine.addCommand(this);
            } else {
                this.engine.addCommand(this.wakeupCommand);
            }
        }
    }

    private CommandInterface wakeupCommand = null;
    private ActiveObjectEngine engine = null;
    private long SleepTime = 0;
    private Date startTime;
    private boolean started = false;

    public SleepCommand(long milliSeconds, ActiveObjectEngine e,
                        CommandInterface wakeupCommand) {
        this.SleepTime = milliSeconds;
        this.engine = e;
        this.wakeupCommand = wakeupCommand;
    }

}
public class DelayedTyper implements CommandInterface {
    private long itsDelay;
    private char itsChar;
    private static boolean stop = false;
    static String printStr = "";
    private static ActiveObjectEngine engin =
            new ActiveObjectEngine();

    static class StopCommand implements CommandInterface
    {
        @Override
        public void execute() {
            DelayedTyper.stop = true;
        }
    }

    public static void Main()
    {
        engin.addCommand(new DelayedTyper(100, 'A'));
        engin.addCommand(new DelayedTyper(300, 'B'));
        engin.addCommand(new DelayedTyper(500, 'C'));
        engin.addCommand(new DelayedTyper(700, 'D'));

        CommandInterface stopCommand = new StopCommand();
        engin.addCommand(new SleepCommand(2000, engin, stopCommand));
        engin.run();
        TraceLog.i(printStr);
    }

    public DelayedTyper(long delay, char c)
    {
        this.itsDelay = delay;
        this.itsChar = c;
    }

    @Override
    public void execute()
    {
        printStr +=itsChar;
        if (!stop)
        {
            DelayAndRepeat();
        }
    }

    private void DelayAndRepeat()
    {
        engin.addCommand(new SleepCommand(itsDelay, engin, this));
    }
}

結果如下:

ABCDAAABACABAADAABCAAABAADABCAAABAACDB

當DelayedTyper沒有到執行的時間點的時候,啟動SleepCommand。

這個很關鍵,

            if (elapsedTime < SleepTime) {
                this.engine.addCommand(this);
            } else {
                this.engine.addCommand(this.wakeupCommand);
            }

如果時間沒到,就把自己加入到隊列最後,等待下次執行。(此處沒有用常見的線程block技術)

時間到了,就把wakeupCommand加入執行隊列。

這裡還有個關鍵是,沒有stopcommand,命令會一直迴圈執行。

參考:

《敏捷軟體開發》 Robert C. Martin 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、編輯器簡介 寫這個控制項之前總想找一找開源的,可以偷下懶省點事。可是各種地方都搜遍了也沒有找到。 於是,那就做第一個吃螃蟹的人吧! 控制項主要有三個功能:塗鴉、裁剪、合成。 塗鴉:主要是用到了InkToolbar和InkCanvas。 裁剪:這個用到的比較複雜,源碼會公佈出來。 合成:將塗鴉圖層按比 ...
  • 1.設置WinForm窗體屬性showinTask=false 2.加notifyicon控制項notifyIcon1,為控制項notifyIcon1的屬性Icon添加一個icon圖標。 3.添加窗體最小化事件(首先需要添加事件引用): 4.添加點擊圖標事件(首先需要添加事件引用): private v ...
  • 模型驗證(Model Validation):是確保用戶接收的數據適合於綁定的模型,並且在不合適時,給用戶提供有用的信息,以幫助他們修正其問題的過程。 模型驗證過程一:檢查接收的數據——是保持域模型完整性的方式之一。 模型驗證過程二:幫助用戶修正問題。 示例項目介紹 項目模板:Basic 項目名稱: ...
  • ApiView是.net api的介面文檔查看網站,用於解決分散式開發過程中的Api介面管理和溝通問題。 自動生成api文檔; 方便調試及第三方開發人員對接,可以應用在asp.net mvc,wcf,webservice 中使用; 代碼及原理都很簡單,方便修改和完善。 ...
  • 在傳統的Spring MVC開發方法中,必須在Bean配置文件中為每個控制器類配置實例和請求映射和讓每個控制器類去實現或者擴展特定於框架的介面或者基類,不夠靈活。 如果Spring MVC可以自動偵測你的控制器類和請求映射,就能減少配置所需要的工作量。 Spring2.5支持一種基於註解的控制器開發 ...
  • Java 項目中常常回遇到發送郵件 Java 發送郵件有幾種,今天先給大家介紹用 HtmlEmail 來發送郵件,我這裡是用 Maven 來搭建的 HtmlEmail 可以抄帶HTML 首先 需要導入jar 包 然後我們來建立一個發送郵件的 Mail 類 JavaBean 然後再來創建一個發送郵件的 ...
  • 只需要加android:windowSoftInputMode="stateHidden|stateAlwaysHidden"就可以 如:<activity android:name=".My_Message" android:windowSoftInputMode="stateHidden|sta ...
  • 一、fstat函數:顯示文件的所有信息 二、文件讀取: 三、寫入文件: 四、文件操作的應用: 五、拷貝文件: 六、創建文件 創建文件夾: 創建文件: 七、刪除文件: 刪除文件夾: 刪除文件: ...
一周排行
    -Advertisement-
    Play Games
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...
  • 目錄前言PostgreSql安裝測試額外Nuget安裝Person.cs模擬運行Navicate連postgresql解決方案Garnet為什麼要選擇Garnet而不是RedisRedis不再開源Windows版的Redis是由微軟維護的Windows Redis版本老舊,後續可能不再更新Garne ...
  • C#TMS系統代碼-聯表報表學習 領導被裁了之後很快就有人上任了,幾乎是無縫銜接,很難讓我不想到這早就決定好了。我的職責沒有任何變化。感受下來這個系統封裝程度很高,我只要會調用方法就行。這個系統交付之後不會有太多問題,更多應該是做小需求,有大的開發任務應該也是第二期的事,嗯?怎麼感覺我變成運維了?而 ...
  • 我在隨筆《EAV模型(實體-屬性-值)的設計和低代碼的處理方案(1)》中介紹了一些基本的EAV模型設計知識和基於Winform場景下低代碼(或者說無代碼)的一些實現思路,在本篇隨筆中,我們來分析一下這種針對通用業務,且只需定義就能構建業務模塊存儲和界面的解決方案,其中的數據查詢處理的操作。 ...
  • 對某個遠程伺服器啟用和設置NTP服務(Windows系統) 打開註冊表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer 將 Enabled 的值設置為 1,這將啟用NTP伺服器功 ...
  • title: Django信號與擴展:深入理解與實踐 date: 2024/5/15 22:40:52 updated: 2024/5/15 22:40:52 categories: 後端開發 tags: Django 信號 松耦合 觀察者 擴展 安全 性能 第一部分:Django信號基礎 Djan ...
  • 使用xadmin2遇到的問題&解決 環境配置: 使用的模塊版本: 關聯的包 Django 3.2.15 mysqlclient 2.2.4 xadmin 2.0.1 django-crispy-forms >= 1.6.0 django-import-export >= 0.5.1 django-r ...
  • 今天我打算整點兒不一樣的內容,通過之前學習的TransformerMap和LazyMap鏈,想搞點不一樣的,所以我關註了另外一條鏈DefaultedMap鏈,主要調用鏈為: 調用鏈詳細描述: ObjectInputStream.readObject() DefaultedMap.readObject ...
  • 後端應用級開發者該如何擁抱 AI GC?就是在這樣的一個大的浪潮下,我們的傳統的應用級開發者。我們該如何選擇職業或者是如何去快速轉型,跟上這樣的一個行業的一個浪潮? 0 AI金字塔模型 越往上它的整個難度就是職業機會也好,或者說是整個的這個運作也好,它的難度會越大,然後越往下機會就會越多,所以這是一 ...
  • @Autowired是Spring框架提供的註解,@Resource是Java EE 5規範提供的註解。 @Autowired預設按照類型自動裝配,而@Resource預設按照名稱自動裝配。 @Autowired支持@Qualifier註解來指定裝配哪一個具有相同類型的bean,而@Resourc... ...