【问题标题】:How to prevent a God model class in an MVC architecture?如何防止 MVC 架构中出现上帝模型类?
【发布时间】:2021-01-04 20:51:42
【问题描述】:

如何防止他们的模型类变得太大或依赖于不直接相关的对象?


示例

想象一个用户注册表单,一旦成功注册,用户会收到一封电子邮件以验证他们的电子邮件地址。

示例代码 1

免责声明 - 这是演示代码

// route.js

app.post('/register', (req, res) => {
  container.get('UserController').postRegisterUser(req, res);
});

选项 1 - 在 User 模型中添加 emailSender 依赖项

// userController.js

class UserController {
  public constructor(model) {
    this.model = model;
  }

  public postRegisterUser(req, res) {
    const {email, password, repeatPassword} = req.body;
    const user = this.model.registerUser({email, password, repeatPassword});
    return res.render('/', user);
  }
}
// UserModel.ts

class UserModel {
  constructor(repository, validator, emailSender) {
    this.repository = repository;
    this.validator = validator;
    this.emailSender = emailSender;  // <--- emailSender injected in to model
  }

  public registerUser(user) {
    if (this.validator.isValid(user)) {
      this.repository.save(user);

      this.emailSender.sendVerificationEmail(user.email); // <---- emailSender called here

      return user;
    }
  }
}

选项 2 - 在控制器中添加 emailSender 依赖项

// userController.js

class UserController {
  public constructor(model, emailSender) {
    this.model = model;
    this.emailSender = emailSender;  // <--- Injected in constructor
  }

  public postRegisterUser(req, res) {
    const {email, password, repeatPassword} = req.body;
    const user = this.model.registerUser({email, password, repeatPassword});

    this.emailSender.sendVerificationEmail(email); // <--- emailSender called here

    return res.render('/', user);
  }
}
// UserModel.ts

// no EmailSender injected
class UserModel {
  constructor(repository, validator) {
    this.repository = repository;
    this.validator = validator;
  }

  public registerUser(user) {
    if (this.validator.isValid(user)) {
      this.repository.save(user);
      return user;
    }
  }
}

当涉及其他系统时,可以看到这些依赖关系会变得有多大——例如将数据发送到 S3 存储桶、生成 csv 文件等。理想情况下,我不希望我的控制器或模型具有这些依赖关系,但是那么他们去哪里了呢?

我认为理想的解决方案介于上述两个选项之间。我只是不知道如何实现我的网络应用程序。

【问题讨论】:

    标签: node.js model-view-controller dependency-injection architecture software-design


    【解决方案1】:

    您可以构建另一个组件UserProcessorUserRegistrationProcessor,其中包含对其他服务的所有外部调用,并将该组件注入UserController

    【讨论】:

    • 这是一个不错的选择,谢谢。也许构造函数可以接收processorFactory,而不是将它传递给控制器​​可能依赖的每个处理器。
    猜你喜欢
    • 2010-11-04
    • 1970-01-01
    • 2019-11-26
    • 1970-01-01
    • 2011-03-10
    • 1970-01-01
    • 2016-12-28
    • 2014-07-19
    • 1970-01-01
    相关资源
    最近更新 更多