对于某些开发人员来说,宽松的耦合是设计精良的软件的圣杯。当面对可能在可预见的将来发生的变化或避免代码重复时,它使代码更加灵活时,这肯定是一件好事。

另一方面,努力松散的夫妇组成部分增加了程序中的间接量,从而增加了其复杂性,通常使其更难理解,并且通常使其效率降低。

您是否考虑过关注松散的耦合,而无需任何用例以散布的耦合(例如避免了代码重复或计划在可预见的将来可能发生的更改)是一个反模式?松散的耦合可以落在Yagni的雨伞之下吗?

有帮助吗?

解决方案

有些。

有时,即使您没有特定的要求要求将某些模块解耦,有时甚至没有太多努力就可以散发出松散的耦合。低悬垂的水果。

另一方面,对荒谬的变化进行过度工程将是很多不必要的复杂性和精力。正如您所说,Yagni击中了它。

其他提示

是编程实践 X 是好是坏? 显然,答案是 总是 “这取决于。”

如果您正在查看代码,想知道可以注入什么“模式”,那么您就做错了。

如果您要构建软件,以使无关的对象不会彼此摆弄,那么您就做对了。

如果您正在“工程”解决方案,以使其可以无限扩展和更改,那么实际上您会使它更加复杂。

我认为归根结底,您剩下的单一事实是:将物体解耦或多或少是复杂的吗?如果夫妇不那么复杂,那是正确的解决方案。如果将它们解散不那么复杂,那就是正确的解决方案。

(我目前正在用非常小的代码库工作,该代码库以一种非常复杂的方式完成了一项简单的工作,而使它如此复杂的部分原因是对原始术语缺乏对“耦合”和“凝聚”一词的理解。开发人员。)

我认为您在这里得到的是 凝聚. 。此代码有良好的目的吗?我可以内化这个目的并了解正在发生的事情的“大图”?

它可能导致难以遵循的代码,这不仅是因为还有更多的源文件(假设这些是单独的类),而且因为没有单个类似乎有目的。

从敏捷的角度来看,我可能会建议这种松散的耦合将是一个反图案。没有凝聚力,甚至没有用例,就无法编写明智的单元测试,也无法验证代码的目的。现在,敏捷代码可能会导致松散的耦合,例如,当使用测试驱动的开发时。但是,如果创建正确的测试,以正确的顺序创建,那么它很可能既有良好的凝聚力又有松散的耦合。而且您只谈论何时显然没有凝聚力。

再次从敏捷的角度来看,您不希望这种人为的间接水平,因为它在可能不需要的事情上浪费了努力。当需要时,重构要容易得多。

总体而言,您需要在模块中高耦合,并在它们之间进行松散的耦合。没有高耦合,您可能没有凝聚力。

对于这样的大多数问题,答案是“取决于”。总的来说,如果我能以逻辑上的方式进行设计,以有意义的方式进行逻辑上的耦合,而没有这样做的主要开销,我会的。在我看来,避免代码中不必要的耦合是一个完全值得的设计目标。

一旦涉及到逻辑上应该紧密耦合组件的情况,我将在开始分解它们之前寻找一个引人注目的论点。

我想我与大多数这样的实践的原则是惯性之一。我有一个想法,我想如何工作,如果我能以这种方式这样做,而没有使生活更艰难。如果这样做会使开发变得更加困难,但是维护和将来的工作更加容易,我将尝试猜测代码一生中是否会更多地工作并将其用作我的指南。否则,这将是值得进行的故意设计点。

简单的答案是,正确完成后,耦合松散。

如果遵循一个功能的原理,则遵循一个目的,那么遵循正在发生的事情应该很容易。另外,散乱的夫妇代码当然会毫不费力地遵循。

简单的设计规则:1。除非您要构建外墙界面,否则不要将多个项目的知识构建为单个点(如无处不在,取决于)。 2.一个函数 - 一个目的(该目的可能是多方面的,例如在外墙中)。3。一个模块 - 一组清晰的相互关联的功能 - 一个明确的目的4.如果您不能简单地单位测试,那么它就没有一个简单的目的

所有这些关于以后更容易重构的评论都是大量COD。一旦知识被内置到许多地方,尤其是在分布式系统中,重构成本,推出同步的成本以及几乎所有其他成本都无法考虑到这一点,以至于在大多数情况下,系统最终由于此而最终被丢弃。

如今,关于软件开发的可悲之处在于90%的人开发新系统,没有理解旧系统的能力,并且由于零碎的碎片和零件的持续重构,该系统何时才能达到如此糟糕的健康状态。

如果另一件事永远不会改变,那么一件事与另一件事有多紧密无关紧要。多年来,我发现通常要专注于寻求改变事物改变,寻求稳定性的理由比通过尝试实现最宽松的耦合形式更容易改变的理由更有生产力。脱钩 我发现非常有用,以至于我有时会赞成适度的代码重复来解除软件包。作为一个基本示例,我可以选择使用我的数学库来实现图像库。我没有,只是复制了一些基本的数学功能,这些功能是微不足道的。

现在,我的图像库完全独立于数学库,无论我对我的数学库做了什么样的更改,都不会影响图像库。这首先是稳定性。现在,图像库更加稳定,因为更改的理由越来越少,因为它与任何可能更改的库解耦(除了C标准库除了希望永远不会更改的C标准库)。作为一项奖励,当它只是一个独立的库时,它也很容易部署,不需要吸入其他LIB来构建并使用它。

