2017-06-19 57 views
0

比方說,我決定寫一個應用程序,進行信件。 所以我製作的一類代表的概念:如何避免爲班級添加越來越多的狀態?

class Letter 
{ 
    //implementation1 
}; 

然後我意識到我需要添加一些「標誌」的字母,如「處理」,「處理」,「wont_be_processed」。

class Letter 
{ 
    //implementation1 
    state letter_state_; 
}; 

並假設所有字母都存儲在某個容器中。
(我想清楚上面提到的狀態是實施所必需的, 並不是業務邏輯的一部分。)
最後我明白我需要另一個特殊的標誌,它只用於一個字母所有對象,存儲在容器中。

於是兩個天真的方式如何進一步,我看現在是着手:
1)添加其他標誌;
2)添加另一個字段。
請注意,第一個選項將是不自然的,因爲「處理」,「處理」,「wont_be_processed」以某種方式相互關聯,並且新狀態不會正確地與它們相關。 第二個選項導致課程膨脹,我的同事也不喜歡添加新的字段(但是,沒有證明理由)。

是否有這樣的設計陷阱的集合名稱或克服問題的標準方法?

Upd。新增示例。
當時

void process_letter(Letter& foo) 
{ 
    if(foo.latter_state_ == states::wont_be_processed) 
     return; 

    if(foo.letter_state_ == states::processed) 
     process_impl_1(foo); 

} 

會是什麼?

void process_letter(Letter& foo) 
{ 
    if(foo.latter_state_ == states::wont_be_processed 
     && foo.new_spacial_state_ != special_state::bar) 
     return; 

    if(foo.letter_state_ == states::processed) 
     process_impl_1(foo); 

} 

UPD2
也許,整個設計是完全錯誤的。如果是這樣,我應該關閉這個問題嗎?

+0

只有兩種可能性:1)新狀態生效時原狀態不適用,2)原狀態獨立於新狀態,可能仍然適用。如果1)那麼它是一個新的狀態。如果2)那麼它是一個新的領域。 – stark

+0

這是第二種情況。然而,假設類是相當大的,我需要在構造函數中添加新的代碼行以正確處理新字段,並且我還需要更改代碼,負責類的序列化。所以添加新字段會導致不同文件的更改。同時,這個領域的唯一消費者將是一個「如果」在一個方法。是否有一條線,我應該停止添加這種「本性」的新領域? –

+0

也許,使用「狀態」這個詞是有誤導性的。我只需要以某種方式將屬性分配給字母以基於這些屬性來處理它們。但是我不想爲不同的字母引入新的類並寫一個工廠來創建它們。另外,我儘量避免使用動態多態。 –

回答

0

我推薦兩個項目:

  1. 枚舉狀態
  2. 使用狀態表

這裏的想法是使代碼,以便它具有至少改變的量。將狀態數據放入一個表格中將允許您用最少量的可執行代碼更改來增加表格。

對於狀態表,有很多實現。例如,在互聯網上搜索「狀態設計模式C++」。

一本好書或參考資料將幫助您進行枚舉。

編輯1:狀態表例子
可以具有[狀態-ID,函數指針]的表:

struct State_Entry 
{ 
    unsigned int state_id; 
    void (*Ptr_State_Processing_Function)(unsigned int state_id); 
}; 

放置狀態ID輸入到表中的一個很好的功能在於州不必是連續的或同質的。而且,通過保持函數指針的類型簡單,可以消除具有不同簽名的函數的問題(函數指針必須是相同的類型/簽名)。

+0

謝謝你的建議!枚舉狀態你的意思是使用枚舉或更一般的抽象枚舉? 這個問題,我可能沒有正確解決我的問題,是我已經有一組國家,我需要添加新的國家不與其他人對齊。我讀到了「國家模式」,但我不明白它是如何面對「非同質」狀態的。 –

+0

您可以創建一個新列表,其中第一個枚舉值是現有'enum'中的最後一個值。 –

+0

最基本的狀態表是一個包含狀態ID和指向處理狀態的函數的指針的結構表。你可以通過使用仿函數來獲得更多的幻想。 –