2015-03-30 48 views
1

這是一個通用的軟件設計問題。假設你有一個基類和許多從它派生出來的類(大約10個)。將方法/字段放入只能由某些派生類使用的基類可以嗎

在一些類(3-4個派生類需要它)之間共享某些常用功能。基本上是UI控件的字段,創建UI控件的抽象方法和使用抽象方法來回收UI片段(8-9行代碼)的通用代碼。類似這樣的:

class BaseClass { 
    ... 

    protected UIControl control; 

    protected abstract UIControl CreateUI(); 

    protected void RecycleUI() { 
     if (/* some condition is met */) { 
      if (this.control != null) { 
       control.Dispose(); 
      } 
      this.control = this.CreateUI(); 
      this.AddToUITree(control); 
     } 
    } 

    ... 
} 

您認爲可以將它放到基類中,而不是在派生類中複製代碼。

缺點是這段代碼只用於某些基類,而對其他類完全不相關。

一種替代方法是創建一個從BaseClass派生的中間類,並將其用作需要該功能的中間類。我覺得爲一些特定目的的代碼行創建派生類感覺很重。它不覺得爲此需要中斷繼承樹。我們儘量保持層次結構儘可能簡單,以便很容易理解和理解繼承樹。也許如果這是C++,其中多重繼承是一個選項,它不會是一個大問題,但多重繼承不可用。

另一個選擇是創建一個實用程序的方法和創建/更新UI控制的接口:

interface UIContainer { 
    UIControl CreateUIControl(); 

    UIControl GetUIControl(); 

    void SetUIControl(UIControl control); 
} 

class UIControlUtil { 
    public void RecycleUI(UIContainer container) { 
     if (/* some condition is met */) { 
      if (container.GetUIControl() != null) { 
       container.GetUIControl().Dispose(); 
      } 
      UIControl control = container.CreateUI(); 
      container.SetUIControl(control); 
      container.AddToUITree(control); 
     } 
    } 
} 

我不喜歡這種選擇,因爲它滲出UI邏輯外部它是作爲它的UI不太安全狀態可以在外部操縱。派生類也必須現在實現getter/setter。一個優點是前面提到的繼承樹之外還有另一個類,它需要這個功能,它也可以使用這個效用函數。

您有任何其他建議嗎?我是否應該抑制內部釀造的共同代碼不再重複的衝動?

回答

1

一種替代方法是創建一個從 BaseClass的派生的中間類,並使用它作爲基礎與需要該 功能的那些。

那麼,這是我認爲是最合適的。但這取決於。這裏的主要問題是:是否需要UI回收的對象,與真正不同的對象?如果它們真的不同,你必須爲它們創建一個新的基類。如果差異真的可以忽略不計,我認爲把事情放在基類中是可以的。

不要忘了LSP

我們儘量保持層次儘量簡單,這樣就容易 跟蹤和了解繼承樹

我覺得更重要的這裏是讓事情變得不僅簡單,而且還接近你的現實世界的事物,以便建模新的實體將是容易的。現在看起來很容易,可能會在未來造成真正的麻煩。

+0

>是需要UI回收的對象,與真正不同的對象不一樣? 除了此UI回收之外,它們沒有太大差別。他們沒有這樣的功能。 我最終放棄了現在複製的代碼,主要是因爲邏輯本身非常簡單,並且很可能它不需要進行維護。 不過關於LSP的好處。 – nrydn 2015-04-01 21:56:26

+0

@nrydn很高興你解決了這個問題;)謝謝你的一個很好的問題。 – 2015-04-02 09:03:43

相關問題