经常听说“面向接口编程”,但并不是特别的理解。什么时候应该面向接口编程?
当我一开始接触暴露出的接口的时候,我很困惑,并不知道为什么需要他们。如果我们使用Java或者c#,我们已经有了继承这个概念,我一开始把接口视为一个弱继承。但有个疑问“为什么要这么麻烦”?从某个方便讲,把接口视为弱继承是对的,但除此以外,我最终把接口的使用理解为:一种语言架构:把共同的特性和行为给对象化,抽象化,这样就可以把一些看似不相关的潜在的对象展示出来。
举个例子:
有一个SIM游戏,和以下类:
class HouseFly inherits Insect {
void FlyAroundYourHead();
void LandOnThings();
}
class Telemarketer inherits Person {
void CallDuringDinner();
void ContinueTalkingWhenYouSayNo();
}
很显然,这两个类没有共同处(从他们直接继承的类来看),但你可以说他们都很烦人。
现在我们想想,我们的游戏需要一些随机的事情可以打扰玩家,在她们正在吃饭的时候。想像一下,一个苍蝇或者一个电话推销员多烦人啊。思考:苍蝇和电话推销员怎么可以通过同一个函数调用,让他们扰乱玩家?
你打算如果让两个完全不同的类,让他们通过同一个方式去扰乱玩家?
key就是:让他们都去实现同一个方法。
interface IPest {
void BeAnnoying();
}
class HouseFly inherits Insect implements IPest {
void FlyAroundYourHead();
void LandOnThings();
void BeAnnoying() {
FlyAroundYourHead();
LandOnThings();
}
}
class Telemarketer inherits Person implements IPest {
void CallDuringDinner();
void ContinueTalkingWhenYouSayNo();
void BeAnnoying() {
CallDuringDinner();
ContinueTalkingWhenYouSayNo();
}
}
可以把接口看成一个合同,现在两个类可以通过自己的方式去扰乱玩家,实现了解耦,只需要满足IPest 这个合同即可。
我们现在模拟这个场景:
class DiningRoom {
DiningRoom(Person[] diningPeople, IPest[] pests) { ... }
void ServeDinner() {
when diningPeople are eating,
foreach pest in pests
pest.BeAnnoying();
}
}
大家准备吃饭的时候调用ServeDinner,IPest[] pests中可能是一群苍蝇或者一群推销员,他们在打扰别人的时候可以分开干自己的活。