2014-09-29 70 views
4

我試圖找到一個優雅的方式來實現決策制定算法,使得易於維護,因爲決策制定的條件可能會經常改變。決策制定,複雜條件和規劃易維護

我要去嘗試和更具體的在這裏一個例子:

比方說,我想管理團隊烹飪的廚師在餐廳的廚房。

每位廚師都知道如何烹製3種餡餅:蘋果派,南瓜派和覆盆子派,以及2種比薩餅:芝士披薩和培根披薩。他們都知道如何烹飪一切。

現在,我想向這些負責人發送有關客戶需求的訂單。

條件是:

一個首席一次只能做一個餡餅。例如,如果我點了一個廚師做蘋果派,我不能命令他做一個覆盆子派或一個南瓜派,除非蘋果派已經完成,否則我會發送取消蘋果派的請求。

我可以請廚師一次做5個披薩,因爲它是針對不同的客戶。

我很想創建一個算法,該算法返回我允許發送給特定廚師的訂單集,關於他已經在做什麼。

我正在使用C++。 我可以寫一個簡單的開關/案例陳述,但如果條件改變或新的餡餅被添加,維護將不是容易的,所以...

我有點卡住,真的看不到我怎麼能包裝條件和決策,以減少雙方的條件,並允許在餡餅烹飪的條件容易維護。

你將如何處理複雜決策算法的實現?

+0

如果您正在尋找它的一般設計決策,可能[programmers.se](http://programmers.stackexchange.com/)更適合這個問題。 – Yann 2014-09-29 09:31:21

+0

然後我會提出我的問題,謝謝 – JeD 2014-09-29 09:35:48

回答

4

我可以寫一個簡單的開關/ case語句,但是如果條件改變或添加新的餡餅,所以保養也並不容易......

我有點卡住,真不」不要看我如何封裝條件和決策制定,以減少雙方的條件差異,並且容易維護餡餅烹飪的條件。

你將如何處理複雜決策算法的實現?

從switch/case到可維護的OOP的經典更改/重構是用抽象類專業化/實現來替換每個條件和動作。

舊代碼:

variable_t variable; // initialized elsewhere 
switch(variable) { 
case value1: 
    do_action1(); 
    break; 
case value2: 
    do_action2(); 
    break; 
// ... 
} 

新代碼:

struct Actor // actor is your "abstract chef" 
{ 
    virtual ~Actor(); 
    virtual bool matches(variable_t const v) const = 0; 
    virtual void do_action() = 0; 
}; 

現在,每個動作和條件相結合,爲您打造一個專業化:

struct SweedishChef: public Actor { 
    bool matches(variable_t const v) const override 
    { 
     return v == 1; 
    } 

    void do_action() override 
    { 
     std::cerr << "bork! bork!\n"; 
    } 
}; 

這樣,客戶端代碼不再有任何硬編碼。

初始化的客戶端代碼:

std::vector<std::unique_ptr<Actor>> actors; 
actors.emplace_back(new SweedishChef{} }; 
// adding a new type of chef simply means adding _one_ line of 
// code here, for the new type 

決策代碼(替換舊switch代碼):

// using std::find, begin, end 
variable_t variable; // initialized elsewhere 
const auto chef = find(begin(actors), end(actors), 
    [&v](const std::unique_ptr<Actor>& a) { return a->matches(v); }); 

if(chef != end(actors)) 
    chef->do_action(); 
else 
{ 
    // here goes whatever was in the default part of the switch code 
} 

從一個維護和可測試性點,該代碼是一個很大的維護:

  • 當廣告時客戶端代碼的變化很小定一個新的廚師

  • 廚師和命令之間的相互作用進行了正式的(和冷凍)的接口

  • 每個條件後面/動作可以(也應該)分別

  • 調度機制測試可以單獨進行測試(並用嘲弄的注入角色來擊中各種情況)。

  • 初始化機構可以單獨

+0

非常準確,謝謝。這與戰略模式相似嗎? – JeD 2014-09-29 09:56:27

+1

它被稱爲狀態模式http://en.wikipedia.org/wiki/State_pattern – 2014-09-29 09:58:06

-1

號測試這是太多的代碼。只需統計符號。這種編碼並不能保證「新SweedishChef {}」可以清除內存。變量聲明中客戶端的大小變長了。

+0

@ user4090727,該問題明確要求減少耦合並使代碼更模塊化/可維護(不包含更少符號的代碼)的設計。此外,「這種conding」被稱爲RAII(即用'new'分配並將結果放置在std :: unique_ptr中,位於std :: vector中),並且_does_事實上保證了釋放「new SweedishChef { 」。 – utnapistim 2014-09-29 10:58:34