2012-02-25 93 views
0

我有一個代表註冊過程中的一個步驟的類。當用戶在填寫完步驟後單擊保存,然後執行我希望在註冊過程結束時執行步驟時執行的其他操作以及在步驟中調用保存時,我希望某些步驟可以執行。那個階段。我決定使用擁有一個國家的想法,但它似乎有一個糟糕的代碼味道。有關如何改進此設計的任何意見?OO設計問題

public class Step1 
{ 
    public Enum State 
    { 
     InProcess = 1, 
     EndProcess 
    } 

    private State processState; 

    public Step1(State currentState) 
    { 
     processState = currentState; 
    } 

    public bool IsValid() 
    { 
     bool result; 

     if(processState = State.InProcess) 
     { 
      result = PerformCheck1(); 
     } 
     else if(processState = State.EndProcess) 
     { 
      result = PerformCheck2(); 
      result = PerformCheck3(); 
     } 
     else 
     { 
      throw new Exception("Cannot determine process state"); 
     } 

     return result; 
    } 

    public void Save() 
    { 
     if(processState = State.InProcess) 
     { 
      DoThing1(); 
     } 
     else if(processState = State.EndProcess) 
     { 
      DoThing2(); 
      DoThing3(); 
      DoThing4(); 
     } 
     else 
     { 
      throw new Exception("Cannot determine process state"); 
     } 
    } 
} 
+2

屬於codereview。 – 2012-02-25 14:36:26

回答

1

忽視其他問題的代碼,如果你採用這種設計,你會與步驟一個單片類風去。我想創建一個ISTEP接口,使每一步自己的類:

public interface IStep 
{ 
    bool IsValid { get; } 
    void Save(); 
} 

public class BeginStep : IStep 
{ 
    public bool IsValid 
    { 
     get 
     { 
      return PerformCheck1(); 
     } 
    } 

    public void Save() 
    { 
     DoThing1(); 
    } 
} 

public class EndStep : IStep 
{ 
    public bool IsValid 
    { 
     get 
     { 
      // Skipped PerformCheck2() since the result is directly overwritten 
      return PerformCheck3(); 
     } 
    } 

    public void Save() 
    { 
     DoThing2(); 
     DoThing3(); 
     DoThing4(); 
    } 
} 
+0

每一步都將是它自己的課程。這個樣本類被稱爲Step1,這是因爲當你保存一個步驟時,會有一些保存動作,當我們在Step5(最後一步)時,它會調用保存所有前面的步驟,但是需要完成一組不同的動作。處於最終狀態。 – user1054637 2012-02-25 14:46:55

0

如果我undersdand你的答案(+上賈斯汀的回答您的評論)正確,每一步都可以在「處理」和「完成」狀態並取決於它處於哪個狀態,您想要調用不同的Save()IsValid()方法。

此外,一旦您到達最後一步,每一步都會自動「完成」。

從您發佈的代碼中,似乎並不像一個步驟需要知道他目前處於哪種狀態。您只是想根據您是否在最後一頁上執行不同的操作。

是否有原因讓您不想創建封裝「已完成」邏輯的特定方法(例如SaveCompleted()IsValidCompleted())?

我不明白爲什麼Step類應該決定要執行哪個代碼,因爲決定是在步驟之外進行的,在這個步驟中,您將跟蹤活動步驟。

基於某種可以從外部修改的隱藏狀態自動執行正確的事情的「魔術方法」通常會導致不一致,意外的問題和長的調試會話。

我會建議你創建一個接口,如賈斯汀建議的,其他兩個包含「已完成」代碼的方法。 (有很多方法可以實現這一點,比如使用抽象基類來代替(可能的優點是「完成」方法可以默認爲「處理」方法)或單獨的接口(僅暴露「完成」方法到最後一頁,而不啓用它來調用regualr方法)等等,等等)

+0

我想我只是覺得它看起來更整潔,讓方法看起來像邏輯流程,而不是分解成單獨的方法。我重申你的觀點:分離關切。我也會在你的文章結尾看看這些建議 – user1054637 2012-02-25 15:38:05

0

作爲除了Justin的答案,這裏是一個維基百科的鏈接Finite-state machine,因爲你正在試圖建立一個有限狀態機。該鏈接提供了關於主題的理論背景知識。如果您的註冊過程變得更加複雜,文章中提到的州/事件表將有助於制定事件的流程。