针对仅具有实现所述接口的一个类的接口进行编程

时间:2011-05-22 13:45:39

标签: c# design-patterns interface implementation

我可以理解为什么要对接口而不是实现进行编程。但是,在以下示例中(我发现了很多):

public interface ISomething
{
    void BlahOne(int foo);
    void BlahTwo(string foo);
}

public class BaseSomething : ISomething
{
    public void BlahOne(int foo)
    {
        //impl 
    }

    public void BlahTwo(string foo)
    {
        //impl
    }
}

public class SpecificSomethingOne : BaseSomething
{
    public void SpecificOne()
    {
        //blah
    }
}

public class SpecificSomethingTwo : BaseSomething
//and on..

目前的例子是我游戏中基于组件的实体系统。 (我有IComponent,Component,PosComponent等)。

但是,我看不出有ISomething的理由。名称可能看起来更好,但它似乎没有目的。我可以随时返回BaseSomething。

当您使用单个基本实现时,是否有理由拥有接口? (我可以看到IComparable或IEnumerable的使用)

编辑:对于稍微不同的场景(但仍然相关,不需要不同的问题),如果我假设我有所有的这个结构,如果我使用ISomething作为参数会有很大的不同类型和变量与BaseSomething相比?

4 个答案:

答案 0 :(得分:13)

我更喜欢“懒惰设计” - 在需要时从BaseSomething提取界面。在此之前,请保持简单并跳过它。

现在我可以想到只有一个实现时有一个接口的两个原因:

  • 还有另一个单元测试的模拟实现(即第二个实现,但不在生产代码中)。
  • 接口和实现在不同的类库中定义。例如。使用Model-View-Presenter模式时,视图可以驻留在依赖于实现演示者的.dll的.exe项目中。然后可以在.dll和演示者对通过依赖注入提供的视图的引用中放入IView接口。

答案 1 :(得分:2)

对您的问题的正确答案是“取决于”。

你可以用许多不同的方式来看待它,而这一切都与视角有关。当您拥有一个具体或抽象的基类时,这意味着您的对象在功能上具有共同点。衍生对象以某种方式相互关联。接口允许您仅在功能合同中确认实现接口的每个对象将负责实现。

同样,当您再次编程接口时,您必须严格了解对象的功能,因为它实现了给定的接口。而且您无需担心每个对象在功能上如何实现这一点。

  

如果我说的话,这不是完全错误的   你的每个对象都是完全的   在谈到时是独立的   实现ISomething接口,因为SpecificSomethingOne和SpecificSomethingTwo不是从BaseSomeThing派生的,而是每个都实现了自己的ISomething。

您可以在同一事项上参考this answer

答案 2 :(得分:1)

这不是必要的,但如果您想稍后扩展程序或者想要实现另一个Base-Class,那么它是一个更好的设计。 在你的情况下,我不会实现基类。如果您不想拥有默认行为,那么接口就可以了。如果您想要一个默认行为,那么只需编写没有接口的Base-Class

答案 3 :(得分:0)

如果您的BaseSomething是抽象的并且您实现了提供程序重载抽象方法的特定事物,那么在那时编程到它们的唯一方法是ISomething接口。但是,在您展示的示例中,除非您有多个基本实现,否则ISomething实际上没有理由。