Некоторое время я читаю о DDD и нахожу этот подход очень интересным.
Контекст
Я запускаю проект для создателя и менеджера таблицы персонажей Dungeon & Dragon, и у меня есть некоторые вопрос о реализации домена "stati c data".
Я знаю, DDD не о данных, но я не могу найти другое слово для моей проблемы.
Реализация
Я упрощаю следующий код, чтобы сосредоточиться на моих допросах. Например, я не писал нулевые проверки.
Персонаж
Мой персонаж - совокупность root, и мы можем выбрать его класс и 2 навыка из этого класса
public class Character : IAggregateRoot
{
public Guid Id { get; }
public string Name { get; private set; }
public Class Class { get; private set; }
...
// class is a keyword, so I use @class
public void ChooseClass(Class @class)
{
Class = CharacterClass.Create(@class);
}
public void ChooseClassSkill(Skill skill)
{
Class.ChooseSkill(skill);
}
...
}
Класс
Класс - это еще один агрегат root. В Dungeon & Dragon существует ограниченное количество классов, и их поведение отличается. Я хочу реализовать их в домене, чтобы представить это поведение. Некоторые классы могут иметь заклинания, некоторые могут носить тяжелую броню, ...
public abstract class Class : IAggregateRoot
{
public string Id => GetType().Name;
public abstract ICollection<Skill> AvailableSkills { get; }
}
Fighter
Класс Fighter является одним из реализованных классов. Я думал, что синглтон - хорошая идея для этого, потому что все персонажи, которые являются бойцами, имеют доступ к одним и тем же вещам. Специфика для одного символа находится в CharacterClass. После прочтения некоторых статей о том, что синглтон является анти-паттерном, я не уверен в этом.
public class Fighter : Class
{
public override ICollection<Skill> AvailableSkills => new List<Skill>()
{
Skill.Acrobatics,
Skill.Athletics,
Skill.Perception
};
private static Fighter instance = null;
internal static Fighter Instance
{
get
{
if (instance == null)
instance = new Fighter();
return instance;
}
}
}
Класс символов
Класс символов является сущностью и ссылается на агрегат класса root. Я читал статью о DDD, который сказал, что ссылка на другой агрегат root должна быть с его идентификатором.
public class CharacterClass : Entity
{
public Guid Id { get; }
public Class Class { get; }
public ICollection<Skill> Skills { get; }
public CharacterClass(Class @class)
{
Id = Guid.NewGuid();
Class = @class;
Skills = new List<Skill>();
}
public static CharacterClass Create(Class @class)
{
return new CharacterClass(@class);
}
public void ChooseSkill(Skill skill)
{
// These business rules can be check with this class properties
if (Skills.Contains(skill))
throw new Exception();
if (Skills.Count > 1)
throw new Exception();
// This business rule need to check another Aggregate root
if (!Class.AvailableSkills.Contains(skill);
throw new Exception();
Skills.Add(skill);
}
}
Опрос
- Должен ли синглтон быть хорошим или плохая идея для моих нужд?
- Должен ли мой CharacterClass ссылаться на класс просто по id или по ссылке?
- Если я ссылаюсь по id, как проверить, доступно ли умение для класса в функция ChooseSkill?
Заранее спасибо.
Редактировать
Я планирую повторно использовать сборку домена в приложении Blazor. Вот почему я хочу реализовать некоторые доменные «данные» и указать поведение c для классов. Мой бизнес логи c будет записан один раз.