2013-06-06 121 views
0

我想第一次做一些領域驅動的設計,並會很樂意接受以下輸入。設計:需要建模建議

目前我正在模擬一個學生預訂參加課程。學生和課程是實體(和聚合根源)。

我的第一個問題:
起初我以爲保留作爲一個實體爲好,因爲有使用情況,我想查詢預訂獨立的學生和課程。但是,要使模型更簡單並避免雙向關聯學生< - >註冊和課程< --->註冊我正在考慮將預留值作爲值對象。但是這有意義嗎?

考慮到使用情況下的查看全部對於特定日子的預訂,我需要加載所有課程並檢索他們的預訂以供檢查。這種情況在我的系統中並不常見,但它仍然感覺不太正確。任何其他想法如何解決這個問題,而不使預約實體?

第二個問題:
假設我使預留值對象。我現在想要實施註冊服務。從概念上講,它應該做到以下幾點:

  1. 創建包含學生 的ID和課程ID的預定值對象。
  2. 從存儲庫加載課程。
  3. 將預訂添加到課程中。
  4. 將課程保存到存儲庫。

假設資源庫的實現使用文檔數據庫並使用樂觀鎖定來處理衝突。現在假設當課程保存到存儲庫時,其他一些學生提前幾分鐘預約,因此我們得到一個OptimisticLockingException。

我該如何解決這個問題,而不會將關於持久化機制的知識推向域層? (或者相反。)我在技術上需要做的是基本上「再試一次」:重新加載課程,再次添加預約,並保存它。但我根本無法弄清楚如何對模型進行建模,同時保持領域模型和持久層之間的關注的清晰分離。

任何幫助將不勝感激。

回答

2

關於第一個問題:

在你的情況下,保留應像自己的域的實體處理。記住領域驅動設計,它是關於無處不在的語言的核心談話,其中要點將概念從問題領域與解決方案領域的組成部分聯繫起來。因此,如果您的用戶和應用程序作爲獨立實體瞭解並談論預訂,那麼您的解決方案應該反映這一點。

預約應該是一個實體。根據您的使用情況或訪問模式,您可以選擇僅包含課程標識符和在其中標識的學生的預留對象。相反,在設計課程或學生實體時,您可以完全忽略保留。相反,當學生想要查看他所有的註冊時,根據學生ID查詢預定庫。

底線是,你能夠同時實現,使保留的實體和簡化的過程 - 預訂 - 師生關係

對第二個問題:

當您使用樂觀鎖定你基本上是說你的應用程序瞭解正在更新的數據可能處於陳舊狀態的場景。因此,當您的數據訪問層檢測到陳舊的數據正在更新時,您必須將此信息公開給用戶,儘管這對於應用程序的域和用例有意義。

例如,在您提供的場景中,當學生提交預約請求時,該課程可用座位的數量發生變化。在這種情況下,您的域邏輯應該檢測到正在更新的數據已過時,並且由於這是預留,這意味着可用座位的數量已更改,並且應要求用戶重新加載課程頁面並重試。因此,應該向前端發送適當的響應。

話雖如此,如果我正在實施你發佈的場景,我不會使用樂觀鎖定。我只是確保課程不會超額預訂。

考慮一下:

  1. 當學生A看到他看到可用的10個席位的課程信息。
  2. 提交預約一個座位的請求。
  3. 與此同時,另一名學生或學生也發出要求保存總共5個席位。
  4. 樂觀鎖定,其中一些學生將被迫重試他們的預訂請求。只需對超額預定課程進行檢查,所有人都可以成功保存預訂。

最糟糕的情況是,在學生A決定保留他的預約之前,所有10個座位都由其他學生保留。在這種情況下,您的域邏輯應該簡單地認識到不能再進行預留,並向用戶顯示合適的消息。

希望這有助於..對不起,長期的迴應。但我覺得這個問題值得解釋。

讓我知道如果我錯過了這一點。

+1

我同意你所提出的觀點,並且對解釋進行+1。 –

+0

@BalázsMáriaNémeth非常感謝。 – Akshay

+0

感謝您的回覆,非常感謝!現在我確信Reservation應該是它自己的實體。仍然不確定處理同一課程同時更新的最佳方式,但它似乎被認爲是脫離主題。 :) – Daniel

1

在我看來,Reservation是一個法律實體。

基本上一個ReservationCourseStudent之間的一種關係。您可以使用多對多連接(連接表)作爲Reservation,不要將其用作實體,但是不存在有關存儲的Reservation的額外信息嗎?學生添加課程的日期,是否被接受等。也許我錯了,但我只能這樣看。

此外,如果它是一個多對多的關係,需要一個連接表,爲什麼你不想讓它成爲一個實體?你有它的物理存儲,我也希望它在邏輯上。

這種方式,您可以查詢Reservation,並通過延遲加載都CourseStudent,你甚至可以有關於預訂信息,而無需首先獲取它們。

至於你的問題的第二部分,我認爲這已經解決了它。您不會觸碰任何CourseStudent實體,只會插入預留(保留Reservation)。

+0

謝謝,感謝您的回覆! – Daniel