2014-09-03 64 views
1

背景這是一個適當的使用組合超越繼承?

我有一個基類BaseObject,我想在整個應用程序中使用。 BaseObject確實只定義了應用程序中所有對象必須具有的公共Guid;此外,BaseObject定義了許多幫助生成財產變更事件的方法。這導致了下面的代碼:

[DataContract] 
public abstract class BaseObject 
{ 
    private Guid id; 
    [DataMember] 
    public Guid Id 
    { 
     get { return id; } 
     set { ChangeProperty(ref id, value, "Id"); } 
    } 

    protected virtual void ChangeProperty<T>(
     ref T property, 
     T value, 
     string propertyName) 
    { 
     // Change the property and generate events 
    } 
} 

問題

因爲所有對象必須從BaseObject繼承,這意味着派生類將有一個「固定」 ChangeProperty。我想修改ChangeProperty,以便它輸出到控制檯,我將不得不修改基類。

潛在的解決方案

,我已經重新編寫,現在看起來像下面的代碼;我有一個單獨的類來處理屬性更改:

public interface IPropertyChangeHelper 
{ 
    void ChangeProperty<T>(
     ref T property, 
     T value, 
     string propertyName, 
     PropertyChangingEventHandler changingHandler, 
     PropertyChangedEventHandler changedHandler); 
} 

[DataContract] 
public abstract class BaseObject 
{ 
    // passed in during construction 
    private readonly IPropertyChangeHelper propertyChangeHelper; 

    private Guid id; 
    [DataMember] 
    public Guid Id 
    { 
     get { return id; } 
     set { ChangeProperty(ref id, value, "Id"); } 
    } 

    // Forwarding method 
    protected virtual void ChangeProperty<T>(
     ref T property, 
     T value, 
     string propertyName) 
    { 
     // Forward to helper 
    } 
} 

可能有人請提供一些反饋,我是否繼續沿着正確的方向關於可組合/繼承?

+2

如果你在這裏有一個「虛擬」成員,爲什麼你必須改變基類?它看起來像你的基類本身實際上只是一個接口本身。我不確定這個問題是不是以意見爲基礎適合SO – Carsten 2014-09-03 07:34:12

+0

嗨,感謝您的評論。是否有另一個董事會/論壇可以讓我更加自信地迴應? – user2684289 2014-09-03 08:00:37

+1

http://codereview.stackexchange.com/? – 2014-09-03 08:46:55

回答

0

ChangeProperty是虛擬的,所以如果你只是想修改繼承(「子」)的一個類的行爲,你可以做到這一點:

[DataContract] 
public class MyObject: BaseObject 
{  
    protected virtual void ChangeProperty<T>(
     ref T property, 
     T value, 
     string propertyName) 
    { 
     // Do my own stuff 
     base.ChangeProperty(property, value, propertyName); 
    } 
} 

在另一方面,如果你想爲每個BaseObject「修改」(或者更好,我會說加大)ChangeProperty方法,我會走你的路。

我可能會使用更多的 「一般」 的方法,如:

[DataContract] 
public abstract class BaseObject 
{ 
    public IPropertyChangeHelper propertyChangeHelper { get; set; } 

    ... 

    public void ChangeProperty<T>(
     ref T property, 
     T value, 
     string propertyName) 
    { 
     if (propertyChangeHelper != null) 
      propertyChangeHelper.beforeChange(value, propetyName) 
     ... 

     if (propertyChangeHelper != null) 
      propertyChangeHelper.afterChange(value, propetyName) 
    } 
} 

相應修改界面。但要達到個人喜好/交易安全(誰將使用你的課程?)以獲得靈活性。

也就是說,如果你不想使用AOP框架!

你所面對的問題是相當普遍:augument方法與跨部門的概念(「方面」),如日誌,安全,ECC ...

C#,本身不具有AOP設施,但有.NET庫可以幫助你。舉個例子,看看PostSharp,或城堡DynamicProxy,或再次在這篇文章MSDN

+0

@Lozenzo感謝您的信息。正如你已經正確猜測,我想能夠修改一個孩子或所有BaseObject的ChangeProperty。我已經快速瀏覽過你建議的DynamicProxy,它可能會很有用,但我必須仔細研究它,看看它是如何發展的。 – user2684289 2014-09-04 01:03:20