DDD漏泄封装问题

时间:2011-08-22 14:57:08

标签: c# .net domain-driven-design

提名可以通过提名者获得奖励(一个)。所以,我的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()是公开可见的,所以可以从Nominator以外的人那里调用,但是Nominator必须知道故事是否已经获得奖励。

任何想法都会很棒!

4 个答案:

答案 0 :(得分:2)

SetAward测试是否给予奖励会不会更有意义?请记住:tell, don't ask

答案 1 :(得分:1)

这个奖项应该指向这个故事,而不是让故事有这个奖项?

public class Award
{
    public Award(Story awardedTo, Nominator awardedBy)
    { ... }
}

不了解您的域名(因此知道什么是故事和奖励),我很难知道什么是有道理的,但该模型将允许故事获得多个奖励。如果故事是电影,奖项可能是金球奖或奥斯卡奖等,那么该模型也允许故事有多个奖项。但是,由于您在原始代码中明确禁止使用该代码,因此可能在您的域中无效。

答案 2 :(得分:1)

这是另一个建议。

故事 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 实例(名称暗示它确实如此),那么 >故事还隐式验证多个故事没有提供相同的 Award 实例。

答案 3 :(得分:0)

你应该遵循tell do not ask原则,只需设置奖励并抛出异常,如果这是StoryBase类中所需的行为