实体标识 - 使用字符串而不是类型

时间:2015-07-03 21:50:02

标签: architecture domain-driven-design software-design

我已经看过许多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以上是一个对象,但实际值为stringintGuid等,具体取决于对象标识类型。

我的问题是为什么不简单地使用字符串作为身份?毕竟,Guids,整数,名称,数字都可以表示为字符串,并且它们可以像普通格式的字符串一样容易比较 - 这不仅可以使字符串作为通用格式更容易使EventEnvelope更容易,它还可以使实体更容易句柄不需要基类或特殊类型?

总而言之,为什么人们不建议使用字符串作为通用格式(或者我还没有看到它),而是讨论基类和身份的通用类型?

2 个答案:

答案 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,同时在整个外部总线上提供相同的格式。

除此之外,它是一般指导原则。软件工程中的每个指南都有利有弊。使用您认为最合适的并且知道最佳的,但要在整个设计中保持一致。