这个业务逻辑在哪里?

时间:2013-07-05 04:36:12

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

我正在构建MVC应用程序,而'M'层包含服务层,域模型层和映射器层。

我的域模型中的逻辑非常复杂。例如,组织有许多员工。当我想修改Organistion / Employee的某些方面时,例如他们的工资水平,我需要查阅Organization对象,User对象和连接这两者的Employee对象。一般来说,我一直把这些责任放在作曲对象上(在本例中是组织),这样做很好。

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

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

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

我怀疑我需要停止推断并将逻辑放在服务层中。你觉得怎么样?

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

2 个答案:

答案 0 :(得分:1)

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

验证

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

  • 数据验证

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

  • 业务规则验证

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

Isnull / IsRequired Validation

小心 isnull / isrequired验证。它既可以是数据验证(例如员工也不能具有空ID,等等),或者业务规则验证(例如员工必须有一个主管)。如果它遵循业务规则,则必须将其放在服务层中,因为我之前解释了状态验证。

哪个层负责创建对象?

所有图层都可以创建对象。您只需要确保所有进程在进入数据访问之前首先访问服务层。如果某个特定物体有一个复杂的逻辑来创建(例如汽车需要引擎,车轮,齿轮,制动器等),那么构建器模式可能会满足您的需求。

答案 1 :(得分:-1)

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

正如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

同样,如果用户正在创建员工 你会这样做,但验证将与用户有关。

我不知道这种模式是否适合您的域名。此外,我作为一个例子展示的内容非常简单,但原则仍然存在。希望这有帮助!