Entity Identity - use of strings instead of type

北战南征 提交于 2019-12-08 03:54:34

问题


I have seen a number of DDD posts and indeed books where entity classes are derived from some form of base class that has a generic parameter for the Entity Identity type:

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>
{
    ...
}

On Vernon's Implementing Domain Driven design, specific types are created for use as identities:

public class TaxPayerIdentity : Identity
{
   public TaxPayerIdentity() { }

    public TaxPayerIdentity(string id)
        : base(id)
    {
    }
}

More recently I have been working on communicating events on an event bus to external listeners. The "issue" I have is I need a common message format for sending of the event envelope:

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
}

Above the IdentityOfSender is an object, but the actual value would be string, int, Guid etc depending on the objects identity type.

My question is why not simply use a string for the identity? After all, Guids, integer, names, numbers can all be represented as strings and they are easily comparable as strings in a common format - this not only would make the EventEnvelope easier with a string as a common format, it would make Entities easier to handle without need for base classes or special types?

So in summary, why do people not recommend the use of strings for identities as a common format (or I have not seen it), and instead talk about base classes and generic types for identities?


回答1:


Because string comparison in cross-culture charset is not easy. The closest data type that can be compared with string is GUID. But even GUID can have different string representation.

ex:

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

All three have same GUID value but different string comparison. Number is famous for the thousand separator / decimal point format difference.

Moreover, I believe that the custom class for identity is to provide explicit identity comparison. Example: Credit card number's has a six-digit Issuer Identification Number (IIN) in the first six digit (wikipedia). That is, enable you higher flexibility in domain-driven design. And yes, that design prevent you from using "one for all" data type.

However you can use encode-decode model for external bus through object mapping though. That way you can avoid breaking the DDD and at the same time providing same format throughout external buses.

That aside, it is a general guidelines. And every guidelines in software engineering has pros and cons. Use one you find most suitable and know the best, but keep it consistent across your design.




回答2:


Practically there are almost no benefits for using types - you can easily use strings in any programming language.

But there is a more subtle advantage. String means string, just a sequence of characters. You have to know the context that some string actually means something else. It might be clear for you, but we write code not for ourselves, we write it for future readers. And it's very important to make it clear to everybody else - date is a date, ID is an ID, etc.

Also, it'll be much easier to extend / refactor some specific ID type later if needed.



来源:https://stackoverflow.com/questions/31214565/entity-identity-use-of-strings-instead-of-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!