簡體   English   中英

DDD(域驅動設計)事件和持久性

[英]DDD (Domain Driven Design) events and persistance

這里的問題是有關如何正確處理DDD DE的,可以說我們有一個非常簡單的示例(我知道對於簡單項目,不需要DDD,但這只是一個示例)。 我們有用戶(聚合根)和UserProfile(值對象),因此表為:

用戶

- id
- email
- password

用戶資料

- country_id
- first_name
- second_name

我們知道我們的代碼應該表達行為,並且不應該以數據為中心,因此例如在我們的六邊形之一(UI瀏覽器)上,我們可以使用此應用程序服務來處理以下情況:

//UserService application service
public static function update($formDTO)

$user->changeCountry($form->country);
$user->changePassword($form->password);
$user->attributes = $form->userData();
$user->save(); // here we use AR not DDD ORM like; you can see this as entityManager->flush(); if you like Hibernate or Doctrine.

方法changeCountry看起來像:

 public function changeCountry($country)
 {
     if ($this->country->id != $country->id) {
          $oldCountry = $this->country;
          $this->moveToCountry($country);
          ...->eventsManager->raise(new UserMovedToCountryEvent(
              [
                  'user' => $this,
                  'oldCountry' => $oldCountry,
                  'newCountry' => $newCountry,
              ],
          ))
     }
 }

有關changePasswordchangeCountry方法的問題:

  • 我們應該在$user->changeCountry()調用save嗎? 這樣的行為方法( changePasswordchangeCountry )是否應該在更改對象后將對象持久保存到存儲中?
  • 如果應該,那么我們應該將其包裝在交易中嗎? 我想是的,因為我們這里有DomainEvent。
  • 如果沒有DomainEvent,我們應該仍然將對象持久存儲嗎? 在這種情況下,這個方法( changeCountrymoveToCountry )用來表達行為,但它應該開始交易? 對這個有什么建議嗎?
  • 或者,也許我們只應該使用$oldInfo $newInfo類的參數來$oldInfo一個域事件UserProfileChanged ,但是就我而言,這一個缺少域。

關鍵是要使事情正確,但不需要大量的持久性調用。 我知道我不應該考慮域層的持久性,但是獲得20 sql更新而不是1不是一個好的解決方案。

域對象不應與持久性有關。 Repositories負責總體持久性。 您將從存儲庫中獲取聚合,在聚合上調用方法,並將其再次保存在應用程序層中。 這導致兩個數據庫調用; 一個SELECT和一個UPDATE-在一個事務中匯總。

var user = repository.GetById(userId);
user.MoveToCountry(country);
repository.Update(user);

我知道這只是一個例子,但是請確保您抓住了用戶的意圖。 該更新方法看起來像是在構建CRUD應用程序,但實際上是在試圖對意圖進行反向工程-在重構等過程中這可能很有意義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM