前回
- こちら
- DDDの考えというものを説明しました。
- 軽量DDDとは何なのかについて説明しました。
今回
- 複数のアーキテクチャを比較して、軽量DDDを実現するためにはどうすれば良いのか話していきます。
- 今回の内容は軽量DDDというものになりますので、軽量DDDとDDDの違いが分からない方はこちらをみるべきと思います。
参考
Layered Architecture
これはDDDの中で紹介されたアーキテクチャです。これからのアーキテクチャを説明する上で重要な要素があります。
- 各層の用語の意味
- 依存関係がはっきりと決まっている
順番に説明していきます。
各層の用語の意味
- UI層
- ユーザーから見える部分のコードを担当する層(例えばマークアップ言語は完全にここな気がする)
- Application層
- データを加工してUI層が扱いやすくするための層。例えば、created_atにunixtimeで時刻が保存されているとしても、そのままの表示をすることは少ない。そのためにここの層で月日だけを取り出してUI層に渡す。
- Domain層
- ビジネスロジックが含まれる層のことで、ここでドメイン解決のためのコードが書かれます。
- Infrastructure層
- データとのやりとりを担当する層。保存したり取得したりする。
個人的にはApplication層には他のアプリでも流用できるような、汎用性の高いコードがくるんじゃないかと思います。例えば時刻変換といった作業は他のアプリでも使うことができますよね。それとは対照的にドメイン層とは、そのプロダクトオリジナルのコードがここにくるんじゃないかと思います。だからもし、時刻変換で少し複雑そうなことをした場合はドメイン層に置くのが正解の時もあると思います。
依存関係がはっきりと決まっている
「依存関係は上の層から下の層のみ許可する」とは、Domain層からApplication層のメソッドや関数を呼ぶといったことが無いようにすると言うことです。なぜこのようにするのかと言うと、前回お話しした1番や3番を達成するためです。DDDとはドメインを元にアジャイルにプロダクトを更新していくものですから、若干の方針変更によるApplication層の更新はドメインに影響させたくない訳です。またプログラマーを層ごとに分けて効率よく開発していきたいのに、層がめちゃくちゃな依存関係だと、アプリが出来上がりませんし、テストも切り分けて行いにくいです。
さて、このモデルはDDDを忠実に再現できているでしょうか?
答えは、まだ改善の余地ありです。理由としては、DDDはドメインが中心の世界であるはずなのにインフラ層に依存してしまっていますね。また、ドメイン層の役割が大きすぎるように思います。
ただし、層分けしたことと、依存関係をはっきりさせたことにとても意味があったという事実を忘れないでください。
Hexagonal architecture
これは見ただけではあまり意味が分からないと思います。ただし、層分けしたことと、依存関係をはっきりさせたことを引き継いでいることに留意してください。ポイントは2つあります。
- ドメインを依存の中心に置いている
- 図が抽象化されている
順番に説明していきます。
ドメインを依存の中心に置いている
先ほどのLayered Architectureでは結局インフラが中心となってしまっていて、データベースの種類や、フレームワークなどにドメインが依存する形となってしまっていました。それを改善したのがこの図となっています。ただしデータの取得方法に依存しないコードの書き方というのは少し想像がしにくいです。ここの解決方法は次回の記事にしたいと思います。(<=更新したらリンクが貼られているはず)
図が抽象化されている
層に名前が付いていますが、Domain ModelとApplicationとそれ以外の3つしかありません。これはどういうことなのかというと、最低限この3つを満たしてアーキテクチャを構成しようということで、ひたすらドメインを中心に置くべき!と主張しているに過ぎないです。これを雛形としてクリーンアーキテクチャやオニオンアーキテクチャが存在しています。これでは抽象化され過ぎているということで、次はオニオンアーキテクチャを見てみましょう。
Onion architecture
やっとここまできました。これまでの考え方を全て引き継いでいることに留意してください。層分けしたことと、依存関係をはっきりさせたこととドメインを依存の中心に置いていること抽象化された概念を引き継いでいることこの4つです。
ここでのポイントは2つあります。
- Domain層が2つに分かれた
- 具体化した
Domain層が2つに分かれた
一番最初のLayered Architectureはなんだかんだ言ってDomain層の役割が大き過ぎました。例えば、データのモデルを定義するのもDomain層でしたし、ビジネスロジックを実装するのもそこでした。これを切り分けるためにDomain層をModelとServiceに分けてあげたというのがこのアーキテクチャです。
具体化した
ヘキサゴナルアーキテクチャと比べて、図が具体化したと思います。つまり、ヘキサゴナルアーキテクチャとオニオンアーキテクチャまたはクリーンアーキテクチャは本質的には同じことを表していて、その表現方法がそれぞれ違ったというだけなのです。本質的なドメインを依存の中心に置くという考えは変わっていません。
まとめ
- 複数のアーキテクチャを比較し、それぞれがどのような主張をしているのか話した
- 層分けしたこと、依存関係をはっきりさせたこと、ドメインを依存の中心に置いていること(Layered Architectureはまだ甘かったがその意思は感じる)がこれらのアーキテクチャで共通していることを話した
次回
- これらのアーキテクチャでどうやってインフラに依存しないドメインを形成するのかについてコードを交えて話したいと思います。次回の記事(<=更新したらリンクが貼られているはず)