design-patterns - 复杂过程的单一职责原则

标签 design-patterns architecture solid-principles single-responsibility-principle

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

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

假设我有一个进程 ProcessA,它由 4 个任务 TasksA1TasksA2TasksA3 组成, TasksA4

如果我在 Controller 层上暴露了一个端点,例如:POSTMethodProcessA

应该如何编写我的代码才能在我的服务层上遵守单一职责原则?

我看到的选项:

选项1( Controller 必须知道进程):

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 ...

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

最佳答案

一个常见的误解是单一职责原则意味着一个类 (或服务或系统等)应该只做一件事。相反,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

关于design-patterns - 复杂过程的单一职责原则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68995364/

相关文章:

Android MVP - Activity 应该是 View 还是 Presenter?

architecture - RabbitMQ中需要单独的死信交换吗?

ios - 阻止回调或协议(protocol)在 VIPER 中的 DataManager 和交互器之间传递信息?

android - 在带有 Parceler 的 Android 中使用 CLEAN 架构

java - 如何在类之间高效共享函数而不违反里氏替换原则

java - 如何在接口(interface)隔离上实现 SOLID

iphone - Cocoa/Iphone 开发 - 目标/操作机制

c++ - 使用模板实现多态

go - go中的包解耦

c# - 代码比较