为什么需要封装
值对象的属性需要同时满足某些条件保证值对象数据的一致性,这些属性同时被传递(作为参数)
示例
很多场景下都会用到的开始、结束时间,两个时间必须不能为空,而且这两个时间一般同时做为参数传递
将这两个属性放到一个值对象中,让它们同时变化与维护自身逻辑,与系统其它部分解耦
代码实现
public class DateTimeRange
{
public DateTime Start { get; private set; }
public DateTime End { get; private set; }
public DateTimeRange(DateTime start, DateTime end)
{
Start = start;
End = end;
}
public DateTimeRange(DateTime start, TimeSpan duration)
{
Start = start;
End = start.Add(duration);
}
protected DateTimeRange() { }
public int DurationInMinutes()
{
return (End - Start).Minutes;
}
public DateTimeRange NewEnd(DateTime newEnd)
{
return new DateTimeRange(this.Start, newEnd);
}
public DateTimeRange NewDuration(TimeSpan newDuration)
{
return new DateTimeRange(this.Start, newDuration);
}
public DateTimeRange NewStart(DateTime newStart)
{
return new DateTimeRange(newStart, this.End);
}
public static DateTimeRange CreateOneDayRange(DateTime day)
{
return new DateTimeRange(day, day.AddDays(1));
}
public static DateTimeRange CreateOneWeekRange(DateTime startDay)
{
return new DateTimeRange(startDay, startDay.AddDays(7));
}
public bool Overlaps(DateTimeRange dateTimeRange)
{
return this.Start < dateTimeRange.End &&
this.End > dateTimeRange.Start;
}
}
当我们审查一个实体的属性时,可能会发现有些属性总是同时出现,这时应该用一个值对象封装这些属性,让它们独立变化,不影响系统的其他部分。这也让该实体的职责更加单一。