Architecture 谁应该负责调用一个方法?

Architecture 谁应该负责调用一个方法?,architecture,solid-principles,design-principles,responsibility,grasp,Architecture,Solid Principles,Design Principles,Responsibility,Grasp,如果我有一个复杂的任务要解决,我有时会遇到这样的情况:我有一个方法来控制执行。由于空检查、if语句、调用在类型之间映射的方法等等,这个方法可能会变得非常长,我很难让它变得更简单 例1 public class A public string MethodA(string stringA) { var fooResult = _fooService.fooMethod(stringA); if(fooResult) var barResult = _barService.

如果我有一个复杂的任务要解决,我有时会遇到这样的情况:我有一个方法来控制执行。由于空检查、if语句、调用在类型之间映射的方法等等,这个方法可能会变得非常长,我很难让它变得更简单

例1

public class A
public string MethodA(string stringA)
{
    var fooResult = _fooService.fooMethod(stringA);

    if(fooResult)
    var barResult = _barService.barMethod(fooResult);

    if(barResult)
    // And so on..

    return someResult;
}
我可以链接方法调用,这使得第一个方法更简单。但是这使得fooMethod依赖于_barService,而barMethod依赖于_someService等等

示例2(与上面相同,但使用链式方法调用)

我应该如何构造代码?当涉及到哪个方法负责调用另一个方法时,我应该如何思考

换句话说,我应该这样做:

class A
{
  Execute()
  {
    A();
    B();
    C();
  }

  method A()
  {
  ...
  }

  method B()
  {
  ...
  }

  method C()
  {
  ...
  }
}
class B
{
  Execute()
  {
    A();
  }

  method A()
  {
    B();
  }

  method B()
  {
    C();
  }

  method C()
  {
  ...
  }
}
或者像这样:

class A
{
  Execute()
  {
    A();
    B();
    C();
  }

  method A()
  {
  ...
  }

  method B()
  {
  ...
  }

  method C()
  {
  ...
  }
}
class B
{
  Execute()
  {
    A();
  }

  method A()
  {
    B();
  }

  method B()
  {
    C();
  }

  method C()
  {
  ...
  }
}

对于您的所有任务,没有通用的决策。基本上,你应该努力把你的方法写得简短,并实现一个任务。正确的命名方法将帮助您做到这一点(似乎这是您的问题)。例如,避免使用诸如
ExampleClass.DoWork()
ExampleClass.ManageObject(object)
之类的名称,因为它们不精确,并且会导致复杂而冗长的实现

通常,前两个示例的“串行”版本更为可取,因为它更易于阅读,
A()
B()
C()
可能有更简单的实现,并且更容易正确命名它们

有关更具体的建议,您可以在中发布代码。

视情况而定

如果阶段定义良好,在大多数情况下按顺序调用它们会更方便

然而,如果示例B定义得很好,但A和C实际上只是依赖于B的作业的开始和结束,因此A或C本身都没有多大意义,很难命名/描述或评估它们是否成功,那么在这种情况下,将A和C结合在一个调用B的方法中会更有意义。 将方法分开以便每个方法都执行特定的任务是很好的,但是如果部分任务本身没有多大意义,那么应该避免将事情分开,使它们只执行任务的一部分

你应该考虑如何测试代码——一个设计对另一个设计更容易。

考虑如何维护代码。这是最容易理解代码最重要的地方,但也要考虑一个阶段是否需要编辑来修复bug或增强功能性;哪种设计可以让您以最少的工作量完成这项工作,以及对其他代码的副作用,以及对不应该真正受到影响的领域的相关重新测试

想一想将来是否需要改变其中一个步骤——根据某些输入或设置调用B的替代版本

考虑可重用性。如果A调用B,在不想同时调用B的情况下,您不能重用A,在其他设计中,您可以重用A

他们是否总是需要按这个顺序调用-是否有余地通过并行调用B和C来优化速度(从B调用C不允许这样)

如果B失败了,你是否仍然尝试调用C(我想大多数人会说不是,因为这更可能是真的,但这确实取决于真正的问题是什么)单独调用通常比链接更容易

为了支持从A调用B,您只需要在接口中公开A,并且(如果您选择的语言允许),您可以将B和C设置为私有。这样,确保B只从A调用就容易多了,因此B可以避免测试某些初始条件是否正确,而仅仅依赖A完成了它的工作


当然,上述问题更多的是一组问题而不是答案,这是因为根据您的实际任务,这两种设计可能都是正确的,但希望上述考虑因素能帮助您做出决定。

在第二个示例中,不清楚您在努力做什么。大多数情况下,您应该关注最小化类依赖关系,而不是方法(阅读松耦合)@Megamozg我编辑了这个问题,希望能让它更清楚。示例1和示例2以不同的方式实现相同的结果,但依赖项最终位于不同的位置。您喜欢示例1还是示例2?如果您更喜欢示例1,那么您如何管理该方法变得很长,并且做了不止一件事?