我正在构建MVC应用程序,而'M'层包含服务层,域模型层和映射器层。
我的域模型中的逻辑非常复杂。例如,组织有许多员工。当我想修改Organistion / Employee的某些方面时,例如他们的工资水平,我需要查阅Organization对象,User对象和连接这两者的Employee对象。一般来说,我一直把这些责任放在作曲对象上(在本例中是组织),这样做很好。
我正在努力解决的一个问题涉及新实体的创建。具体来说,当存在管理新实体创建的条件/规则时,它们应该存在于服务层还是域层中?
在我看来,最可靠的选择是将逻辑放在域模型层中,但是我的域对象似乎“不那么纯粹”。例如,Employee对象是Employee对象,无论是谁创建它。但是,如果我创建Employee实体的规则取决于创建者是谁,我将需要将创建者注入Employee对象。 (我创建Employee对象的规则因创建它的组织管理员或任何旧用户而异。
将创建规则放在服务层中感觉更自然,但这会引发两个问题。首先,我需要绝对确定所有对域模型的访问都是通过该服务层进行的。 (这不是什么大不了的事。)更重要的是,我的业务逻辑现在分布在两个层面,并且存在更大的混淆可能性。
我怀疑我需要停止推断并将逻辑放在服务层中。你觉得怎么样?
仅供参考,我正在使用PHP,Zend Framework和jQuery / javascript前端。
答案 0 :(得分:1)
这个答案不是特定于PHP的(我缺乏面向对象的PHP经验)。
验证实际上有非常广泛的定义。它可以是:
数据验证
这种类型的验证通常关注数据类型,数据长度,格式等。通常对应于数据库模式。这种验证可以安全地放在域模型中,并且可以放在服务层。
业务规则验证
此类验证遵循业务规则。它通常验证一些业务规则,例如总金额不得低于零,年龄不得减去等等。这最好放在服务层。仅仅因为对象可以处于不同的状态并且具有不同的验证,例如,当文章处于草稿状态时,您可能具有空标题,但是当处于已发布状态时,则可能没有。
小心 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
同样,如果用户正在创建员工 你会这样做,但验证将与用户有关。
我不知道这种模式是否适合您的域名。此外,我作为一个例子展示的内容非常简单,但原则仍然存在。希望这有帮助!