爲了將我們的邏輯從數據庫遷移到微服務,我在幾個月前修改了可用性引擎。當時,業務邏輯是相當簡單:如何確定組合房間的可用性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