2014-09-03 111 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