这是组合而非继承的恰当用法吗
本文关键字:用法 继承 组合 | 更新日期: 2023-09-27 18:20:23
背景
我有一个基类BaseObject
,我想在整个应用程序中使用它。BaseObject
实际上只定义了应用程序中所有对象都必须具有的公共Guid
;此外,CCD_ 4定义了许多方法来帮助生成属性更改事件。这导致了以下代码:
[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
}
}
有人能提供一些反馈吗?我是否正在沿着关于可组合性/继承的正确道路前进
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框架!
您面临的问题很常见:具有交叉概念("方面")的预兆方法,如日志记录、安全性、ecc。。。
C#本身没有AOP功能,但有一些.NET库可以为您提供帮助。举个例子,看看PostSharp,或者看看Castle DynamicProxy,或者再看看MSDN上的这篇文章。