我曾多次看到有人提到这一点,但我不清楚这是什么意思。你什么时候,为什么要这么做?
我知道接口是做什么的,但我不清楚这一点的事实使我认为我错过了正确使用它们。
如果你要这样做
IInterface classRef = new ObjectWhatever()
你可以使用任何实现IInterface的类吗?你什么时候需要这样做?我能想到的唯一一件事是,如果你有一个方法,你不确定什么对象将被传递,除了它实现IInterface。我不知道你需要多久做一次。
另外,如何编写一个方法来接受实现接口的对象呢?这可能吗?
即使当我们不依赖于抽象时,面向接口编程也是有利的。
接口编程迫使我们使用对象的上下文适当的子集。这很有用,因为它:
防止我们做一些不合时宜的事,还有
让我们在将来安全地更改实现。
例如,考虑实现Friend和Employee接口的Person类。
class Person implements AbstractEmployee, AbstractFriend {
}
在这个人的生日的情况下,我们编程到朋友界面,以防止像对待员工一样对待这个人。
function party() {
const friend: Friend = new Person("Kathryn");
friend.HaveFun();
}
在这个人的工作环境中,我们对雇员界面进行编程,以防止模糊工作场所的边界。
function workplace() {
const employee: Employee = new Person("Kathryn");
employee.DoWork();
}
太好了。我们在不同的环境中都有适当的表现,我们的软件运行良好。
在遥远的未来,如果我们的业务改变为与狗打交道,我们可以相当容易地更改软件。首先,我们创建一个实现Friend和Employee的Dog类。然后,我们安全地将新的Person()更改为新的Dog()。即使两个函数都有数千行代码,这个简单的编辑也可以工作,因为我们知道以下是正确的:
Function party只使用Person的Friend子集。
函数workplace只使用Person的Employee子集。
类Dog实现了Friend和Employee接口。
另一方面,如果任何一方或工作场所都针对Person进行编程,就会有同时拥有特定于Person的代码的风险。从“人”改为“狗”需要我们梳理代码,删除任何“狗”不支持的“人”特定代码。
寓意:为接口编程可以帮助我们的代码适当地运行,并为更改做好准备。它还使我们的代码能够依赖于抽象,这带来了更多的好处。
Using interfaces is a key factor in making your code easily testable in addition to removing unnecessary couplings between your classes. By creating an interface that defines the operations on your class, you allow classes that want to use that functionality the ability to use it without depending on your implementing class directly. If later on you decide to change and use a different implementation, you need only change the part of the code where the implementation is instantiated. The rest of the code need not change because it depends on the interface, not the implementing class.
This is very useful in creating unit tests. In the class under test you have it depend on the interface and inject an instance of the interface into the class (or a factory that allows it to build instances of the interface as needed) via the constructor or a property settor. The class uses the provided (or created) interface in its methods. When you go to write your tests, you can mock or fake the interface and provide an interface that responds with data configured in your unit test. You can do this because your class under test deals only with the interface, not your concrete implementation. Any class implementing the interface, including your mock or fake class, will do.
编辑:下面是一篇文章的链接,其中Erich Gamma讨论了他的引用,“面向接口编程,而不是面向实现编程。”
http://www.artima.com/lejava/articles/designprinciples.html