公共函数之间的耦合度

4
假设我有一个名为do3()的函数,为了让该函数正常工作,需要执行do1()和do2()函数。
然而,do1()和do2()也可能被其他东西所需要(例如do4())。
所有这些函数都是公开的(必须是公开的)。
问题是,我应该如何实现代码?
选项1:
function do3() {
    do2()
    do whatever is needed for do3
}

function do2() {
    do1()
    do whatever is needed for do2
}

function do1() {
    do whatever is needed for do1
}

如果我调用do3()函数,虽然会出现耦合,但我可以确信所有事情都会完成。
选项2
function do3() {
    do whatever is needed for do3
}

function do2() {
    do whatever is needed for do2
}

function do2() {
    do whatever is needed for do1
}

所以当我想调用do3()时,我必须
do1()
do2()
do3()

我觉得第二个选项更好,因为它耦合性较低,但我无法真正解释为什么,更像是一种感觉。如果我使用选项一并且有一天更改do2(),可能会出问题。

然而,使用选项2时,我必须确保每次想要使用do3时都调用do1和do2。

如果有人有更好的想法(选项3?),那就太好了。

谢谢


我认为你可能会发现这本书(在线查看)“基于事件的编程:将事件推向极限”非常有价值。不要只看标题——第一章提供了一种深入的描述和方法,可以将耦合减少/转移为较小形式的耦合行为。 - Paul Sullivan
3个回答

1

耦合是与类而非函数相关的概念。 一个函数应该能够调用同一类中的任何其他函数。 在这里没有耦合问题。

你的第一个选项很好,只要它们都在同一个类中,do3 调用 do2,do2 调用 do1 没有任何问题。

你不应该选择你的第二个选项,因为它会要求你在每个地方重复代码。


耦合就是耦合,当然它与类有着密切的关系——但如果您决定将函数重构为单独的类,会发生什么呢?除此之外,我同意你的看法。 - Adrian K
你好。我的错误,"functions" 实际上是对象中的方法(具体来说是 PHP 对象)。问题在于 do1()、do2() 和 do3() 可能位于不同的类、不同的包中,并具有不同的功能。因此请记住它们位于不同的类中,同时也要记住 do2() 可能会被 do6() 和 do8() 调用。 - Juan Antonio Gomez Moriano

0

假设我有一个名为do3()的函数,为了让这个函数工作,我需要执行函数do1()和do2()。

Juan: 根据你的描述,do3()依赖于do1()和do2()。 依赖图如下:

    - ->do2()
do3()
    - ->do1() 

在这种情况下,您应该选择第二种方法。
如果您的依赖关系图如下:
do3()- ->do2() - -> do1()

ie

  • do3 依赖于 do2

  • do2 依赖于 do1

在这种情况下,您应该选择第一种方法。

--> : shows the dependency.

0
简短的回答是,如果do3()总是必须在调用do2/do1之后进行,并且没有上下文需要调用者在这些调用之间执行某些操作,则确实应该将do2包含在do3中等等。我还要断言,除非doX调用是API或其他难以更改的环境的一部分,否则最好避免分离调用,以防“以防万一”未来出现需要拆分它们的情况(谨慎设计原则)。
更长的答案: 测试某个事物的真实性的一种方法是探索病态案例。将您的第二个选项推向极端基本上意味着完全解开函数组合,直到完全消除函数;毕竟,某个函数正在调用do1() do2() do3(),因此与这些函数“耦合”。
[讲台] 静态依赖关系(耦合)不一定是缺点,尽管这种观念现在很流行。静态依赖关系可能看起来不太灵活,但它们也易于理解、机器可验证和高度可优化。为了说明这一点,请考虑以下假设代码:
person = WebRequest('/GetPerson');
if (person.Phone.AreaCode = '')
    person.Phone.AreaCode = GetAreaCodeFromZip(person.Zip);
...

这样的逻辑往往会因为各种原因被分解成许多部分:

requestService = CreationFactory(IRequest);
requestService.Configure(ConfigurationService.GetConfiguration(requestService));
requestService.SetEntityContext('Person');
response = requestService.Invoke();
entity = EntityService.ProcessEntity(response.Data);
EntityService.RegisterEntityCorrectionService(entity, IAreaCorrectionService);
...
interface IAreaCorrectionService
...
class AreaCorrectionService : IAreaCorrectionService
...
ServiceFactory.Register(AreaCorrectionService...

我的观点很简单,就是“解耦”会带来性能、可读性甚至降低声明性的成本。然而,在考虑控制反转和其他框架时,这一点很少被明确考虑到。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接