使用户明确!
我已经遇到过用户的文化是该域中的一等公民的域,但是在这种情况下,我建模了一个适当的值对象(在您的示例中,我将使用正确实现的 Position 类IEquatable<Position>
)和能够表达此类的 User价值观。
坚持你的例子,比如:
public sealed class VATIN : IEquatable<VATIN> { // implementation here... }
public sealed class Position : IEquatable<Position> { // implementation here... }
public sealed class Person
{
// a few constructors here...
// a Person's identifier from the domain expert, since it's an entity
public VATIN Identifier { get { // implementation here } }
// some more properties if you need them...
public Position CurrentPosition { get { // implementation here } }
// some commands
public void PromoteTo(Position newPosition) { // implementation here }
}
public sealed class User
{
// <summary>Express the position provided according to the culture of the user.</summary>
// <param name="position">Position to express.</param>
// <exception cref="ArgumentNullException"><paramref name="position"/> is null.</exception>
// <exception cref="UnknownPositionException"><paramref name="position"/> is unknown.</exception>
public string Express(Position position) { // implementation here }
// <summary>Returns the <see cref="Position"/> expressed from the user.</summary>
// <param name="positionName">Name of the position in the culture of the user.</param>
// <exception cref="ArgumentNullException"><paramref name="positionName"/> is null or empty.</exception>
// <exception cref="UnknownPositionNameException"><paramref name="positionName"/> is unknown.</exception>
public Position ParsePosition(string positionName) { // implementation here }
}
并且不要忘记文档和正确设计的异常!
警告
您提供的示例模型中至少有两种巨大的设计气味:
- 公共设置器(Position 属性)
- 持有业务价值的 System.String
公共设置器意味着您的实体将其自己的状态暴露给客户,而不管其自身的不变量如何,或者此类属性对实体没有商业价值,因此根本不应该成为实体的一部分。实际上,可变实体应该始终将命令(可以改变状态)和查询(不能)分开。
具有业务语义的 System.String 总是带有隐含的域概念的味道,通常是具有相等操作的值对象(我的意思是实现 IEquatable)。
请注意,要获得可重用的领域模型非常具有挑战性,因为它需要两名以上的领域专家和丰富的 ddd 建模经验。我在职业生涯中遇到的最糟糕的“领域模型”是由一位具有丰富 OOP 技能但之前没有建模经验的高级程序员设计的:它是 GoF 模式和数据结构的混合体,希望非常灵活,事实证明没用。在花费了 20 万欧元之后,我们不得不把它扔掉并从头开始。
可能你只需要一个好的数据模型直接映射到 C# 中的一组简单数据结构:如果你真的不需要它,你将永远不会从域模型的前期投资中获得任何投资回报!