【问题标题】:Where to put this business logic?把这个业务逻辑放在哪里?
【发布时间】:2013-07-05 04:36:12
【问题描述】:

我正在构建一个 MVC 应用程序,“M”层由服务层、域模型层和映射器层组成。

我的领域模型中的逻辑非常复杂。例如,一个组织有很多员工。当我想修改组织/员工的某些方面,例如他们的工资水平时,我需要查阅组织对象、用户对象和连接两者的员工对象。一般来说,我一直将这些职责放在组成对象(在本例中是组织)上,这很好。

我正在努力解决的一个问题与创建新实体有关。具体来说,当存在管理新实体创建的条件/规则时,它们应该存在于服务层还是域层?

在我看来,最可靠的选择是将逻辑放在域模型层中,但是我的域对象似乎“不那么纯粹”。例如,一个 Employee 对象就是一个 Employee 对象,不管它是谁创建的。但是,如果我创建 Employee 实体的规则取决于创建者是谁,我需要将创建者注入到 Employee 对象中。 (我创建 Employee 对象的规则取决于创建它的组织管理员还是任何旧用户)。

将创建规则放在服务层中感觉更自然,但这会引发两个问题。首先,我需要绝对确定所有对域模型的访问都是通过该服务层进行的。 (这并不是什么大问题。)更重要的是,我的业务逻辑现在分散在两层中,并且存在更大的混乱可能性。

我怀疑我需要停止推诿并将逻辑放在服务层中。你怎么看?

仅供参考,我正在使用 PHP,Zend 框架和 jQuery/javascript 前端。

【问题讨论】:

  • mmmh,您的创建问题听起来像工厂,但如果您有更复杂的逻辑,您可能希望将其放入服务中。我绝对赞成将服务添加到域对象中,因为(据我了解)您正在触摸多个对象。

标签: design-patterns domain-driven-design domain-model


【解决方案1】:

这个答案不是 PHP 特定的(我缺乏 PHP 面向对象的经验)。

验证

验证实际上有非常广泛的定义。可以是:

  • 数据验证

    这种类型的验证通常关注数据类型、数据长度、格式等。通常对应于数据库模式。这种验证放在领域模型是安全的,可以放在服务层。

  • 业务规则验证

    这种类型的验证遵循业务规则。它通常是验证一些业务规则,例如总量不能低于零,年龄不能减等。这个最好放在服务层。仅仅因为一个对象可以处于不同的状态并且具有不同的验证,例如当文章处于草稿状态时您可能有空标题,但在发布状态时则不会。

Isnull / IsRequired 验证

当心 isnull / isrequired 验证。它可以是数据验证(例如员工不得有空 ID 等),也可以是业务规则验证(例如员工必须有一个主管)。如果是遵循业务规则,就必须放在服务层,因为我之前讲过的状态验证。

哪一层负责创建对象?

所有层都可以创建对象。您只需要确保所有进程都首先访问服务层,然后再进行数据访问。如果特定对象有一些复杂的逻辑要创建(例如汽车需要引擎、车轮、齿轮、制动器等),那么构建器模式可能会满足您的需求。

【讨论】:

  • 谢谢 Fendy,我会暂时搁置一下,看看是否有其他答案浮出水面,但我确实喜欢你的解释。您能否指出有关此主题的任何其他资源/链接?
  • 我没有有效的来源/参考资料,但是我发现了一些讨论这方面的文章,例如 abdullin.com/journal/2010/4/14/…ayende.com/blog/2278/…
【解决方案2】:

我认为业务规则应该是领域层的一部分。

正如 ZeissS 所建议的,工厂似乎适合在域层中使用。或者代替工厂, 您可以在 Employee 类本身上有验证方法。 创建 Employee 的域对象执行它的验证并抛出异常 如果有错误。 这样您就可以将验证者与正在完成的工作区分开来。

为了说明,我将工厂归入 Employee 类:

Organization.createEmployee( employee input fields...) {
Employee employee = new Employee();
employee.setfirstName(firstName);
employee.setLastName(firstName);

...
then 
employee.validatePosition();
employee.validatePayRate(); //throw exception if error

类似地,如果用户正在创建员工 你会做同样的事情,但验证将与用户有关。

我不知道这种模式是否适合您的领域。此外,我作为示例显示的内容非常简化,但原理仍然成立。希望这会有所帮助!

【讨论】:

  • 您不应该将实体置于无效状态。这意味着没有 validate() 方法,没有 setSomething() 方法,只有执行业务操作和保护不变量的有意义的方法。你的例子是一个贫血的领域模型。
猜你喜欢
  • 2013-09-04
  • 1970-01-01
  • 1970-01-01
  • 2011-08-02
  • 2011-08-02
  • 1970-01-01
  • 2013-06-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多