复杂流程的单一责任原则

Aio*_*ion 4 architecture design-patterns single-responsibility-principle solid-principles

当我必须保证的过程相当复杂时,我总是有一个问题,如何保证单一责任原则。

我使用 3 层架构后端:控制器(我的 API 端点)| 服务(单一职责功能)| 数据(访问数据库)

假设我有一个由 4 个任务, , ,ProcessA组成的流程。TasksA1TasksA2TasksA3TasksA4

如果我的控制器层上公开了一个端点,例如:POSTMethodProcessA

应该如何编写我的代码以尊重我的服务层的单一责任原则?

我看到的选项:

选项1(控制器必须知道该过程):

class MyController {
  exports.processA = functions.https.onRequest(req, res) => {
    myservice.doTaskA1(); // single responsability on task1
    myservice.doTaskA2(); // single responsability on task1
    myservice.doTaskA3(); // single responsability on task1
    myservice.doTaskA4(); // single responsability on task1
  });
}

Run Code Online (Sandbox Code Playgroud)

选项 2(服务了解流程并放弃单一责任)

class MyController {
  exports.processA = functions.https.onRequest(req, res) => {
    myservice.doProcessA();
  });
}

//inside the service (the doProcessA method must be in charge of multiples tasks and loose the single responsability principle :
class MyService {
  function doProcessA() {
    this.doTasksA1();
    this.doTasksA2();
    this.doTasksA3();
    this.doTasksA4();
  }
}
Run Code Online (Sandbox Code Playgroud)

如果任务由多个作业组成,这个问题对我来说就更复杂了:FirstJobA1, SecondJobA1, ThirdJobA1...

如何在代码结构上处理这些复杂层以尊重单一责任原则是我一直遇到的问题。

Sve*_*rev 7

一个常见的误解是,这Single Responsibility Principle意味着一个类(或服务或系统等)应该只做一件事。相反,SRP 意味着主题必须有单一的理由进行更改

因此,为每个任务提供单独的“服务”实现,然后使用一个“聚合”服务来编排整个过程是很好的:

service TaskA;
service TaskB;
service TaskN;

service Process{
    TaskA::run();
    TaskB::run();
    ...
    TaskN::run();
}
Run Code Online (Sandbox Code Playgroud)

任务的更改不应影响不相关的任务。此外,流程的更改不应影响子任务。这与共同封闭原则 (CCP)有关,该原则规定:

组件中的类应该针对相同类型的更改关闭在一起。影响组件的更改会影响该组件中的所有类,但不会影响其他组件。

或者更非正式地:

将那些因相同原因同时发生变化的类聚集到组件中

这意味着,如果 的更改TaskA将不可避免地导致 的更改TaskB,那么也许这两个任务应该是一个任务,而不是两个任务。

将其递归地应用于您的子任务:FirstJobA1...FirstJobA-N