DDD Утечка Вопрос о Инкапсуляции - PullRequest
2 голосов
/ 22 августа 2011

A Story может получить Award (One) от 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 ]

2 голосов
/ 22 августа 2011

Не имеет ли смысла для SetAward проверять, была ли вручена награда?Помните: скажи, не спрашивай .

1 голос
/ 22 августа 2011

Вот еще одно предложение.

Иметь 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 (имя подразумевает, что это так), история также неявно подтверждает, что один и тот же экземпляр Award не предоставляется нескольким историям.

1 голос
/ 22 августа 2011

Вместо того, чтобы позволить истории получить награду, возможно, награда должна указывать на историю?

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

Не зная вашего домена (таким образом, зная, что такое история и награда), мне трудно понять, что имеет смысл, но эта модель позволит истории получить несколько наград. Если история была фильмом, а награда могла быть премией «Золотой глобус» или «Оскар» и т. Д., То эта модель также позволяет истории иметь несколько наград. Но поскольку вы специально запретили это в своем исходном коде, возможно, это недопустимо в вашем домене.

0 голосов
/ 22 августа 2011

Вы действительно должны следовать принципу «говорите, не спрашивайте», просто установите вознаграждение и скажите исключение, если это желаемое поведение в классе StoryBase

...