稳定对我非常有帮助。我喜欢建立一系列经过良好测试的代码,这些代码的理由越来越少,将来改变的理由越来越少。那不是白日梦;自80年代后期以来,我一直在使用C代码,并再次使用,从那时起,它根本没有改变。它肯定是低级的东西,例如以像素为导向和几何相关的代码,而我的许多高级内容变得过时了,但这仍然很有帮助。这几乎总是意味着一个依赖越来越少的事物的库,如果没有外部的话。如果您的软件越来越多地取决于稳定的基础,这些基础很少或根本没有更改的理由,则可靠性会提高。即使在实践中,运动部件的数量要比稳定零件要大得多,也要少得多。知道整个代码库不包含活动部件,这仍然有助于我的理智。

松散的耦合是相同的,但是我经常发现松散的耦合比没有耦合稳定得多。除非您在一个界限界面设计师和客户端不改变主意的团队中工作,否则即使是纯粹的界面,也经常会发现以仍会导致整个代码中级联破裂的方式变化的理由。只有在接口设计比第一次更容易获得正确的情况下,只有将依赖性引导到抽象而不是混凝土可以实现稳定性,这是有用的。我经常发现,由于他们认为应该满足的设计要求,开发人员可能会创造出非常好的(即使不是出色)的实现,但即将在将来发现设计要求完全改变了。如果您向我问大规模代码库试图满足不断变化的要求,那么设计比实施要难得多得多,并且在这种情况下,如果抽象设计是最多的东西,则将抽象设计与具体的实现分开无济于事。容易改变。

因此,我喜欢偏爱稳定性和完整的解耦,以便至少可以自信地说:“这个多年来使用并通过彻底测试确保的小孤立图书馆几乎没有任何可能需要更改的可能性。”不管在外部需要哪种设计更改,它都会给我一点理智。

耦合和稳定性,ECS示例

我也喜欢实体组件系统,它们引入了很多紧密的耦合,因为组件依赖项的系统所有访问并直接操纵原始数据,例如:

enter image description here

此处的所有依赖项都非常紧密,因为组件只是揭示了原始数据。依赖关系并没有流向抽象,而是流向 原始数据 这意味着每个系统都有有关其要求访问的每种组件的最大知识。组件与所有系统访问和篡改原始数据没有功能。但是,由于它是如此平坦,因此很容易理解这样的系统。如果纹理呈螺丝质,那么您立即就知道只有渲染和绘画系统访问纹理组件,并且您可能可以快速排除渲染系统,因为它仅从概念上读取纹理。

同时,一个松散的耦合替代方案可能是:

enter image description here

...所有依赖项都流向抽象功能,而不是数据,而该图中的每一件事都公开了公共接口和功能。在这里,所有依赖关系都可能非常松散。对象甚至可能无法直接依赖对方,并通过纯界面相互交互。仍然很难理解该系统,尤其是如果出现问题,鉴于相互作用的复杂纠结。与EC相比,还会有更多的交互(尽管较松),因为实体必须了解它们汇总的组件,即使他们只知道彼此的抽象公共界面。

另外,如果任何事物都有设计更改,您将获得比ECS更多的级联断裂,并且通常会有更多的设计更改的原因和诱惑,因为每件事都试图提供一个不错的面向对象的界面和抽象。这立即提出了这样一个想法,即每一小事都会试图对设计施加限制和局限性,而这些约束通常是保证设计的改变。功能比原始数据更具限制性,并且必须做出更多的设计假设。

我在实践中发现上述类型的“平面” ECS系统比最轻松耦合的系统更容易推理,而这些系统具有复杂的依赖性依赖性的复杂蜘蛛网,最重要的是,我发现的原因很少。为了使ECS版本需要更改任何现有组件,因为依赖组件没有责任,除了提供系统功能所需的适当数据。比较设计纯的困难 IMotion 接口和具体运动对象实现了提供复杂功能的接口,同时试图通过私人数据和运动组件维护不变性,而动作组件只需要提供与解决问题相关的原始数据,并且不用处理功能。

功能要比数据要难得多得多,这就是为什么我认为通常可选的是将依赖性流向数据的流程。毕竟,那里有多少个向量/矩阵库?他们中有多少使用完全相同的数据表示形式,并且功能方面仅略有不同?尽管存在相同的数据表示,但我们仍然拥有许多相同的数据表示,我们仍然有很多东西,因为我们希望在功能方面存在细微的差异。那里有多少个图像库?其中有多少人以不同且独特的方式代表像素?几乎没有,并且在许多情况下,与数据更加不稳定和倾向于设计变化更加不稳定和容易发生。当然,在某个时候,我们需要功能,但是您可以设计大部分依赖项朝数据的系统,而不是朝着抽象或功能流向数据。这将优先考虑稳定性高于耦合。

我写过的最稳定的功能(自80年代后期以来我一直在使用和重复使用的功能)都是所有依赖原始数据的功能,例如几何功能,它只是接受了一系列的数组浮子和整数,而不是依赖复杂的浮子 Mesh 对象或 IMesh 接口或向量/矩阵乘法,仅取决于 float[] 或者 double[], ,不是一个依赖的人 FancyMatrixObjectWhichWillRequireDesignChangesNextYearAndDeprecateWhatWeUse.

许可以下: CC-BY-SA归因
scroll top