亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

創建聚合根及其子對象(實體)的正確流程是什么?

創建聚合根及其子對象(實體)的正確流程是什么?

PHP
嗶嗶one 2022-10-28 16:26:30
我正在將我的數據驅動設計重構為領域驅動,我對代碼的結構有幾個問題我有一個User entitynamespace Planner\Domain\Entities;class UserEntity {    private $userId;    private $weight;    private $height;    public function __construct(int $id, float $weight, float $height){        $this->userId = $id;        ...    }}我還有一個Settings entity應該與用戶對象創建一起創建的。namespace Planner\Domain\Entities;class SettingsEntity {    private $id;    private $userId;    private $darkTheme;    public function __construct(int $id, int $userId, bool $darkTheme){        $this->id = $id;        $this->userId = $userId;        $this->darkTheme = $darkTheme;    }}Settings 對象不能沒有 User 存在,因此 settingsEntity 應該由 User 實體管理。這意味著,用戶實體不僅僅是一個實體,它應該是一個聚合根。目前,當用戶點擊“創建賬戶”時,App 向 發出 API 請求example.com/user/save,控制器動作將請求對象發送到Planner\Application\Services\UserServicesave 方法。namespace Planner\Application\Services;use Planner\Domain\Entities\UserEntity;use Planner\Domain\Entities\SettingsEntity;use Planner\Domain\Repositories\UserRepository;use Planner\Application\Services\SettingsService;class UserService {    public function __construct(UserRepository $repo, SettingsService $settings){        $this->userRepository = $repo;        $this->settingsService = $settings;    }    public function save($request){        $user = new UserEntity(...);        $settings = new SettingsEntity(...);        if(!$this->userRepository->save($user) || !$this->settingsRepository->save($settings)){            throw new UserCreationFailedException();        }    }}問題是,我不知道是否應該一次性創建用戶實體和設置實體(從理論上講,因為我沒有用戶聚合根,只有一個用戶實體)用戶聚合根或者當前方式有效。我還有其他需要同時創建的實體...與設置對象相同,我只是將它們添加到ifUserService 保存方法中的檢查中(上面的代碼)還是應該全部在用戶聚合下,例如:namespace Planner\Domain;class User extends AggragateRoot {    public function __construct(UserRepository $repository){        $this->repository = $repository;    }    public function createAccount($request){        $user = new UserEntity(...$request);        $settings = new SettingsEntity(...$user);        $this->repository->save($user, $settings);    }}
查看完整描述

2 回答

?
MYYA

TA貢獻1868條經驗 獲得超4個贊

所有頂級實體都是聚合根。在您當前的設計中,UserEntitySettingsEntity是有效的聚合根 (AR)。AR 是事務性和一致性邊界。AR 的作用是確保與它們封裝的數據相關的不變量永遠不會被破壞,即使通過并發也是如此。

AR 應該設計得盡可能小,因為它們可以防止對它們保護的數據進行并發修改。為了從 AR 模式中受益,您必須努力將 AR 視為事務邊界,因此對于大多數用例(可能存在例外),嘗試只修改每個事務的單個 AR。但是,該規則在創建 AR 時并不適用,因為在創建時并發沖突不應該是常見的。

這里有兩種顯而易見的潛在設計,正確的一種取決于實際的業務不變量和您想要做出的妥協。

  1. User并且Settings具有交叉不變量,這意味著不變量User可能取決于狀態,Settings反之亦然。在這種情況下User,并且Settings必須是同一一致性邊界的一部分。您很可能擁有UserAR 和Settings生活在User.

  2. User并且Settings可以獨立進化(除了他們的創造)。在這種情況下,您很可能希望將UserSettings作為自己獨立的 AR,但在同一個事務中創建兩者(或不創建 - 最終一致性)。請注意,在 AR 上使用工廠方法來創建另一個工廠方法通常很優雅。

    transaction {
         user = new User(…)
         settings = user.initSettings(...)
         userRepository.save(user);
         settingsRepository.save(settings);}

    從那時起,UserSettings在不同的事務中進行修改。

PS:我建議刪除諸如“實體”之類的技術前綴。語言是 DDD 的關鍵,我懷疑領域專家在他們的語言中使用“UserEntity”(甚至可能不是“User”)或“SettingsEntity”這個詞。


查看完整回答
反對 回復 2022-10-28
?
溫溫醬

TA貢獻1752條經驗 獲得超4個贊

這取決于它是否是新用戶。

如果它是現有用戶,則處理它的一種方法是使用存儲庫“水合”用戶和存儲中的設置。然后修改。

如果是新用戶,您可以使用工廠實例化聚合根(用戶實體)并使用符合 UL 的工廠方法從輸入生成設置。

擁有用戶對象后,將其發送到存儲庫以進行持久化。


查看完整回答
反對 回復 2022-10-28
  • 2 回答
  • 0 關注
  • 211 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號