我已经看过许多DDD帖子,实际上是书籍,其中实体类派生自某种形式的基类,它具有实体标识类型的通用参数:
public interface IEntity<out TKey>
{
TKey Id { get; }
}
public interface IComplexEntity<out TKey, in TEntity>
{
TKey Id { get; }
bool IsSameAs(TEntity entity);
}
//Object Definition
public class TaxPayer : IComplexEntity<string, User>
{
...
}
在Vernon的实施域驱动设计中,创建了特定类型以用作身份:
public class TaxPayerIdentity : Identity
{
public TaxPayerIdentity() { }
public TaxPayerIdentity(string id)
: base(id)
{
}
}
最近,我一直致力于将事件总线上的事件传递给外部听众。 &#34;问题&#34;我有一个共同的消息格式来发送事件信封:
public EventEnvelope
{
long EventStoreSequence; // from the event store
bool IsReplay; // if event store is replaying from position 0 of stream
object EventBeingSent; // this is the actual event, i.e. class AddressChanged { string Old; string New; DateTime On; }
object IdentityOfSender; // this is the identity of the entity who raised the event
}
IdentityOfSender
以上是一个对象,但实际值为string
,int
,Guid
等,具体取决于对象标识类型。
我的问题是为什么不简单地使用字符串作为身份?毕竟,Guids,整数,名称,数字都可以表示为字符串,并且它们可以像普通格式的字符串一样容易比较 - 这不仅可以使字符串作为通用格式更容易使EventEnvelope更容易,它还可以使实体更容易句柄不需要基类或特殊类型?
总而言之,为什么人们不建议使用字符串作为通用格式(或者我还没有看到它),而是讨论基类和身份的通用类型?
答案 0 :(得分:1)
实际上,使用类型几乎没有任何好处 - 您可以轻松地在任何编程语言中使用字符串。
但是有一个更微妙的优势。 String表示 string ,只是一个字符序列。您必须知道某些字符串实际上意味着其他的上下文。对你来说可能很清楚,但我们不是为自己编写代码,而是为未来的读者编写代码。向其他人说清楚是非常重要的 - 日期是日期,ID是ID等。
此外,如果需要,以后更容易扩展/重构某些特定的ID类型。
答案 1 :(得分:1)
因为跨文化字符集中的字符串比较并不容易。可以与字符串比较的最接近的数据类型是GUID。但即使GUID也可以有不同的字符串表示。
前:
{FD49D6AE-019C-4118-B7D1-A4DA54E4474F},
fd49d6ae-019c-4118-b7d1-a4da54e4474f,
FD49D6AE019C4118B7D1A4DA54E4474F
所有三个都具有相同的GUID值但不同的字符串比较。数字以千分隔/小数点格式差异着称。
此外,我认为身份的自定义类是提供显式身份比较。示例:信用卡号在前六位数中具有六位数的发卡行标识号(IIN)(wikipedia)。也就是说,使您在域驱动设计中具有更高的灵活性。是的,这种设计阻止你使用&#34;一个人使用#34;数据类型。
但是,您可以通过对象映射将编码 - 解码模型用于外部总线。这样你就可以避免破坏DDD,同时在整个外部总线上提供相同的格式。
除此之外,它是一般指导原则。软件工程中的每个指南都有利有弊。使用您认为最合适的并且知道最佳的,但要在整个设计中保持一致。