【发布时间】:2013-08-28 14:07:53
【问题描述】:
我有一个Configurator 类,为了完成它的工作,必须通过接口接收一个Context 对象:
public class Configurator : IContextAware
{
private IContext _context;
//property setter defined by the IContextAware interface
public IContext Context { set { _context = value; } }
// use _context object in other methods here ...
}
我计划编写许多Configurator 类型,它们都需要以相同的方式初始化它们的_context 字段。我的第一个想法是“为什么不激怒互联网上的每个程序员并使用继承”?
public class ContextInitializer: IContextAware
{
// field to hold the injected context
protected IContext _context;
//property setter defined by the IContextAware interface
public IContext Context { set { _context = value; } }
}
public class Configurator : ContextInitializer
{
// use _context object here ...
}
这样,我编写的任何其他需要 Context 对象的类都可以直接从 ContextInitializer 继承,并立即使用 Context 对象。
优点:保证一致的初始化,没有分散注意力,每个类中的重复初始化代码
缺点:实现继承是邪恶的!,.. 嗯,Configurator 不能从任何其他类继承.. ??
我应该澄清一下,配置器必须以一种或另一种方式实现IContextAware 接口。此外,该类必须有一个默认/无参数构造函数,因此构造函数依赖注入在这里不是一个选项。
有人可以建议如何使用组合来实现相同的好处,但设计更灵活,和/或描述上述继承解决方案的真正缺点吗?谢谢!
附:这是改编自 Spring.Net CodeConfig,如果有人好奇的话。
【问题讨论】:
-
继承是邪恶的?我错过了那份备忘录。
-
@Rik blogs.msdn.com/b/steverowe/archive/2008/04/28/… javaworld.com/javaworld/jw-08-2003/jw-0801-toolbox.html c2.com/cgi/wiki?ImplementationInheritanceIsEvil 事实上,如果我被问到“
Configurator是ContextInitializer吗?我不得不说不,但使用ContextInitalizer,因此表明继承在这里并不完全正确。 -
绝对陈述总是是错误的。继承本身并不是邪恶的。这是一个工具。您可以使用锤子将钉子钉入墙壁或敲开某人的头骨。这就是你如何使用它,这可能是邪恶的。
-
好的,所以滥用继承是邪恶的。明白了。
-
@user1467261 - 你是对的,
Configurator使用ContextInitializer。那么为什么不将构造函数设为public Configurator(IContextInitializer contextInitializer) { // use contextInitializer }? (顺便说一句。如果您打算使用不同类型的上下文初始化器,我强烈建议您使用接口)- 一个很好的例子是在 wikipedia。
标签: c# inheritance