2012-04-05 63 views
1

我需要實現一個工作流程系統。您將如何實施Workflow系統?

例如,導出一些數據,我需要:

  1. 使用XSLT處理器來轉換XML文件
  2. 使用出現的轉變轉換成任意的數據結構
  3. 使用生成(文件或數據)並生成歸檔文件
  4. 將歸檔文件移動到給定文件夾中。

我開始創建兩類類Workflow,它負責添加新的Step對象並運行它。

每個步驟實現一個StepInterface。

我主要關心的是我所有的步驟都依賴於前一個步驟(除第一個步驟外),我想知道處理這些問題的最佳方法是什麼。

我雖然循環遍歷每個步驟,並提供每個步驟的結果前面(如果有的話),但我並不滿意它。

另一個想法已經允許「前面的」步驟被設定於一個步驟,如:

$s = new Step(); 
$s->setPreviousStep(Step $step); 

但我失去了工作流類的實用工具。

任何想法,建議?順便說一句,我還擔心整個工作流程的成敗,這意味着如果任何步驟失敗,我需要回滾或清理以前的數據。

回答

1

回滾可以很容易地適用於此結構,因爲每個Step將實現其自己的rollback()方法,如果任何步驟失敗,工作流程可以調用(優先以相反的順序)。

至於主要問題,這取決於你想得到多麼複雜。在基本級別上,您可以定義一個StepResult接口,每個步驟返回並傳遞到下一個接口。這種方法的明顯問題是每一步都應該「知道」StepResult的期望執行。對於小型系統來說,這可能是可以接受的,對於大型系統,您可能需要某種可配置的映射框架,可以告訴如何將上一步的結果轉換爲下一步的輸入。所以Workflow將調用StepStep回報StepResultWorkflow然後調用StepResultConverter(這是你的配置映射啄),StepResultConverter返回StepInputWorkflow然後調用下一StepStepInput等。

+0

您好,感謝您的寶貴答案,我做了類似的事情(至少是第一步,http://pastebin.com/KF2bp0Wy)我雖然過的StepResult但不是StepInput,關於「配置」爲我正在使用Symfony2我想知道如何使用ConfigurationBuilder來驗證結果。 – Trent 2012-04-05 18:19:42

+0

恐怕我不能給你任何實施幫助,除非你用Java來做。 :)請注意,回滾的「自然」方法是以相反順序調用它們,以便每個步驟都可以知道它處於與運行後完全相同的狀態。 – biziclop 2012-04-05 18:32:23

3

去年我實現了一個類似的工作流引擎(儘管封閉源代碼 - 所以沒有我可以共享的代碼)。以下是一些基於此體驗的想法:

  1. StepInterface - 可以做你現在正在做的事情 - 抽象一步。
  2. 此外,提供回滾的能力,但我認爲,當它失敗了一步應該知道和進一步處理之前進行清理。一個抽象的步驟可幫助您處理該(模板方法)
  3. 你可能要考慮基礎上,StepResult分支 - 這樣你就可以做一個StepMatcher,需要一個stepResult對象和條件 - 其子步驟,如果只執行條件返回true。
  4. 你也可以做一個StepException處理例外流程。如果某個步驟出現了錯誤。理想情況下,您可以在工作流級別進行定義(如果任何步驟失敗,請執行此操作)和/或在步驟級別進行定義。
  5. 我已經採取了一步返回所有可用的下一個步驟一個定義良好的結構(StepResult)的方法。如果存在龐大的數據(比如大文件等),那麼資源的URI /定位器將在StepResult中傳遞。
  6. 您的工作流程將需要上下文一起工作 - 在你引用的例子,這將是該文件的名稱,歸檔等的位置 - 這樣認爲WorkflowContext
附加的思想

你可能要考慮以下幾點太 - 如果這是什麼,你打算實施的大規模服務/服務器:

  1. 步驟可以在圖書館進行動態加載的
  2. 工作流程定義在XML/JSON文件中 - 再次在編輯時動態重新加載。
  3. 遠程調用和回調 - 作業提交給遠程服務,回調API。當遠程服務回調時,流程中的後續步驟會執行工作流程執行。
  4. 並行執行在可能的情況等
  5. 無國籍設計
1

我已經取得了巨大成功使用finite state machine實現工作流程。它可以像你喜歡的那樣簡單或複雜,多個工作流相互連接。通常情況下,FSM可以實現爲一個簡單的表,其中通過在對象上保留轉換的日誌並簡單地檢索最後一個條目,從而在歷史表中跟蹤給定對象的當前狀態。因此,一個轉型將是下面的形式:

nextState = TransLookup(currState,事件,[狀態])

如果要實現前端您可以使用此轉換信息來構建可在事件列表到當前狀態下的給定對象。