如何消除方法的副作用?

时间:2019-06-18 14:37:18

标签: coding-style solid-principles code-cleanup side-effects clean-architecture

编写代码时,我会尽量小心SOLID和简洁代码原则。当我查看自己的函数时,我认为我会遇到副作用错误。

例如,假设我在Web服务中具有逻辑。当我触发一个方法时,它必须从另一个服务获取所有数据并将它们插入数据库。我的代表性方法如下。

   //when I call the method, process starts
    public void TriggerProcess()
    {
       GetInformationsFromService();
    }

    public void GetInformationsFromService()
    {
       var informations = exampleService.GetInformations();

       InsertInformations(informations);
    }

    public void InsertInformations(informations)
    {
       insertThemToDb(informations);
    }

当我编写上述代码时,我陷入了副作用错误。如果有人只想在服务中使用GetInformationsFromService()方法,则不应插入数据。

但是,如果我调用如下方法。

  public void TriggerProcess()
    {
       var informations = GetInformationsFromService();
       InsertInformations(informations);
    }

总是有很多方法,例如链方法,其目的之一是按正确的顺序调用方法,并且总是有中间方法 触发方法和负责任的方法之间的层。如果生意变大,我想这似乎很奇怪。

  public void RepresentativeMethod()
     {
        method1();
        method2();
        method3();
        //...
     }

如何避免副作用?我可以使用哪种模式来实现良好的实现?

1 个答案:

答案 0 :(得分:1)

从另一个服务的数据更新/插入数据库中的数据,仅查看数据是两个不同的用例/过程。不要尝试重用GetInformationsFromService(),因为它有不同的用途。实际上,您必须将其重命名为SyncInformation()之类,然后您将使用另一种称为GetInformation()的方法来查看数据。

这是您可以做的,消除TriggerProcess(),因为SyncInformation()已经是一个过程,只需直接调用它即可:

此用例/过程也应包含在域层中:

同步信息用例:

public void SyncInformation() {
  var informations = exampleService.GetInformations();

  informationRepository.insertInformation(informations);
}

获取信息用例:

public List<Information> GetInformation() {
  return exampleService.getInformation();
}

获取和保存数据应在您的数据层中:

ExampleService:

public List<Information> getInformation() {
  // logic to fetch from another service, eg: API
}

InformationRepository:

public void insertInformation(informations)
{
   // insert to database logic
}

在这里,我们正在遵循关注点分离,因为我们将其分为两层:域和数据。 域层处理所有应用程序/业务逻辑,例如有关如何同步信息的步骤。 它知道何时保存,但不知道如何保存数据层 知道如何读取和保存数据,但是它不知道何时何时发生