好的,假设我有两个类,A类和B类。它们都需要执行一个常见的操作,但是让它们都来自同一个对象是没有意义的,所以我们选择组合。基本上,“有一个”是有意义的,“是一个”不是。
现在,这两个类中的每一个都实例化了这个对象,并使用它来执行常见操作,一切都很好。现在一切都很好。
当这两个类中的每一个都必须暴露公共例程必须引发的事件时,就会出现问题。哦,哦。现在怎么样?
嗯,我们可以在两个类中的每个类中执行类似的操作:
public event EventHandler CommonEvent
{
add { theCommonObject.CommonEvent += value; }
remove { theCommonObject.CommonEvent -= value; }
}
但是现在这个代码需要在两个类中的每个类中重复,代码的读者也可能会对此代码感到有些困惑。 add
和remove
至少不是常见的关键字。
尽管如此,这两个类中都存在重复的代码,不仅如此,但此解决方案并不总是有效!
例如,如果theCommonObject
在单个方法中进行本地实例化,并且其范围仅在该方法中,那该怎么办呢。
在这种情况下,每个类中必须重复的示例代码:
public event EventHandler SomeCommonEvent;
private void SomeMethod()
{
theCommonObject = new theCommonObject();
theCommonObject.DoSomething();
theCommonObject.SomeCommonEvent += thisClass_SomeCommonEvent;
}
private void thisClass_SomeCommonEvent(object sender, EventArgs e)
{
var handler = SomeCommonEvent;
if (handler != null)
{
handler(this, e);
}
}
正如您所看到的,在这两种情况下都存在重复的代码,但在第二种情况下还有更多的代码,因为该对象是方法的本地而不是成员变量。
除了使用继承之外,我无法想到解决这个问题的方法,但我不认为这样做会产生语义上的意义,并且许多人经常声称组合在复杂性降低,易于使用方面优于继承。理解等等。
答案 0 :(得分:2)
你说你有一个“有一个”的关系。从那以后,根据您提出的复制代码的解决方案,我假设您的A类看起来像:
public class A
{
private SomeCommonObject theCommonObject;
public event EventHandler CommonEvent
{
add { theCommonObject.CommonEvent += value; }
remove { theCommonObject.CommonEvent -= value; }
}
public A()
{
theCommonObject = new SomeCommonObject();
}
}
问题出在哪里? theCommonObject
永远不能“在单个方法中进行本地实例化,其范围仅在该方法中。”
是的,add
和remove
并不常用。所以呢?该类的客户端永远不会看到add
和remove
。他们仍然使用传统的+=
语法订阅该事件。就客户而言,add
和remove
语法不是问题。而你,正在创建课程的开发人员,应该知道这些事情。
答案 1 :(得分:0)
您可以使用静态助手来获取代码一次但它也是“坏”
问题是实现可以用派生编写一次,你决定不派生。