IDDDを読んで、それなりに書いてあることは分かり始めたかな。と思ってたけど。
いざサンプルプロジェクトを読んでみたら、全然そんなことなかった。(ノД`)シクシク
いつものように、自分メモ。
プロジェクトの構成
全部で3プロジェクトと1ライブラリがある。
iddd_agilepm
- データストアとしてKVS(LevelDB)を使用。
- DIコンテナは使ってない。
iddd_collaboration
Event Sourcing と CQRS。ORM使わずにやってみた。
例をシンプルにするために、Event Sourcedな書き込みモデルと、CQRSの読み込みモデルを1スレッドで実行してる。イベントジャーナルとしてLevelDBを、リードモデル用にMySQLを使ってるのでほんのちょっとだけ一貫性がない状態が発生する可能性がある。別々のデータストアを使って、でも、できるだけ一貫性が保てるようにしてみた。
iddd_identityaccess
iddd_common
共通のコードを保持。このやり方は推奨はしないけど、サンプル用には別にいいかな。
テスト
Dockerで環境構築してgradleでテスト実行できるよ。
プロジェクトまとめ
iddd_agilepmを読む
パッケージングがこんな感じ。port/adapterはヘキサゴナルアーキテクチャか。
- application
- domain/model
- port/adapter
applicationパッケージ
- サブパッケージ
- ApplicationServiceLifeCycleってなんぞ?
- アプリケーションサービスの入力パラメータ
- 更新系はCommandオブジェクトを受け取ってる。
- って、このプロジェクトには更新系のサービスしかないや。
- Commandオブジェクトに必要な情報を詰め込んで渡してるんだね。
- 戻り値
- 書き込み系なので基本的にはvoidを返す。
- もしくは、生成されたエンティティのIDだけを返す。
- でも、値オブジェクトじゃなくて文字列を返してる。
- Commandクラス
- リポジトリ
domain/model パッケージ
- サブパッケージ
- モデル
- 生成時のバリデーション
- Productの生成のときにどれくらい入力値チェックしてるのかなー?と思ってみてみたけど、アプリケーションサービスでもモデルでもtenantが存在してるかどうかとかはチェックしてないな。まぁ、tenantがなかったら見えないプロダクトになるだけだから別に悪影響はないか。
- 関連は基本的にモデルではチェックしない、ってことなのかな。
ports/adapter パッケージ
- persistence パッケージにリポジトリの実装が入ってる
- リポジトリからエンティティをどうやって生成してるのかなーって思ったらLevelDBから取得した文字列からDeserializeしてるだけだった。
- messaging パッケージにRabbitMQ周りの実装が入ってる
- キューに対して、アプリケーションサービスを呼び出してるだけだね。
iddd_collaboration
- だいたいパッケージ構成は同じ。
- 腐敗防止層の実装がport/adapterパッケージにある。
- イベントソーシングだから、リポジトリの実装とエンティティのwhenメソッドが面白い。
- 変更イベントをMySQLに適用するために、Dispatchしてて面白い。
- アプリケーションサービスが、CQRSのクエリに対して、SQLを直接MySQLに発行してて面白い。
- クエリの結果を返すクラスの名前はAbcDataみたいにDataサフィックスがついてる。
iddd_identityaccess
RESTインターフェイスがあるくらいかな。
面白かったーーーー!!!学びしかない。