在TDD /注入视角思考中,我会非常感兴趣地告诉我正在处理接口的课程的“用户”。主要原因是我认为系统的不同“代理”之间的接口合同。在我系统的一个角落工作的代理人,不应该知道另一个代理工作的具体实现;他们应该只交换合同,并期望合同能够在不了解的情况下实现。另一个也是非常重要的原因是,一个界面可以完全模拟,从而使单元测试更容易。你可以嘲笑一个具体的课程有多少限制。
因此,我更喜欢可视化我确实在接口上处理或以接口为参数。但是,由于UncleBob是我们社区的重量级冠军,而且我只是另一个飞行桌面骑师,我想知道我是否缺少某些东西。
我是否坚持我在界面是错误的?
接口前面的“I”是另一个向后的约定。当您传递对对象的引用时,您应该期望它是一个接口。接口应该是默认的;所以没有什么意义可以做一些额外的事情,像使用一个前缀,宣布你正在做每个人都期待你做的事情。如果我们为传递一个具体类的特殊条件保留了一个特殊标记,那将会更好(但是仍然是错误的)。
使用I的另一个问题是(奇怪的是)我们用它来通信使用接口的实现决定。通常我们不希望实施决定如此响亮,因为这使得他们难以改变。例如,考虑到如果您确定IFoo真的应该是抽象类而不是接口,那么可能会发生什么。你应该改名为Foo还是CFoo,还是ACFoo?
我可以听到你的头部转动的轮子。你在想:“是的,但接口在语言中有一个特殊的地方,所以用一个特殊的命名约定来标记它们是合理的。”确实如此。但整数也有一个特殊的语言,我们不会标记它们(再也没有)。此外,问问自己,为什么界面在语言中有特殊的地位?
Java和C#中的接口背后的整个想法是一个cop-out。语言设计师可以使用抽象类,但是担心实现多重继承的困难。所以他们自己做了一个后台处理。他们发明了一种人造结构(即接口),它将提供多种继承的一些功能,并且它们将正常类限制为单一继承。
这是语言设计师做出的最糟糕的决定之一。他们发明了一个新的和重量级的语法元素,以排除有用的和强大的(虽然有争议的)语言特征。接口没有被发明以实现,它们被发明为禁用。接口是设计师不愿意解决MI的更难问题的语言中的一个黑客。所以当你使用我的前缀,你是一个大的聚光灯在语言史上最大的黑客之一。
下次写这样的函数签名时:
public void myFunction(IFoo foo) {...}
问问自己:“为什么我想知道IFoo的作者使用”界面“这个词呢?对我来说,他使用’interface’或’class’甚至’struct’有什么区别?不是我的,所以为什么他强迫我知道他的事情,把这个伟大的大我在他的类型名字前面?为什么他不拉他的声明,让他的私人离开我的脸?