单元测试 – 与I的前缀接口?

我目前正在阅读“清洁代码”(Rober Martin)(UncleBob),并且普遍喜欢UncleBob的想法。不过,我有点困惑,当我读到他避免了前缀“IPerson”这样的接口。他说“我不想让我的用户知道我正在交给他们一个接口”。

在TDD /注入视角思考中,我会非常感兴趣地告诉我正在处理接口的课程的“用户”。主要原因是我认为系统的不同“代理”之间的接口合同。在我系统的一个角落工作的代理人,不应该知道另一个代理工作的具体实现;他们应该只交换合同,并期望合同能够在不了解的情况下实现。另一个也是非常重要的原因是,一个界面可以完全模拟,从而使单元测试更容易。你可以嘲笑一个具体的课程有多少限制。

因此,我更喜欢可视化我确实在接口上处理或以接口为参数。但是,由于UncleBob是我们社区的重量级冠军,而且我只是另一个飞行桌面骑师,我想知道我是否缺少某些东西。

我是否坚持我在界面是错误的?

在Java和C#中有一些惯例让我们变得更加舒适;但是这是倒退的。例如,从技术的角度来看,将私有变量置于每个类的顶部的约定是相当愚蠢的。关于班级最重要的事情是公开的方法。最重要的是我们隐藏在隐私权障碍之中的东西,就是实例变量。那么为什么要把它们放在顶端呢?

接口前面的“I”是另一个向后的约定。当您传递对对象的引用时,您应该期望它是一个接口。接口应该是默认的;所以没有什么意义可以做一些额外的事情,像使用一个前缀,宣布你正在做每个人都期待你做的事情。如果我们为传递一个具体类的特殊条件保留了一个特殊标记,那将会更好(但是仍然是错误的)。

使用I的另一个问题是(奇怪的是)我们用它来通信使用接口的实现决定。通常我们不希望实施决定如此响亮,因为这使得他们难以改变。例如,考虑到如果您确定IFoo真的应该是抽象类而不是接口,那么可能会发生什么。你应该改名为Foo还是CFoo,还是ACFoo?

我可以听到你的头部转动的轮子。你在想:“是的,但接口在语言中有一个特殊的地方,所以用一个特殊的命名约定来标记它们是合理的。”确实如此。但整数也有一个特殊的语言,我们不会标记它们(再也没有)。此外,问问自己,为什么界面在语言中有特殊的地位?

Java和C#中的接口背后的整个想法是一个cop-out。语言设计师可以使用抽象类,但是担心实现多重继承的困难。所以他们自己做了一个后台处理。他们发明了一种人造结构(即接口),它将提供多种继承的一些功能,并且它们将正常类限制为单一继承。

这是语言设计师做出的最糟糕的决定之一。他们发明了一个新的和重量级的语法元素,以排除有用的和强大的(虽然有争议的)语言特征。接口没有被发明以实现,它们被发明为禁用。接口是设计师不愿意解决MI的更难问题的语言中的一个黑客。所以当你使用我的前缀,你是一个大的聚光灯在语言史上最大的黑客之一。

下次写这样的函数签名时:

public void myFunction(IFoo foo) {...}

问问自己:“为什么我想知道IFoo的作者使用”界面“这个词呢?对我来说,他使用’interface’或’class’甚至’struct’有什么区别?不是我的,所以为什么他强迫我知道他的事情,把这个伟大的大我在他的类型名字前面?为什么他不拉他的声明,让他的私人离开我的脸?

相关文章

什么是设计模式一套被反复使用、多数人知晓的、经过分类编目...
单一职责原则定义(Single Responsibility Principle,SRP)...
动态代理和CGLib代理分不清吗,看看这篇文章,写的非常好,强...
适配器模式将一个类的接口转换成客户期望的另一个接口,使得...
策略模式定义了一系列算法族,并封装在类中,它们之间可以互...
设计模式讲的是如何编写可扩展、可维护、可读的高质量代码,...