【问题标题】:Entity Identity - use of strings instead of type实体身份 - 使用字符串而不是类型
【发布时间】:2015-07-03 21:50:02
【问题描述】:

我看过许多 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)
    {
    }
}

最近,我一直致力于将事件总线上的事件传递给外部侦听器。我遇到的“问题”是我需要一个通用的消息格式来发送事件信封:

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 更容易使用字符串作为通用格式,而且会使实体更容易无需基类或特殊类型即可处理?

所以综上所述,为什么人们不推荐使用字符串作为标识的通用格式(或者我没见过),而是谈论标识的基类和泛型类型?

【问题讨论】:

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


    【解决方案1】:

    因为跨文化字符集中的字符串比较并不容易。可以与字符串比较的最接近的数据类型是 GUID。但即使是 GUID 也可以有不同的字符串表示形式。

    例如:

    {FD49D6AE-019C-4118-B7D1-A4DA54E4474F},
    fd49d6ae-019c-4118-b7d1-a4da54e4474f,
    FD49D6AE019C4118B7D1A4DA54E4474F
    

    这三个都有相同的 GUID 值但不同的字符串比较。数字以千位分隔符/小数点格式差异而闻名。

    此外,我相信身份的自定义类是提供明确的身份比较。示例:信用卡号的前六位有一个六位数的发卡机构识别码 (IIN) (wikipedia)。也就是说,使您在域驱动设计中具有更高的灵活性。是的,这种设计会阻止您使用“one for all”数据类型。

    不过,您可以通过对象映射将编码-解码模型用于外部总线。这样您就可以避免破坏 DDD,同时在整个外部总线中提供相同的格式。

    除此之外,这是一般准则。软件工程中的每条准则都有其优点和缺点。使用您认为最合适且最了解的一种,但在您的设计中保持一致。

    【讨论】:

      【解决方案2】:

      实际上,使用类型几乎没有任何好处——您可以轻松地在任何编程语言中使用字符串。

      但还有一个更微妙的优势。 String的意思是string,只是一个字符序列。你必须知道一些字符串实际上意味着其他东西的上下文。您可能很清楚,但我们不是为自己编写代码,而是为未来的读者编写代码。向其他人说明这一点非常重要 - date 是一个日期,ID 是一个 ID,等等。

      此外,如果需要,以后扩展/重构某些特定 ID 类型会容易得多。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-02
        • 2018-01-09
        相关资源
        最近更新 更多