谁应该负责调用方法?

Who should be responsible for calling a method?

如果我有一项复杂的任务要解决,我有时会遇到一种情况,即我只有一种方法可以控制执行。由于 null 检查、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(与上面相同,但使用链式方法调用)

public class B
public string MethodB(string stringB)
{
    return _fooService.fooMethod(stringB);
}

public class Foo
public string fooMethod(string stringB)
{
    return _barService.barMethod(stringB);
}

public class Bar
public string barMethod(string fooString)
{
    return _someService.someMethod(fooString);
    // And so on...
}

我应该如何构建我的代码?哪个方法负责调用另一个方法,我应该怎么想?

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

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) 这样的名称,因为它们不准确并且会导致复杂而漫长的实现。

通常,您最后两个示例的 "serial" 版本更可取,因为它更易于阅读,并且 A()B()C() 可能有更简单的实现, 正确命名它们会更容易。

如需更具体的建议,您可以 post 您在 Code Review 中的代码。

视情况而定。

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

然而,如果例如 B 定义明确,但 A 和 C 实际上只是依赖于 B 的工作的开始和结束,那么 A 或 C 本身都没有多大意义并且很难 name/describe 或评估它们是否成功,那么在这种情况下,将 A 和 C 组合在一个调用 B 的方法中更有意义。 将方法分开以便每个方法都完成特定任务是好的,但是如果部分任务本身没有太大意义,你应该避免将事情分开到它们只完成部分任务的程度。

您应该考虑如何测试代码 - 一种设计是否比另一种设计更容易。

考虑您将如何维护代码。这是易于理解代码最重要的地方,但也要考虑某个阶段是否需要编辑以修复错误或增强功能;哪种设计可以让您以最少的努力做到这一点,并且对其他代码产生副作用以及对不应该真正受到影响的区域进行相关的重新测试?

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

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

他们是否总是需要按此顺序调用 - 是否可以通过并行调用 B 和 C 来优化速度(从 B 调用 C 不允许这样做)。

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

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

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