如何在DDD中管理某些域“静态数据”
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在DDD中管理某些域“静态数据”相关的知识,希望对你有一定的参考价值。
一段时间以来,我了解了DDD并发现这种方法非常有趣。
上下文
我为Dungeon&Dragon角色表创建者和管理者启动了一个项目,并对域“静态数据”的实现提出了一些疑问。
我知道DDD与数据无关,但是我无法为我的问题找到另一个词。
实施
我简化了以下代码,将重点放在我的询问上。例如,我没有写空检查。
字符
我的角色是一个总的根,我们可以从这个班级中选择他的课程和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);
...
班级
Class是另一个聚合根。在《地牢与龙》中,类的数量是有限的,它们的行为是不同的。我想在领域中实现它们以代表这些行为。有些班级可以使用咒语,有些班级可以穿重型盔甲,...
public abstract class Class : IAggregateRoot
public string Id => GetType().Name;
public abstract ICollection<Skill> AvailableSkills get;
战斗机
战斗机类别是已实施的类别之一。我认为单身是个好主意,因为所有战斗机角色都可以使用相同的东西。一个字符的特异性在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;
角色类
字符类是一个实体,引用类的聚合根。我读了一些有关DDD的文章,他说对另一个聚合根的引用应该与他的ID有关。
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应用程序上重用域程序集。这就是为什么我要为类实现某些域“数据”和特定行为。我的业务逻辑将被写入一次。
[确定,我可以使用服务的一种方式。
我将重命名一些内容,并忽略某些继承-并采用其他方法。
- 将“班级”重命名为SkillsClass
- 添加可用的技能工厂
- 观察:技能只是一个枚举
- 我将使用另一个枚举-CharacterType 1 = Fighter
// This is dummy code without input, such as a test - but could be in a Service etc.
SkillsClass availableSkills = AvailableSkillsFactory.Get(CharacterType.Fighter);
Character character = new Character(CharacterType.Fighter);
character.ChooseSkill(Skill.Perception, availableSkills);
在角色类中,我将选择技能更改为此...
public void ChooseSkill(Skill skill, SkillsClass availableSkills)
...
// This business rule need to check another Aggregate root
bool isSkillAvailable = availableSkills.IsAvailable(skill);
if (!isSkillAvailable)
// action
Skills.Add(skill);
然后是SkillsClass ...
public class SkillsClass
public IEnumerable<Skill> AvailableSkills get; private set;
public SkillsClass (IEnumerable<Skill> skills)
this.AvailableSkills = skills;
public bool IsAvailable (Skill skill)
var doesExist = this.AvailableSkills.Contains(skill);
return doesExist;
还有工厂...
public static class AvailableSkillsFactory
public static Get(CharacterType characterType)
if (characterType == CharacterType.Fighter)
var availableSkills = new Fighter().AvailableSkills;
return new SkillsClass(availableSkills);
为了确定它的简单性,我反复来了几个名字,并决定不进行过多的重构。
有多种方法可以做到这一点。
以上是关于如何在DDD中管理某些域“静态数据”的主要内容,如果未能解决你的问题,请参考以下文章
如何在 DDD 中使用 EF DbContext 分离我的聚合