ABP框架 - 值对象

文档目录

 

本节内容:

简介

“一个表示领域的一个描述性方面的没有概念上的身份对象,称为值对象。“(Eric Evans)。

与一个有身份(Id)实体相反,一个值对象没有身份。如果两个实体的身份(Id)不同,它们被认为是不同对象/实体,即使其它所有的属性都相同。比如两个不同的Person实体,它们的Name、Surname和Age相同,如果它们的Id不同,我们就认为这是两个不同的Person。但是,对于一个Address(地址,一个经典的值对象)类,如果两个地址有相同的国家、城市、街道号码等,它们就被认为是同一个address对象。

在DDD里,值对象是另一种类型的领域对象,它可以包含业务逻辑和领域的要素。

 

值对象基类

为可简单地创建值对象类型,可以继承ABP的ValueOjbect<T>基类,例如Address值对象类型:

public class Address : ValueObject<Address>
{
    public Guid CityId { get; private set; } //A reference to a City entity.

    public string Street { get; private set; }

    public int Number { get; private set; }

    public Address(Guid cityId, string street, int number)
    {
        CityId = cityId;
        Street = street;
        Number = number;
    }
}

ValueObject基类重写了相等操作符(==,和其它相关的操作符和方法),用来比较两个值对象,如果所有属性都是相同的,那么就认为这两个值对象是相同的。所以这些测试都可以通过:

var address1 = new Address(new Guid("21C67A65-ED5A-4512-AA29-66308FAAB5AF"), "Baris Manco Street", 42);
var address2 = new Address(new Guid("21C67A65-ED5A-4512-AA29-66308FAAB5AF"), "Baris Manco Street", 42);

Assert.Equal(address1, address2);
Assert.Equal(address1.GetHashCode(), address2.GetHashCode());
Assert.True(address1 == address2);
Assert.False(address1 != address2);

即使它们在内存里是不同的,对于我们的领域来说也是相同的。

 

最佳实践

这里有些关于值对象的最佳实践:

  • 把值对象设计成不可变的(如上面的Address),如果没有好的理由,不要把它设计成可变的。
  • 组成一个值对象的属性应该形成一个概念上的整体。例如:CityId,Street和Number不应该被分离成Person的三个属性,而且整个值对象也简化了Person实体。

 

posted @ 2016-10-24 19:12 kid1412 阅读(...) 评论(...) 编辑 收藏