dmz*_*rsk 5 setter encapsulation domain-driven-design
DDD教我们像我们的真实世界原型一样构建我们的类.
所以不要使用setter
job = new Job
job.person = person
job.since = time.Now()
job.title = title
Run Code Online (Sandbox Code Playgroud)
我们在聚合根中定义了命名良好的方法
job = person.promote(title, /** since=time.Now() **/)
Run Code Online (Sandbox Code Playgroud)
现在是棘手的部分
假设我们有一个title人工智能的用户界面,他/她通过HTML表单输入新内容并制作一个类似"prgrammer"的拼写错误(当然在实际应用中有一个选择列表,但这里我们有一个文本输入),或选择错误的日期(如今天默认)
现在我们遇到了问题.现实世界中没有拼写错误.我们的John Doe绝对是一名"程序员"而且绝不是"程序员"
我们如何在域模型中解决这个错误?
我们Person刚刚promote,demote,fire,等方法,反映了人力资源领域模型.
我们可以稍微欺骗并Job直接更改记录,但现在我们有一个Job.setTitle方法,它不反映我们的域模型,而且,setter是邪恶的,你知道.
这可能看起来有点"学术性",但当我尝试为复杂的应用程序构建一个好的域模型时,这真的让我感到困惑
DDD的另一面是不变量-“ 始终有效 ”的实体。并且,当您尝试打破此不变式(某些规则)时,必须停止执行并大声说出来(抛出异常)。因此,您需要具有有效标题的列表,并且当您尝试将标题(无关紧要)更改为无效状态时,必须抛出一些有用的异常。
要“解决”错字情况,您必须将域中promote的操作分开是一项操作(它可能会检查某些内容,向您发送矛盾电子邮件:),依此类推)。和edit操作-只是编辑一些属性。因此,区别在于操作逻辑。你不能叫promote没有一些先决条件(例如,需要工人的经验),但你可以叫edit因为类型的固定工作人员的姓名。通常,此操作在不同的用户之间是分开的:如果是错误的,则只有HR可以,promote而工人可以edit命名。对于此类示例,此解决方案非常复杂,但始终与DDD配合使用。主要概念-分开操作。每个人都有自己的条件,权限,规则。
一个问题关于不变(规则)。
| 归档时间: |
|
| 查看次数: |
110 次 |
| 最近记录: |