我的代码在哪里?控制器,服务还是型号?

时间:2010-07-20 23:44:47

标签: design-patterns oop architecture

所以我们有一个PHP + Zend Framework + Doctrine 1.2应用程序,它具有以下结构:

控制器 - >行动 - >服务 - >模型

并非所有模型都通过服务进行交互。我们目前的观点是控制器可以直接使用模型,服务可能使用其他服务。

我的问题是:如果您有一个业务逻辑,您使用什么准则来确定实现该逻辑的代码是否应该在模型,控制器或服务层中?我特别感兴趣的是控制器和服务层之间的区别。

以下是我们的开发团队提出的指南,但我对他们的任何反馈/意见非常感兴趣:

  1. 服务和控制器包含 用于捆绑各种组件的逻辑 一起完成一项任务。 这个逻辑可能不在 模型,以避免依赖和制作 该模型更可重用。 这个 逻辑也可能不在模型中 因为我们认为模型应该 避免消耗东西 应用程序堆栈要避免 不必要的依赖(例如: 模型不会消耗服务或 控制器)。
  2. 可以使用代码时使用服务而不是控制器 由多个模块或控制器组成。
  3. 模型应包含尽可能多的逻辑,但要避免 引用特定于应用程序的 功能。通常是一个模型 至少包含验证逻辑。
  4. 对于任何功能,请考虑将其放入模型中 第一。如果有令人信服的话 理由不,考虑服务 (也考虑开销和 维持新服务的目的)。 如果不需要服务而且 代码不会在此重用 应用程序使用控制器。

2 个答案:

答案 0 :(得分:2)

我相信您应该将业务逻辑放在服务层中。这背后的原因是业务逻辑应该是数据结构/模型的一个单独问题。

与大多数情况一样,您经常发现数据结构和业务逻辑紧密交织在一起,因此可能没有足够的分离来证明我的第一个陈述是正确的。但是,我认为这通常指的是代码味道。

在每个实例优化中,您可以将代码移动到性能最佳的位置,但在第一次迭代中,我仍然会将其放置在服务层中。

我同意模型应尽可能包含内向聚焦逻辑,但模型必须是非特定的。业务逻辑是一个用例,它会为您的应用程序使用模型,因此应该是独立的。

答案 1 :(得分:1)

在您的上下文中,我将模型和控制器视为业务逻辑的一部分;定义“什么”事物的模型,控制器定义“如何”访问它们。

服务处于最顶层,可能将业务逻辑暴露给业务逻辑层之外的任何事物。我同意您的意见,服务可能会封装多个特定组件(或更精确的模型)。

  

服务和控制器包含逻辑   用于将各种组件捆绑在一起   完成一项任务。

是的,我也同意你关于避免依赖等的陈述。该模型不应该依赖于任何其他密切相关的模型(Common Closure Principle)。

此外,如果逻辑特定于模型 - 那么它应该去哪里;如果逻辑更通用,它应该放在合适的级别 - 可能是控制器或公共内部实用程序。

  

使用服务而不是控制器   当代码可能被多个使用时   模块或控制器。

我同意。在粒度方面,我会看到服务处于更高的抽象层次 - 你更有可能将服务暴露给外部系统,而不是“内部”控制器。

  

模型应包含尽可能多的逻辑   尽可能避免引用   特定于应用程序的功能   通常模型至少包含   验证逻辑。

它应该只包含适合的逻辑,否则我同意。验证 - 您可以将其删除;模型应该明确包含验证使用的规则,但不一定包含验证本身。我已经看过使用这两种风格,只要你保持一致,我认为没有错误或正确的答案。

  

任何功能   考虑将其放入模型中   第一。如果有令人信服的理由   不要,考虑一项服务(也   考虑开销和目的   维持新服务)。如果是服务   是不希望的,代码不会   在这个应用程序中重用使用a   控制器。

它取决于“功能性”是什么,如果它特定于模型,那么它可能属于模型;如果它对于多个模型是通用的,则它或者属于控制器或业务逻辑中的公共实用程序类。

当我开始写所有这些时,我想围绕你使用的术语的定义放在一边。我还以为我会把它包括在内 - 所以如果我错了就纠正我:)正如你所看到的,我不清楚你的背景中的“行动”是什么意思。

  • 模型:(from Wikipedia - MVC)“模型用于管理信息并在信息发生变化时通知观察者;它也是应用程序运行的数据的特定于域的表示。”在我看来,这意味着属性等 - 而不是方法。
  • 控制器:(from Wikipedia - MVC)“接收输入并通过对模型对象进行调用来启动响应。控制器接受来自用户的输入,并指示模型和视口根据该输入执行操作。”
  • 服务:关于服务是什么有很多不同的意见,我假设在你的上下文中服务是:面向外部的可调用点(在系统层的上下文中),它提供特定问题的特定答案。 (服务通常基于业务概念而非技术概念。)
  • 行动:我不知道你明确指出的是什么。