我正在努力了解C#中ValueObject的用例,何时使用以及对ValueObject的需求。我在文档中看到,当我们想初始化对象,然后不想更改意味着使其不可变的属性时,可以使用它,但这与Singleton模式不同吗?在Singleton模型中,您可以在构造函数中初始化对象属性,并且它将在应用程序的整个生命周期中持续存在?现在我们为什么需要ValueObject,以及这个EqualityComparer和hashCode((等的全部功能。
来自Microsoft文档的代码:
public abstract class ValueObject
{
protected static bool EqualOperator(ValueObject left, ValueObject right)
{
if (ReferenceEquals(left, null) ^ ReferenceEquals(right, null))
{
return false;
}
return ReferenceEquals(left, null) || left.Equals(right);
}
protected static bool NotEqualOperator(ValueObject left, ValueObject right)
{
return !(EqualOperator(left, right));
}
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 override int GetHashCode()
{
return GetEqualityComponents()
.Select(x => x != null ? x.GetHashCode() : 0)
.Aggregate((x, y) => x ^ y);
}
// Other utility methods
}
现在地址实体:
public class Address : ValueObject
{
public String Street { get; private set; }
public String City { get; private set; }
public String State { get; private set; }
public String Country { get; private set; }
public String ZipCode { get; private set; }
public Address() { }
public Address(string street, string city, string state, string country, string zipcode)
{
Street = street;
City = city;
State = state;
Country = country;
ZipCode = zipcode;
}
protected override IEnumerable<object> GetEqualityComponents()
{
// Using a yield return statement to return each element one at a time
yield return Street;
yield return City;
yield return State;
yield return Country;
yield return ZipCode;
}
}
在上面的代码中,这个地址是什么,我们为什么使用ValueObject,这个equalOperator是什么,所有这些都写在ValueObject类中,只是试图理解实时使用ValueObject的用例,我们为什么需要它,它是关于使用ValueObjects的场景的实时用例,为什么我们需要ValueObject中的Equality运算符,而不是equal运算符。
我是这个话题的新手。
ValueObject
类应该用于业务逻辑。
在DDD中,值对象不能通过Id来标识,而是通过对象中的字段来标识,因此需要比较对象中一个或多个属性的相等运算符。
这也是您无法更改属性的原因,因为对象将无法与其他加载的实例进行比较。就像在示例中一样,如果您更改街道编号,它将不再是同一地址。
当实现DDD值对象时,您必须将所有比较逻辑复制到每个类中,从而复制代码。
ValueObject
类消除了这种需要,并使您自己的对象更加以业务为中心(即更可读(,就像使用DDD时一样(或者只是一个干净的业务层(。