domain-driven-design - Domen 驱动的架构和用户拼写错误/错误

标签 domain-driven-design encapsulation setter

DDD 教我们像真实世界的原型(prototype)一样构建我们的类。

所以不要使用setter

job = new Job
job.person = person
job.since = time.Now()
job.title = title

我们在聚合根中定义了命名良好的方法
job = person.promote(title, /** since=time.Now() **/)

现在棘手的部分

假设我们有一个 HR 的 UI,他/她在其中输入一个新的 title通过 HTML 表单并输入“prgrammer”之类的错字(当然在实际应用中会有一个选择列表,但这里我们有一个文本输入),或者选择了错误的日期(如今天的默认值)

现在我们有一个问题。现实世界中没有错别字。我们的 John Doe 绝对是一个“程序员”,而不是一个“prgrammer”

我们如何在我们的领域模型中修复这个错字?

我们的Person刚刚promote , demote , fire等方法,体现了HR领域模型。

我们可以稍微作弊并更改 Job直接记录,但现在我们有一个Job.setTitle方法,这不反射(reflect)我们的领域模型,而且,setter 是邪恶的,你知道的。

这可能看起来有点“学术”,但是当我尝试为复杂的应用程序构建一个好的域模型时,这真的让我很烦恼

最佳答案

DDD 的另一面是不变量——“always valid”实体。当你试图打破这个不变量(某些规则)时,你必须停止执行并“大声”地说出这个(抛出异常)。因此,您需要有一个有效标题列表,并且当您尝试将标题(不管如何)更改为无效状态时,您必须抛出一些有用的异常。

要“修复”错字情况,您必须将域中的操作分开 promote是一项操作(它可能会检查某些内容,发送通知电子邮件:) 等等)。和edit操作 - 只是为了编辑一些属性。因此,区别在于操作逻辑。您不能调用promote没有一些先决条件(例如,要求 worker 的经验),但您可以调用edit并根据类型修复 worker 的姓名。
而且通常这些操作在不同的用户之间是分开的:只有 HR 可以 promote但是 worker 可以edit他的名字,如果它是错误的。
对于此类示例,此解决方案非常复杂,但始终使用 DDD。
主要概念 - 单独操作。每一个都有自己的条件、权限、规则。

一个 question关于不变量(规则)。

关于domain-driven-design - Domen 驱动的架构和用户拼写错误/错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32002962/

相关文章:

domain-driven-design - 何时更新审计字段? DDD

oop - 事件溯源中的值对象

domain-driven-design - DDD 组合多个有界上下文

java - 反射 API 不会破坏数据封装的目的吗?

java - Struts2参数拦截器中的错误

ios - objective-c 中复制属性的自定义 setter

asp.net-mvc - NHibernate: "failed to lazily initialize...",DDD方法

c - C中的可重入库设计

C#:部分类和 Web 服务:分离形式和功能

导致 exc_bad_access 的 swift setter