第 29 章 耦合 耦合
本作品已使用人工智能进行翻译。欢迎您提供反馈和意见:translation-feedback@oreilly.com
为了准备撰写他们的经典著作《结构化设计》(Structured Design),埃德-尤登(Ed Yourdon)和拉里-康斯坦丁(Larry Constantine)对程序进行了研究,以找出它们之所以如此昂贵的原因。他们注意到,昂贵的程序都有一个共同特点: ,改变一个元素需要改变其他元素。而廉价的程序往往需要进行局部修改。
他们将这种变化感染属性称为 "耦合"。如果改变一个元素就必须改变另一个元素,那么两个元素在特定变化方面就是耦合的。
例如,调用函数与被调用函数的耦合与被调用函数名称的变化有关:
caller()
called()
called() // changing this name requires changing the call site(s) too
... // changing the formatting of the body requires no changes to call sites
这里的第二条评论强调了耦合的一个重要细微差别:我们不能只说两个元素是耦合的。要想说一些有用的东西,我们还必须说与哪些变化相关的耦合。如果两个元素在某个从未发生的变化方面是耦合的,那么它们就不是我们应该关注的耦合。这种耦合就是山顶的巨石,它永远不会滚下来压垮村庄。
分析耦合性不能仅仅通过查看程序的源代码来完成。在判断两个元素是否耦合之前,我们需要知道已经发生和/或可能发生的变化。(作为一个实验,看看哪些文件对在提交中倾向于出现在一起。这些文件就是耦合的)。
耦合决定了软件的成本。由于耦合是如此基本,我尽可能用多种方式来表达和形象化它。数学定义
coupled(E1, E2, Δ) ≡ ΔE1 ⇒ ΔE2
图 29-1展示了这一图像。
图 29-1. 被调用函数与调用函数在名称更改方面的耦合关系
如果耦合只发生在两个元素之间,那么它就不会成为我们的噩梦。相反,耦合有两个特性将其推向中心舞台:
- 1-N
-
一个元素可以与任意数量的其他元素耦合在一起发生变化。
- 级联
-
一旦一种变化从一个要素波及到另一个要素,这种隐含的变化就会引发另一轮变化,而这些变化本身又会引发自身的变化。
1-N问题可以通过工具在一定程度上消除。如果你有一个自动重构工具来更改函数名和所有调用者,那么你就可以只做一次更改。无论你有一个还是一千个调用者,成本都是一样的。(不过,如果你要同时更改一千个调用者,你可能会希望尽快将这一更改全部投入生产)。
级联变化是更大的问题。正如,我们将在下一本书中看到的,变更成本遵循幂律分布。这种分布是由级联变更的成本造成的。您将使用软件设计来降低级联变更的概率和幅度。
随着时间的推移,"耦合 "一词已经失去了意义,它指的是系统中元素之间的任何关系。"这个服务与那个服务耦合"--好吧,但怎么耦合?发生了什么变化?仅仅知道一个服务调用另一个服务是不够的,我们还需要知道一个服务的哪些变化需要另一个服务的变化。
Meilir Page-Jones 在他的《What Every Programmer Should Know About Object-Oriented Design》(Dorset House)一书中用 ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access