2010-11-23 99 views
4

我有以下類可讓某些對象訂閱更改事件。問題是我也有類B和C需要這個功能,允許對象訂閱相同類型的東西。我們當然不想複製和粘貼這個行爲。我們考慮繼承一個通用的基類,但是我們所有的類,包括A,B和C都已經從一個通用的BaseClass中繼承了。我們不希望將此行爲添加到BaseClass,因爲我們從BaseClass繼承的其他類E,F,G不需要此行爲。如何重構重複的事件處理代碼

有沒有更好的解決方案?

public class A : BaseClass 
{ 

    /*other properties and code */ 

    public event EventHandler OnChange; 
    private bool _hasChanged; 
    public bool HasChanged 
    { 
     get { return _hasChanged; } 
     set 
     { 
      _hasChanged = value; 
      //only need to notify when we've changed. 
      if (value) 
      { 
       if (OnChange != null) 
        OnChange(this, EventArgs.Empty); 
      } 
     } 
    } 
} 

回答

2

如果我們不使用繼承了一會兒什麼?

1-假設不是從一個公共基類繼承,而是將需要事件機制的客戶類與實現事件機制的對象組合起來。

假設我們班

public class EventNotifier 
{ 
    public event EventHandler OnChange; 
    private bool _hasChanged; 
    public bool HasChanged 
    { 
     get { return _hasChanged; } 
     set 
     { 
      _hasChanged = value; 
      //only need to notify when we've changed. 
      if (value) 
      { 
       if (OnChange != null) 
        OnChange(this, EventArgs.Empty); 
      } 
     } 
    } 
} 

2-

public class A 
{ 
    private EventNotifier eventNotifier; 
    public EventNotifier MyEventNotifier { get { return eventNotifier; } } 

    public A() 
    { 
     eventNotifier = new EventNotifier(); 
    } 


} 

3-現在你的A類用戶(類是繼承/由A級)

這是因爲如果B包含A

public class b 
{ 
    A obj ; 
    public b() 
    { 
     obj = new A(); 
     obj.MyEventNotifier.OnChange += new EventHandler(delegate { Console.WriteLine("Hi"); }); 
     obj. MyEventNotifier.HasChanged = true; 
    } 
} 
+0

這是perf等。沒有繼承的混亂,它更容易維護。謝謝。 – Riz 2010-11-23 12:33:27

4

考慮一種面向方面的編程方法,就像這個PostSharp example中使用的編程方法一樣。它將允許您使用屬性注入這種樣板代碼。

如果您創建相應的方面,然後你可以有這樣的代碼:

public class A : BaseClass 
{ 
    public event EventHandler OnChanged; 

    [ChangedNotify("OnChanged")] 
    public bool HasChanged { get; set; } 
} 

,或者,如果想法是有一個OnChange事件多個屬性,你可以只硬編碼到一方面,減少了你的代碼

public class A : BaseClass 
{ 
    [NotifyOnChanged] 
    public bool HasChanged { get; set; } 
} 
1

你可以考慮引入BaseClass的和A,B,C,包含共同行爲之間的中介類。這樣你就不會污染E,F,G這些不需要的行爲。

   BaseClass 
    ----------------------------- 
    |       | 
-----     NotifyBaseClass 
E,F,G       | 
          ----- 
          A,B,C 

NB雖然AOP看起來好吃我有重大問題試圖讓Postsharp與其他技術如工作MS代碼分析和MSBuild。

0

擁有可通知對象的子類可能是一種可行的方式,但它可能非常棘手,因爲方法會將這種方式乘以各種不同的類。另一種方法是將它包含在你的基類中併爲它定義一個接口,然後你可以簡單地添加相關類的接口。

當運行你要跟只需檢查它是否是一個IChangeable(或東西),只有掛鉤的事件,然後