1

我有一个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 对象。

优点:保证一致的初始化,没有分散注意力,每个类中的重复初始化代码

缺点:实现继承是邪恶的!,..嗯,配置器不能从任何其他类继承.. ??

我应该澄清一种或另一种方式,配置器必须实现IContextAware接口。此外,该类必须具有默认/无参数构造函数,因此构造函数依赖注入在这里不是一个选项。

有人可以建议如何使用组合来实现相同的好处,但设计​​更灵活,和/或描述上述继承解决方案的真正缺点吗?谢谢!

PS这是改编自Spring.Net CodeConfig,如果有人好奇的话。

4

1 回答 1

1

我认为 .NET 基类库是回答此类问题的一个很好的标准。您对继承的使用永远不会被放入 BCL,因为它将 API 的用户暴露给 API 内部。现在有一个没有任何语义含义的基类。它只是为了保存代码而存在。所有公共 API 元素都应该有目的和语义。

BCL 的作者在 API 设计方面显然非常严格。我从未见过如此庞大而原始的类型集合。

也就是说,如果您不需要该级别的 API 清洁度,则无需遵守相同的标准。并非每个 API 都向数百万开发人员公开。在 API 纯度上稍作妥协以节省大量代码并消除冗余和潜在的错误是一种合理的权衡。

我的选择:我会将您的方法用于内部代码。对于公共 API(想想 Codeplex 库等),我宁愿复制多余的东西并保持公共 API 表面干净。

于 2013-08-28T16:17:32.537 回答