不良设计的标准
生活很简单:通常,要聪明,你只需要不做傻事。这也适用于软件开发:在大多数情况下,要想把一件事做好,你只需要不把它做得不好。
大多数程序员都有过设计糟糕的系统部分的经验。但更可悲的是,你们中的大多数人都会有悲伤的经历,意识到自己是这样一个系统的作者。我们想要最好的,但结果一如既往。
大多数开发人员并不渴望糟糕的架构,对于许多系统来说,他们开始说它的架构很糟糕。为什么会这样?架构设计是从一开始就不好,还是随着时间的推移变得不好?
这个问题的根源是缺乏“坏”设计的定义。
在我看来,理解设计质量及其“衰退”的原因是任何程序员最重要的素质。与大多数其他情况一样,最主要的是确定问题,解决问题将是技术问题。
“不良设计”的定义
如果你决定在其他程序员面前吹嘘你的代码,你很可能会得到嘲笑:“这是谁做的?”,“为什么会这样?” 和“我会做不同的事情。” 这种情况经常发生。
所有人都是不同的,但你仍然为你的程序员伙伴编写代码,所以在开发每个功能的过程中,当其他人看你的代码时,你总是需要一个审查阶段。
但即使很多事情可以用不同的方式完成,也有一套所有开发人员都会同意的标准。任何满足其要求但仍表现出一个(或多个)特征的代码都是糟糕的设计。
糟糕的设计:
- 很难更改,因为任何更改都会影响系统的太多其他部分。(刚性,刚度)。
- 进行更改时,系统的其他部分会意外中断。(脆弱性,脆弱性)。
- 代码很难在另一个应用程序中重用,因为很难将它从当前应用程序中取出。(不动性,不动性)。
有趣的是,几乎不可能找到一个不包含任何这些特性(即灵活、可靠和可重用)的系统,满足要求,同时它的设计很糟糕.
因此,我们可以通过这三个特征来明确地判断一个设计是“坏”还是“好”。
“不良设计”的成因
是什么让设计变得僵硬、脆弱和不可移动?模块的刚性相互依赖。
如果设计不能轻易改变,那么它就是死板的。这种僵化是由于对编织系统中一段代码的单一更改会导致相关模块的级联更改。当一个人在编写代码时,总是会发生这种情况。
这立即使整个商业开发过程复杂化:当设计人员或开发人员无法预测级联更改的数量时,就无法估计这种更改的影响。因此,他们试图无限期推迟此类更改。
而这反过来又使变革的成本变得不可预测。面对这样的不确定性,管理者不愿意做出改变,所以设计正式变得死板。
在某个时候,您的项目会越过“事件视界”,注定会落入僵化架构的“黑洞”。
脆弱性是系统在一次更改后在多个地方崩溃的趋势。通常新问题发生在概念上与变更地点无关的地方。这种脆弱性严重破坏了对系统设计和维护的信心。
当没有私有方法时,通常就是这种情况。将所有方法公开就足够了,你注定会出现脆弱的架构。封装有助于在微观层面处理这个问题。但在宏观层面,你需要一个模块化的架构。
当项目具有脆弱的架构时,开发人员无法保证产品的质量。
应用程序一部分的简单更改会导致其他不相关部分出现错误。纠正这些错误会导致更多的问题,护送过程变成追自己尾巴的名犬。
当系统的必要部分与其他不需要的细节紧密相关时,设计就是固定的。太多他们自己的代码,他们自己独特的方法和解决方案。
您还记得 JUL 记录器吗,它的开发人员无缘无故地想出了自己的日志记录级别?仅此而已。
要让设计人员了解重用现有设计有多么容易,只需考虑在新应用程序中使用它会有多容易。
如果设计是紧密耦合的,那么将系统的必需部分与不必要的细节分开所需的工作量会让这位设计师感到震惊。在大多数情况下,这样的设计是不可重用的,因为分离它的成本超过了从头开始开发它的成本。
关联
一切都变了,但一切都保持不变。(中国谚语)
上面提出了很好的问题。脆弱和僵硬的系统有哪些危险?是的,因为管理这样一个项目的过程变得不可预测和不可控制。而且价格天价。
如果经理不知道实际需要多少时间,他怎么能同意或不同意添加某些功能?如果无法充分估计任务实施的时间和复杂性,如何确定任务的优先级?
当我们支付费用时,开发人员如何还清相同的技术债务,而在我们收取费用之前我们无法了解我们将收取多少费用?
代码重用或测试的问题也非常相关。单元测试不仅用于测试关于被测单元的一些假设,而且可以确定其内聚程度,并可以作为重用的指标。
这是 Bob Martin 对这个案例的引用:“为了重用你的代码,你需要使重用它的努力低于从头开始开发的成本。 ” 否则,根本就没有人会理会这件事情。
设计原则和模式的使用服务于一个目的——让设计变得更好。如果它们的使用没有给您带来任何好处(反之亦然,违反了“良好设计”的原则),那么您的温室中的某些东西是不对的,也许该工具已开始用于其他目的。
GO TO FULL VERSION