【问题标题】:Programming against an interface with only one class implementing said interface针对只有一个类实现所述接口的接口进行编程
【发布时间】:2011-05-22 13:45:39
【问题描述】:

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

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相比?

【问题讨论】:

  • 如果只有一个实现,是的,从实际的角度来看,你真的不需要接口。但是,问问自己:是这样吗?如果事实证明不是,你是否愿意检查整个代码库?
  • 这是一个新项目,所以几乎还没有完成。我已经以这种方式工作了一段时间,只是刚刚开始怀疑它。如果我有一个现有的代码库,我不会打扰。

标签: c# design-patterns interface implementation


【解决方案1】:

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

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

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

【讨论】:

  • 这个答案比接受的答案恕我直言更有帮助。谢谢。
【解决方案2】:

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

您可以通过多种不同的方式来看待它,而这一切都与透视有关。当您拥有具体或抽象的基类时,这意味着您的对象在功能上具有共同点。派生对象以某种方式相互关联。接口让您仅在实现接口的每个对象都将负责实现的情况下确认功能契约。

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

这也不是完全错误的,如果我说 你的每一个对象都是完全的 独立的时候 实现接口 ISomething,前提是 SpecificSomethingOne 和 SpecificSomethingTwo 不是从 BaseSomeThing 派生的,而是各自实现自己的 ISomething。

同样的事情你可以参考this answer

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 2013-04-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多