DDD領域驅動設計:實體、值對象、聚合根


1 前置閱讀

在閱讀本文章之前,你可以先閱讀:

  • 什么是DDD

2 實現值對象

值對象有兩個主要特征:它們沒有任何標識。它們是不可變的。

我們舉個例子:小明是“浙江寧波”人,小紅也是“浙江寧波”人,小王是“浙江杭州”人,在這個例子中,我們把地址可以獨立出一個值對象出來,我們會遇到了多個對象是否相同的問題,例如小明和小紅的地址應該是相等,小明和小王應該是不相等,這很好理解,我們來看一下例子;

public class Address
{
    public string Province;
    public string City;
}

var xm = new Address { Province = "浙江", City = "寧波" };
var xh = new Address { Province = "浙江", City = "寧波" };
var xw = new Address { Province = "浙江", City = "杭州" };

Console.WriteLine(xm.Equals(xh));
Console.WriteLine(xm.Equals(xw));

讓我們來看看輸出結果:

False
False

這個顯然不符合我們預期,我們需要重寫一下Equals,確保地址值相等的情況下對象相等。

public class Address
{
    public string Province;
    public string City;

    public bool Equals(Address obj)
    {
        return this.Province.Equals(obj.Province) && this.City.Equals(obj.City);
    }
}

var xm = new Address { Province = "浙江", City = "寧波" };
var xh = new Address { Province = "浙江", City = "寧波" };
var xw = new Address { Province = "浙江", City = "杭州" };

Console.WriteLine(xm.Equals(xh));
Console.WriteLine(xm.Equals(xw));

讓我們來看看輸出結果:

True
False

這個顯然符合我們預期了,接下來我們把值對象的Equals方法封裝到基類中。

public abstract class ValueObject
{
    protected abstract IEnumerable<object> GetEqualityComponents();
    public override bool Equals(object obj)
    {
        if (obj == null || obj.GetType() != GetType())
        {
            return false;
        }

        var other = (ValueObject)obj;

        return this.GetEqualityComponents().SequenceEqual(other.GetEqualityComponents());
    }
}

public class Address : ValueObject
{
    public string Province;
    public string City;

    protected override IEnumerable<object> GetEqualityComponents()
    {
        yield return Province;
        yield return City;
    }
}

3 實現實體

實體主要特征:具有唯一標識。

前面我們講到值對象將特定值都相等的對象視為相等對象,在實體中比較容易理解,標識相等的對象視為相等對象。

public abstract class Entity
{

    #region IEntity Members
    public abstract Guid Id
    {
        get; set;
    }
    #endregion

    public override bool Equals(object obj)
    {
        if (obj == null || !(obj is Entity))
            return false;

        if (Object.ReferenceEquals(this, obj))
            return true;

        if (this.GetType() != obj.GetType())
            return false;

        Entity item = (Entity)obj;

        return item.Id == this.Id;
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}

4 實現聚合根

聚合根與實體的區別,實體只在聚合內部進行操作,聚合根是對外打交道的唯一實體。我們在這里設計時聚合根需要有增改刪狀態字段。

public enum AggregateState
{
    Added = 1,
    Updated = 2,
    Deleted = 3
}

public abstract class AggregateRoot : Entity
{
    #region IAggregateRoot Members
    public AggregateState AggregateState { set; get; }
    #endregion
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM