如果您听其他语言社区(例如Python或Ruby),则Java开发人员似乎倾向于过度设计。
也许他们只是嫉妒我们的高级平台(眨眼),也许有一些非常微小的原因让他们相信。我相信是这样。我通过进行代码审查意识到了这一点,这很有趣,尽管我可能会在编写代码时过度设计自己。但是我正在努力。
当然,您是一个“简单”的开发人员,只有架构师才能设计,所以只有他们才能承担过度工程的责任,不是吗?恐怕并非如此:开发人员一直都在这样做。在本文中,我将重点介绍我在评论中评论过很多的一种症状,但也可以将其扩展到许多其他症状。
我在职业生涯的早期就曾被教导要设计我的班级层次结构,使其尽可能地可扩展。它转换为由具体类实现的父接口。有时,它们之间甚至可能有一个抽象类。它看起来像下面的图: 图片标题
看起来很棒,它构成了可扩展的层次结构,并且实现了接口范式的编程。
例如,Spring框架在其整个软件包中都大量使用此设计。一个很好的例子是ViewResolver接口,它具有丰富的子级层次结构和许多不同的实现类。例如InternalResourceViewResolver和VelocityLayoutViewResolver等。在框架的不同部分中还存在其他示例(bean注册表,上下文等)。
但是,请注意有关Spring的一些重要事实:
回到我们当前的项目-假设是一个常规的Web应用程序。找到定义的接口之一。从这一点出发,很容易找到其子实现。在大多数情况下,只有一个,并且以Default为前缀(或者以Impl作为后缀)。同样,在大多数情况下,该接口位于xyz包中,而实现位于xyzimpl中。人们可能会对这种完全缺乏想象力的东西感到好奇。嗯,很难为实现提供一个相关的名称,因为它和接口之间没有语义上的区别,即前者没有专门化后者。唯一可能的结论是该接口不是必需的!
一些架构师可能会争辩说,即使现在没有用了,抽象也可能在以后有用。但是,仅由于在将来可能变得有用而添加不必要的代码只会降低代码库的信噪比-毫无理由地妨碍了可读性。此外,需要创建,测试和维护这些额外的代码,因此增加了成本和浪费。这与“足够”实现目标的敏捷方法相反。最后,如果(且仅当)需要出现时,只需更改应用程序的代码即可很容易地引入父接口。毫无疑问,得益于任何值得称呼的IDE的重构功能。
如果有人故意设计上述方法以为假设的未来做准备,那么我将上述方法视为过度工程,而如果仅仅因为它总是这样进行,则将其视为“货运崇拜”。
无用的接口只是过度工程的一个简单示例。还有更多。我很高兴阅读您发现的(或练习过的)那些。
原文链接:http://codingdict.com