DDD泄漏封装问题
本文关键字:问题 封装 泄漏 DDD | 更新日期: 2023-09-27 18:06:32
故事可由提名者授予奖(一)。因此,我的Nominator实体有以下方法:
public void GiveAward(StoryBase story)
{
if (story.HasAward())
throw new InvalidOperationException("...");
if (BusinessUnit.HasAwardsToGive() == false)
throw new ...
story.SetAward(new Award(AwardType.Results));
}
到目前为止,我对如何实现这个问题不太清楚。SetAward()是公开可见的,所以它可以从提名人之外的人调用,但是提名人必须知道这个故事是否已经获得了奖项。
任何想法都会很棒!
让SetAward
测试一个奖项是否被授予不是更有意义吗?记住:告诉,不要问。
我还有一个建议。
让Story以Nominator作为输入。
public class Story
{
public void GiveAward(Nominator nominator)
{
if (this.Award != null)
throw new ...
var award = nominator.CreateAwardForStory(this);
this.SetAward(award); // SetAward can now be private
}
}
public class Nominator
{
public Award CreateAwardForStory(Story story)
{
if (BusinessUnit.HasAwardsToGive() == false)
throw new ...
return new Award(AwardType.Results);
}
}
现在,如果我们假设CreateAwardForStory(…)函数保证返回一个新的Award实例(名称暗示它确实如此),Story还隐式地验证相同的Award实例没有给多个故事。
与其让故事获得奖项,不如让奖项指向故事?
public class Award
{
public Award(Story awardedTo, Nominator awardedBy)
{ ... }
}
不了解你的领域(因此不知道什么是故事和奖项),我很难知道什么是有意义的,但这个模型将允许一个故事获得多个奖项。如果这个故事是一部电影,奖项可以是金球奖或奥斯卡奖等,那么这个模型也允许一个故事获得多个奖项。但既然你在原始代码中明确禁止了这一点,那么这可能在你的域名中无效。
你应该遵循"告诉不要问"的原则,如果这是StoryBase类中期望的行为,就设置奖励并抛出异常