我可以理解为什么要对接口而不是实现进行编程 . 但是,在以下示例中(我发现了很多):
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 回答
如果你想稍后扩展程序或者想要实现另一个Base-Class,那么它并不是真正必要的,但它是一个更好的设计 . 在你的情况下,我不会实现基类 . 如果您不想拥有默认行为,那么接口就可以了 . 如果您想要一个默认行为,那么只需编写没有接口的Base-Class
我更喜欢"lazy design" - 在需要时从
BaseSomething
中提取界面 . 在此之前,保持简单并跳过它 .现在我可以想到只有一个实现时有一个接口的两个原因:
还有另一个单元测试的模拟实现(即有第二个实现,但不在 生产环境 代码中) .
接口和实现在不同的类库中定义 . 例如 . 使用Model-View-Presenter模式时,视图可以驻留在.exe项目中,该项目依赖于实现演示者的.dll . 然后可以将IView接口放入.dll和演示者对通过依赖注入提供的视图的引用 .
如果您的BaseSomething是抽象的并且您实现了提供程序重载抽象方法的特定事物,那么在那时编程到它们的唯一方法是ISomething接口 . 但是,在您展示的示例中,除非您可以拥有多个基本实现,否则ISomething确实没有理由 .
你问题的正确答案是“ It depends ” .
你可以通过许多不同的方式来看待它,而这一切都与视角有关 . 当你有一个具体或抽象的基类时,它意味着你的对象在功能上有一些共同点 . 衍生对象以某种方式相互关联 . 接口允许您仅在功能 Contract 中确认实现接口的每个对象将负责实现 .
同样,当您再次编程接口时,您必须严格了解对象的功能,因为它实现了给定的接口 . 而且您无需担心每个对象在功能上如何实现这一点 .
您可以在同一事项上参考this answer .