[英]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相關。
所以我的問題是,在設計的框架中,我該如何或應該以從IAction到IAction的信息傳遞方式來實現此目的?
聽起來您正在嘗試表示狀態轉換圖。 您可以使用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.