簡體   English   中英

Java設計模式幫助

[英]Java Design Pattern Help

您好,我正在嘗試構建將按順序執行的IAction對象的框架。 每個IAction實現都將執行為其實現的processAction()方法。 此方法返回一個IAction ,在大多數情況下是其自身,但在某些情況下可能是指向List中另一個IAction的指針。 創建了IActionIterator接口來管理列表中的移動。 這是界面



public interface IAction {
    public IAction processAction();
}

pulbic interface IActionIterator {
    public IAction getFirstAction();
    public IAction getNextAction( IAction action );
}

我的框架將獲得一個List ,並將遍歷該列表,執行每個IAction類的processAction() 這是循環的樣子



  IActionIterator  iter = ... // created some how
  IAction action = iter.getFirstAction();
  do {
       IAction newAction = action.processAction();
       if( action.equals( newAction ) 
           action = iter.getNextAction( action );
       else 
           action = newAction;

  while( action != null  )  {

因此,每個IAction都有其要執行的實現,並且某些IAction具有業務邏輯,這些邏輯將在列表中返回一個IAction而不是執行列表中的下一個IAction

我預計將要執行一些IAction類,但是列表中的下一個IAction將需要第一個的結果。 例如,一個IAction正在執行SQL查詢,並且結果與列表中的下一個IAction相關。

所以我的問題是,在設計的框架中,我該如何或應該以從IActionIAction的信息傳遞方式來實現此目的?

聽起來您正在嘗試表示狀態轉換圖。 您可以使用FSM而不是嘗試自己滾動嗎?

getFirstAction() / getNextAction()的返回簽名更改為簡單的holder對象:

public class IActionResponse {
    List getResultList();
    IAction getReturnAction();
}

我從未做過,但是也許您可以使用Serializable接口在Action之間傳遞通用信息? 然后,行動將期望某些類型的數據並知道如何處理它們。

希望這會有所幫助。我會將其放在接口本身中...如果僅需要前一個操作的結果,否則如果還需要祖先的結果,則可以將結果更好地存儲在某個外部類實例中,該實例在循環中填充並基於在操作ID上,您可以提取結果。

對於更簡單的情況,需要先前操作的結果

IActionIterator {public IAction getFirstAction(); 公共getFirstActionResult(); 公共IAction getNextAction(IAction action); }

在這種情況下,以下類型的界面確實可以很好地發揮作用:

public interface IAction {
    void invoke(IActionRequest req, IActionResponse res);
}

每個動作都從“ req”對象獲取其輸入-是開放式的,可以是任意值。 反過來,每個動作都有機會使用'res'對象傳達輸出-同樣是開放式的。

FWIW,您所描述的框架聽起來與某些現有框架非常相似。 在Cernunnos項目中查看一個示例,該示例的設計非常接近您的建議。

您可以考慮將動作傳遞給上下文/狀態對象(本質上是一個映射)。 讓操作用上下文元素將其傳遞給鏈上其他操作所需的元素。 然后,后續操作可以使用這些元素並根據需要操縱上下文。 您需要確保正確地排序事物,就像管理全局狀態一樣。 您可能需要具有多個僅將上下文的子集公開給特定操作的接口。 您的控制器可以根據需要檢查動作調用之間的上下文。

我認為您需要的是兩種設計模式的組合:命令和責任鏈

在命令中,您可以封裝動作的參數並在動作之間傳遞數據。 您可以記錄參數的處理,甚至可以根據需要實現撤消功能。 實際上,每個命令對象都類似於當前操作處理的上下文。

動作可以使用命令鏈相互傳遞控制,其中每個動作都鏈接到下一個動作。 完成其業務邏輯后,一個動作將調用下一個動作以處理向其提供命令對象的過程。

為了使其可擴展到不同的動作類,還可以在實現責任鏈時使用模式模板方法。 因此,每個動作類都是某些超級動作的子類,這些動作將定義一個模板方法,在該方法中將對命令進行一些預處理,例如檢查參數和其他內容。 然后將調用該子類,然后該模板方法將控制權傳遞給鏈中的下一個動作。

使用這種模式時,您不需要動作列表和一般的循環來處理它們。 您只需構造一個動作鏈,然后在向其提供命令對象的列表中的第一個動作上調用處理方法。 同樣,在構建鏈時,您還具有額外的自由度,可以按所需方式混合操作順序。 列表中的動作順序將沒有依賴性。

因此,基本上,您將需要下一個類和接口:

public interface IAction {
     public void process (Command command);
}

public class SuperAction implements IAction {
     private IAction nextAction;

     public void process (Command command) {
           // Check command object

           processAction(command);

           if (nextAction != null)
                nextAction.process(command);
     }

     public abstract processAction(Command command);

     public void setNextAction(IAction action) {nextAction = action;}
}

public class ActionConstructor {
     public IAction constructActoinChain() {
           // construct chain and return first object
     }

}

為了完成此操作,您必須定義Command對象,無論是否使用execute方法。 如果沒有execute方法,那么Command將只是在動作之間傳遞的參數的容器。

一些一般性的評論:您正在創建一個有限狀態機,這可能是工作流引擎的開始。 看一下其他人的嘗試是一個主意:

工作流引擎通常對標准類型的工作流項目進行操作。 如果您是這種情況,那么您可以將工作流程項(實現WorkflowItem接口的對象)(的集合)傳遞給第一個操作,並將其傳遞給每個下一個操作。 這使引擎可以通過參考WorkflowItem接口來處理常見的工作流程問題。 具體操作將需要檢測該亞型。

我沒有聽說過的一個主題是工作流的一個典型方面:異步處理。 通常,您希望能夠執行某些操作直到某個點,然后保持工作流狀態。 然后,可以通過某些事件(例如,用戶登錄並做出決定)觸發工作流以繼續。 為此,您需要一個數據層,該數據層可以將通用工作流狀態與特定於應用程序的數據分開保存。

最近,我為正在從事的項目構建了成熟的工作流引擎。 它是可行的(特別是如果您不嘗試使它無休止地通用,而是將其與當前的問題相匹配),但是卻需要大量工作。 我們之所以決定這樣做,是因為現有的框架(jBPM等人)似乎太不靈活且過於笨拙,無法滿足我們的需求。 而且我這樣做很有趣!

希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM