复杂过程单一职责原则

Single responsability principle on complex process

当我必须保证的过程非常复杂时,我总是对如何保证单一责任原则有疑问。

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

假设我有一个进程 ProcessA,它由 4 个任务组成 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
  });
}

选项 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();
  }
}

如果任务本身由多个作业组成,这个问题对我来说会更加复杂:FirstJobA1SecondJobA1ThirdJobA1 ...

如何在代码结构上处理这些复杂层以尊重单一职责原则一直是我的难题。任何见解都会有很大帮助!

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

因此,每个任务都有单独的“服务”实现很好, 然后是协调整个过程的“聚合”服务:

service TaskA;
service TaskB;
service TaskN;

service Process{
    TaskA::run();
    TaskB::run();
    ...
    TaskN::run();
}

任务中的更改不应影响不相关的任务。此外,改变了 进程不应影响子任务。这与 Common Closure 有关 原则 (CCP) 其中指出:

The classes in a component should be closed together against the same kind of changes. A change that affects a component affects all the classes in that component and no other components.

或更通俗地说:

gather into components those classes that change for the same reasons and at the same times

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

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