0

考虑有一个非常复杂的业务需求,在启动操作时需要执行几个业务逻辑步骤。例如,当用户提交请求时,需要执行的步骤是:

  • 验证数据
    • 验证请求是否已经存在
    • 验证用户是否存在
    • 验证用户是否有足够的财务金额来提交请求
    • 验证用户是否可以立即发布请求
    • 验证是否有请求的项目
    • 验证请求的项目是否有效
    • 验证项目没有负金额
    • ...(进一步验证)
  • 将数据存储到存储库
  • 向用户或相关方发送电子邮件
  • ...(也许还有其他步骤要做)

上面的例子可能离真正的业务需求还很远,但考虑到它是,那么我想这个操作将有大约 10 多个服务。

在使用构造函数依赖时,拥有 10 个以上的构造函数应该是一件坏事,所以我认为重构它就可以了。重构设计的一些说明:

ISubmitter(IValidator, IRequestRepository, INotification)
IValidator(IRequestValidator, IItemValidator)
IRequestValidator(IRequestRepository, IUserValidator, IItemExistValidator)
IUserValidator(IUserRepository, IUserFinancialValidator, IUserPublisherValidator)
IItemValidator(IItemRepository, IItemAmountValidator)
... // maybe more

项目金额验证流程从提交者做了4层:ISubmitter->IValidator->IItemValidator->ItemAmountValidator。

我知道就关注点分离而言,我可以轻松获得所需的正确实现(例如:ItemAmountValidation)。但是在调试代码方面,跟踪它使用哪个验证类会不会变得更加困难?由于构造函数注入是在实现中定义而不是在接口中?

考虑最坏的情况,当调试器不是开发人员时,只有最低限度的测试场景,根本没有文档。

4

2 回答 2

2

你说的逻辑属于不同的层,但是需要注入到你的应用层。我要做的是注入执行任务所需的组件,例如执行请求的命令处理程序;一个负责验证输入的验证器,一个处理数据逻辑的存储库,以及一个发送邮件的 Mailer 组件(或服务)。

这一切都是为了将​​职责放在正确的组件中。构造函数注入是一个很好的选择,它在灵活性、可测试性方面为您提供了许多优势,并且使您的代码易于理解。

就调试而言,我不认为您必须做的更多努力应该成为不以模块化方式构建代码的理由。只需设置正确的断点就可以了。

也许http://tinyurl.com/d99w8rl可以给你更多的洞察力。

于 2013-04-22T11:12:36.077 回答
1

但是在调试代码方面,跟踪它使用哪个验证类会不会变得更加困难?由于构造函数注入是在实现中定义而不是在接口中?

是的,它可能会让你在调试时不得不跳过更多的类。但是,这种设计允许测试您的代码(当然使用 TDD),并且在练习 TDD 时,您将不得不比以前少得多的调试代码。

于 2013-04-22T07:59:59.900 回答