为了将我们的逻辑从数据库迁移到微服务,我在几个月前修改了可用性引擎。当时,业务逻辑是相当简单:如何确定组合房间的可用性DDD
资源(会议室,桌子,空荡荡的办公室,设备)仅当它是不是已经预订给定的时间框架(即:无其他使用相同的资源)
当资源是不可用的,最接近的可用时间框架必须被计算
为了满足这些要求订票,我建立了小片的下面的代码:
public class Schedule : IAggregateRoot
{
public int CityId { get; }
public int BuildingId { get; }
public int CentreId { get; }
public int ResourceId { get; }
public ICollection<Booking> Bookings { get; }
public Schedule(int cityId, int buildingId, int centreId, int resourceId, IEnumerable<Booking> bookings)
{
CityId = cityId;
BuildingId = buildingId;
CentreId = centreId;
ResourceId = resourceId;
Bookings = new List<Booking>(bookings);
}
public bool IsTimeSlotFree(DateTimeOffset startDate, DateTimeOffset endDate)
=> Bookings.Any(/* Predicate */);
public IEnumerable<Availability> GetFreeTimeSlots(
DateTimeOffset startDate,
DateTimeOffset endDate,
TimeSpan duration)
{
var nbSlots = Math.Floor((endDate - startDate)/duration);
for(int i=0; i<nbSlots; i++) {
/* yield return availability */
}
}
}
public class Availability : ValueObject
{
public DateTimeOffset StartDate { get; set; }
public DateTimeOffset EndDate { get; set; }
public int ResourceId { get; set; }
public bool IsAvailable { get; set; }
}
public class Resource : Entity
{
public string Code { get; set; }
// Required for EF Core
protected Resource() { }
}
public class Booking : Entity
{
public DateTimeOffset StartDate { get; set; }
public DateTimeOffset EndDate { get; set; }
public string Status { get; set; }
public int ResourceId { get; set; }
// Required for EF Core
protected Booking() { }
}
几周前,我被要求处理组合房间(两个较小的房间可以合并成一个更大的组合房间)。在这种情况下,组合房间只能使用其子房间和本身。换句话说,我需要检查几个时间表来确定可用性,不幸的是,我当前的抽象级别不允许(一个时间表,一个房间)。
我发现的唯一方法是检索资源及其子(= subrooms),然后创建一个包含ResourceId和预订字典的计划。
public class Resource : Entity
{
public string Code { get; set; }
public Resource Parent { get; set; }
public ICollection<Resource> Children { get; set; }
// Required for EF Core
protected Resource() { }
}
public class Schedule : IAggregateRoot
{
public int CityId { get; }
public int BuildingId { get; }
public int CentreId { get; }
public int ResourceId { get; }
public IDictionnary<int, ICollection<Bookings>> Bookings
(...)
}
我不觉得这个解决方案真的很优雅。对我来说,更好的解决方案是检索计划并将它们合并以确定实际可用性。我尝试了几种解决方案,但最终我写了意大利面代码。
对于如何重新设计我的聚合以正确处理这个新概念,您有什么想法吗?
谢谢 勒布
有没有提前知道有限的子房可能性,还是可以将任何两个房间组合成一个更大的房间? – guillaume31
是的,他们提前知道。我知道哪些房间可以合并。其实我把这个信息存储在一个分贝:) – Seb