webx—CommandDispatcher分發服務

一、簡介

Command pattern是一套基於Spring Framework ,以Use Case爲中心的框架。它糅合了幾種經典的JavaEE設計模式,使應用開發者在實現Use Case時,能夠更專注於商業邏輯本身。

結構圖:




整個業務層都是用Spring框架來配置的。Spring是一種輕量的IoC的框架,使用Spring能夠最大程度上保證業務邏輯不被污染

表現層調用業務邏輯層的流程圖:


二、具體流程

1. 客戶端

如何調用一個業務邏輯呢?對於業務邏輯的調用者(通常是表現層),完全不用關心這個業務邏輯是如何實現的。對客戶端而言,它只能看到command dispatcher,如下圖:
對需要調用業務操作的Web層組件,其內聚了一個CommandDispatcher,通過該dispatcher來完成業務的委派,但是這個commandDispatcher就是一個Bean,它存在於Spring容器之中(可以參考web層的模塊ioc)。缺點在於web層被command所侵入,並且與業務實現在一定程度上發生了耦合。


步驟:

a)創建一個Command,填上業務邏輯所需要的參數。
b)將Command對象傳遞給CommandDispatcher,這樣就完成了業務邏輯的調用。
c)如果需要,可以取得業務邏輯的返回結果。

// Step 1. 裝配一個command,
//         command名稱爲"userCommand","userCommand"中有許多有關user的子命令,
//         而"registerUser"是其中的一個子命令。(子命令參數是可選的)
Command command = new CommandSupport("userCommand", "registerUser");

commandName.getParameters().put("name", "michael");
commandName.getParameters().put("password", "helloworld");
commandName.getParameters().put("email", "[email protected]");

// Step 2. 調用業務邏輯
Result result = getDispatcher().execute(command);

// Step 3. 處理返回結果
if (result.isSuccess()) {
    User user = (User) result.getModels().get("user");
    
    // 通常這類操作會返回數據庫所創建的sequence ID。
    int id = user.getId();
    
    ...
} else {
    ResultCode errorCode = result.getResultCode();
    
    if (errorCode == UserResultCode.USER_ALREADY_EXISTS) {
        ...
    }
    
    ...
}

2. 服務端

服務端,它也不需要了解客戶端的情況。服務端要做的,無非是從系統接收command的請求,然後執行相應的業務邏輯而已。

步驟:

a)創建ApplicationObject(即AO)。
實現ApplicationObject接口,但建議從ApplicationObjectSupport繼承

public class LoginAO extends ApplicationObjectSupport {
}

b)執行

類似於WebX中的action,AO可以根據command中的event參數來自動調用相應的方法,例如 new CommandSupport("loginAO", "login"),那麼,只要實現下面的方法即可

public Result doLogin() {
    Account user   = userManager.login(userId, password);
    Result  result = new ResultSupport();

    if (user == null) {
        result.setSuccess(false);
        result.setResultCode(
                LoginResultCode.INVALID_USER_OR_PASSWORD);
    } else {
        result.setDefaultModel("user", user);
    }

    return result;
}
如果沒有提供event參數,或未匹配event,那麼默認的doPerform()方法將被執行

3. CommandDispatcher 實現

CommandDispatcher是一個“分發器”。它的功能就是根據command的名字找到相應的業務邏輯對象,並執行之。每一個業務邏輯對象對應一個或一組相關的use case。例如:在用戶管理系統中,用戶的創建、刪除、修改等操作可以看作一個use case,因而我們可以寫一個業務邏輯對象——“UserManagementAO”——來處理這個use case。“AO”是“ApplicationObject”的縮寫,每一個AO必須實現ApplicationObject接口。

CommandDispatcher有多種實現,以適應多種需要:



序號

CommandDispatcher的實現

說明

1.

Stateless Session Bean

(CommandDispatcherBean)

 

使用Stateless Session Bean來分發Command。該實現允許進行分佈式的商業邏輯調用。

2.

Message-driven Bean

(CommandDispatcherClient)

通過Message-driven Bean來分發Command,通過JMS來發送Command請求。該實現允許進行異步的商業邏輯調用。

3.

Plain Javabean

(CommandDispatcherLogic)

通過普通的Javabean來分發Command。這個實現非常適合在非EJB的環境下調用商業邏輯。

4.

NOOP

(CommandDispatcherNoop)

不做任何事情的分發器。這個實現非常適合在程序的開發階段,用來調試程序。或者當商業邏輯還未開發完成時,調用者可以利用該分發器來“調用”商業邏輯,以便調用者的代碼可以被順利地開發。

5.

Selector

(CommandDispatcherSelector)

該分發器可根據Command的內容來自動先擇合適的其它CommandDispatcher。這樣,我們就可以更方便地控制CommandDispatcher的行爲。例如,在調用者完全不知情的情況下,將某個Command的處理轉變爲利用Message-driven bean來異步處理。


儘管有這麼多種CommandDispatcher的實現,但是表現層完全不用瞭解這些細節。所有的CommandDispatcher都是通過spring來配置的


4. 小結

Command Pattern是基於request-response的模式。客戶端創建command,服務端響應command並返回結果給客戶端 —— 類似WEB層的模式。而客戶端和服務端是通過command dispatcher來連接的。
這種模式有什麼好處呢?
最大的好處,就是客戶端和服務端完全分離。無論是Web-tier還是Biz-tier都不用瞭解command分發的細節 —— 這些細節對代碼是透明的。
其次,所有的CommandDispatcher都是通過spring來配置的,因此也很容易創建新的CommandDispatcher模式。目前已經支持同步、異步等操作。
那麼,這種模式有什麼缺點呢?任何設計模式都有適用的場合,也有不利的一面。Command Pattern也不例外。
這種模式最大的缺點是,沒有一種統一的方法,可以知道業務邏輯層所需要的參數個數、類型,同樣也很難知道返回值的數量和類型。這樣會增加客戶端/服務端程序員交流的成本。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章