8

我试图将我的 DAL 与我的业务层分开,并且在这样做时,我决定避开任何 ActiveRecord 方法并采用 DataMapper 方法。换句话说,我的域对象不会处理自己的持久化。这样做,我似乎在侵犯“贫血域模型”反模式。例如,我的程序中的一个实体是一个组织。

一个组织可以这样表示:

class Organization {
    private $orgId;
    private $orgName;

    // getters and setters
}

所以基本上这个组织除了充当一些数据的“包”(正如 Martin Fowler 所说)之外什么都不做。在 PHP 世界中,它只不过是一个美化的数组。与之相关的行为为零。

而在程序中的行为,我一直坚持“服务级别”类,比如 OrganizationService,它主要充当这些对象和 DAL 之间的中介。

除了 PHP 的潜在扩展问题(我确实有其他原因为什么我坚持在这些对象中“装袋”我的数据),这种方法完全不可行吗?

在这些情况下,您如何处理您的领域模型?也许一个组织一开始就不属于我的领域?

4

4 回答 4

6

好吧,一开始似乎是这样,但是当您更多地重构代码时,您将获得组织类的一些行为......

我现在可能想到的一个例子是,如果您有人员(员工),您可能希望将他们与组织相关联。因此,您可能有一个方法AssociateEmployee(User employee)可以在您的组织类中找到它的位置。

或者您可以更改公司的位置,而不是分三步设置地址,城市,州等参数,您可以添加ChangeLocation(Street, City, State)方法..

一步一步来,当你在 BL/service 层遇到一些看起来应该属于域的代码时,将它下移到域中。如果您阅读 Fowler,当您在代码中看到它时,您很快就会明白。

于 2009-06-19T17:40:04.077 回答
2

现在可能只是贫血?

例如,有一次我正在开发一个会议/会议注册网站。它始于一次会议。

还有一个会议课,只有一个实例,但是第二年我们召开了会议,它被扩大了,并且增加了新的属性(举行两次背靠背会议),所以显然它还没有完全开发,因为我们随后添加了可能包含多个会议的会议组。

所以我认为重要的是要记住域会随着时间而变化,并且您的模型最终可能会被重构,因此即使您可能认为它乏善可陈,它也可能有点过于前瞻性(就像您的组织类将开始获取一些设置、规则或偏好等)。

于 2009-06-19T17:36:57.903 回答
2

您可能还会考虑,如果您没有很多业务规则,或者域不是那么复杂,那么 DDD 可能对您来说开销太大。DDD 是大型复杂域的出色解决方案,但如果您只是将数据输入、数据输出,则会产生大量开销和复杂性。DDD 更难设计并且固有地增加了复杂性,因此为了证明它的合理性,问题域的复杂性应该超过它。

这就是我要添加到 zappan 和 Epitka 的全部内容。

于 2009-06-19T18:01:54.173 回答
1

你的实体不是贫血的,因为你正在承担一开始就不应该存在的责任。持久化和获取实体是存储库的责任。实际上,您的行为应该在您的实体中而不是在服务层中。但是,解释去向远非简单的答案。Eric Evans 的 DDD 是一个很好的起点。

于 2009-06-19T17:37:20.290 回答