2009-05-26 9 views
2

假設您具有帶有Visibility屬性的控件A,B,C,D和E。您還有狀態1,2,3,4,5和6,其中將顯示各種控件組合。重構設計模式:根據狀態顯示/隱藏控件的不同組合

目前,這是由switch語句的每個狀態的處理:即

Select Case PageState 
    case "1" 
     a.visible = false 
     b.visible = true 
     c.visible = false 
     d.visible = true 
     e.visible = false 
    case "2" 
     a.visible = true 
     b.visible = true 
     c.visible = false 
     d.visible = true 
     e.visible = false 
    case ... 
End Select 

正如你可以想像,這是每個國家都需要爲每個控件顯示/隱藏的語句變成了痛苦。我如何重構這個,以便添加控件和/或狀態變得微不足道?

我的第一本能是擴展控件並添加它應該顯示的狀態集合,但這聽起來像是矯枉過正。

編輯 我故意模糊了我的問題,以防這種情況有其他影響。在我目前的情況下,所討論的「控制」是ASP面板。這會改變什麼嗎?

回答

2

使用狀態模式。讓每個狀態下運行的網頁(抽象爲一個接口)上:

public interface IControlSituationPage // your page implements this 
{ 
    void SetAvisibility(bool visibility); 
    void SetBVisibility(bool visibility); 
    ... 
} 

....

public interface PageState // each state implements this 
{ 
    void ApplyState(IControlSituationPage page); 
} 

..然後,在(工廠模式也許)搞清楚你是哪個州之後,調用方法:

// ... somewhere.. 
_state.ApplyState(this); 

當然,這是代替實際使用像MVC或MVP更強大的演示模式。

3
+0

萬歲狀態機! – 2009-05-26 20:22:19

+1

喜歡這個名字。感謝您的迴應。 – 2009-05-26 20:24:09

1

[注:我是一個Java的傢伙,所以我下面的實現是在Java中 - 它應該是非常相似的C#或任何其他語言要使用]

羅布指出,上述的麻煩解決方案 - 它是不可維護的。

它也非常詳細(GoF狀態模式通常是...)。

有時狀態模式不是你應該使用的。

如何將問題從內部轉出並讓數據驅動它?

把它看作是「哪些國家應該顯示X?「

嘗試類似如下:

  1. 創建一個代表你的國家
  2. 爲每個控件的EnumSet枚舉(他們是非常有效的)
  3. 在每個EnumSet,加國對於其控制應是可見
  4. 狀態改變時,檢查每個控件的可見

粗略的實現(未編譯/測試)

public enum MyStates {State1, State2, State3...} 

public class VisibilityManager { 
    private Map<Component, Set<MyStates>> managedComponents = 
     new HashMap<Component, Set<MyStates>>(); 
    private Component component; 
    public void setVisibility(Component component, MyStates... states) { 
     Set<MyStates> visibleStates = EnumSet.of(states); 
     managedComponents.put(component, states); 
    } 
    public void update(MyStates currentState) { 
     for (Map.Entry<Component, Set<MyStates>> e : managedComponents.entrySet()) 
      e.getKey().setVisible(e.getValue().contains(currentState)); 
    } 
} 

// then in your GUI setup 

VisibilityManager v = new VisibilityManager(); 
v.setVisibility(comp1, MyStates.State1, MyStates.State2); 
v.setVisibility(comp1, MyStates.State3); 
v.setVisibility(comp1, MyStates.State1, MyStates.State3, MyStates.State5); 
... 

// and when you change the state 
v.update(newState); 

希望這有助於!

0

斯科特得到了重點 - 對於這種微不足道的情況(當你只需要控制可見度),使用反向邏輯就很有意義。如果您需要執行狀態轉換並從業務邏輯中獲取UI摘要,狀態模式將變得非常有用。