Oop 公共职能之间的耦合

Oop 公共职能之间的耦合,oop,architecture,software-design,coupling,Oop,Architecture,Software Design,Coupling,假设我有一个名为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 } f

假设我有一个名为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()
我觉得第二种选择更好,因为它的耦合更少,但是我无法真正解释为什么,它更像一种感觉。我认为如果我使用选项1,有一天我会更改do2(),我可能会遇到问题

但是,对于选项2,我必须确保每次使用do3时都调用do1和do2

如果有人有更好的想法(选项3?),你会很高兴


感谢

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

您的第一个选项很好do3调用do2和do2调用do1没有什么错,只要它们都在同一个类中

您不应该选择您的选项2,因为它要求您在任何地方重复代码。

“假设我有一个名为do3()的函数来实现该函数 要工作,我需要执行函数do1()和do2()

胡安:根据你的描述,do3()依赖于do1()和do2()。 依赖关系图是

    - ->do2()
do3()
    - ->do1() 
在这种情况下,您应该使用第二种方法

--> : shows the dependency.
如果依赖关系图为:

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

  • do3依赖于do2

  • do2依赖于do1

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

--> : shows the dependency.

简单的回答是,如果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...

我的观点很简单,从性能、可读性、甚至降低声明性到“解耦”都是有代价的。在考虑控制反转和其他框架时,很少明确考虑这一点。

耦合就是耦合,当然它与类特别相关,但是如果您决定将函数重构为单独的类,会发生什么?否则我同意你的看法。糟糕的是,“函数”实际上是对象中的方法(更具体地说是php对象)。问题是do1()do2()和do3()可能位于具有不同功能的不同包的不同类中。因此,请记住它们在不同的类中,也请记住do6()和do8()可能会调用do2()。我认为您可能会找到一本书()《基于事件的编程:将事件限制到极限》不要从表面上看这个标题——第一章给出了一个有见地的描述和方法,通过这些描述和方法,可以减少/改变耦合行为的较小形式。