【IT】MVCモデル、クリーンアーキテクチャ、オニオンアーキテクチャ、ドメイン駆動開発の関係

徒然草2.0

机上で各技術や設計の関係性・違いを理解するのと、それを実際にコードとして自分の手で実装できるようになることの間には、大きなギャップがあります。

最終的に求められるのは、そうした技術を実装レベルで使いこなすことであり、さらに高い生産性と低コストを両立させ、顧客のビジネスの成功に貢献することです。

また、ユーザーやクライアントの前で「とりあえず動くもの」を素早く作ることと、後々のテストや保守がしやすいような優れた設計にすることの間にも、やはり大きな隔たりがあります。

しかし、近年ではそのような「動くこと」と「保守性・品質」とのトレードオフがあること自体が前提とされており、むしろエンジニアの側がそのバランスを理解し、意識的に切り分けて取り組むことが求められています⋯とはいえ、それを丁寧に具体的に解説してくれる人はあまりおらず、実際には興味を持ったエンジニアが、現場や自習を通じて自分の経験として身につけていくしかない、というのが現状ではないでしょうか。

たとえば、プロトタイプレベルの荒削りな実装を、実際に本番環境で動く安定したシステムに作り変える必要があったり、あるいは前任者が残したひどい設計・コードを「作り直したほうが早いですね」とは言わず(言えず)に、地道にリファクタリングして保守していかなければならない、といった無茶な要求に応える場面も少なくありません(でした。と過去形にしたい)。

また、ジュニアレベルのエンジニアでチームに貢献をするにしても、このへんのバランスを分かっていないといけないこともあり、動くものと保守しやすいものに温度感を感じたりしないでしょうか?Frameworkにおんぶでだっこでそれとなく個々の問題に向き合っていればどうにかなる感じ?であればいいのですが。

⋯私たちは、短いサイクルでスプリントを回すアジャイル開発を「これが僕たちのやり方です」と営業が自信たっぷりに語れるように、現場では残業続きで生活が破綻しないよう、必要な汗をかくことになります。それが本当に必要な努力であればまだ救いがありますが、できれば「無駄な汗」をかくことは避けたいものです。汗が血に変わるデスマだけは、避けなければなりません。

⋯ソフトウェア開発に携わるエンジニアならばマストなのに分かった風になっている、MVCモデル、オニオンアーキテクチャ、そしてドメイン駆動開発について改めてまとめておきたい。これらは違うもののはずなのに(と私だけが思い込んでいるのかもしれないが、)それぞれが相互関係にあって、まるで同じもののように語られることがあります。

ソフトウェア開発の現場責任者が語る文脈に定義を合わせれば特段困りませんが、自分の頭の中では切り分けておいたほうがよいでしょう。

MVCモデルとは?

MVCモデルはプレゼンテーション層(UI層)の責務を分離する考え方。

小規模なシステムの場合はモデルにインフラストラクチャ(DB接続とか)やビジネスドメイン(各ユースケースに関する処理)が入り込むことがある。

そして、モデルに責務を集中させることで、コードの見通しをよくする。

逆に言えば「コントローラが肥大化しないようにして」とか「ビューにロジックを組まないようにして」という、当たり前なことが守られていれば、とりまOKとされるようなWebアプリケーションばかりに携わっていてかつ机上の知識が身についていない⋯端的に勉強不足だと、レイヤードアーキテクチャやドメイン駆動開発についての関係性が見えなくなりがちである(私の個人的な課題である)。

繰り返しになるが、あくまでMVCモデルは画面部分でレイヤードアーキテクチャで言えば、プレゼンテーション層(またはUI層)レベルの構成に関する文脈で語られるものと捉えておくこと。そうでないと、なかなかDDDやクリーンアーキテクチャが理解できない。

ドメイン駆動開発(DDD)とは?

ここが最も誤解されやすい点だと思うので先に述べると、DDDはレイヤードアーキテクチャと相互運用されるが、DDD自体がレイヤードアーキテクチャではない。

DDD(ドメイン駆動設計)は、設計思想であり戦略的なアプローチであって、レイヤードアーキテクチャはそれを実装するためのパターンのひとつにすぎない。

DDDの本質は、ドメイン(業務知識)に深く根ざしたモデルを中心にシステムを設計・開発することにある。そしてその過程では、チーム全体が共通言語(ユビキタス言語)を使い、継続的にソフトウェアを育てていくことが重要な特徴となる。

ドメインモデルは、業務上のルール・概念・振る舞いを明示的にコードに落とし込んだものであり、エンティティ、値オブジェクト、集約、ドメインサービスといった要素で構成される。

また、ドメインは「ユースケース(使われ方)」によって切り分けて考える必要があり、これがアーキテクチャ的には「アプリケーション層(ユースケース)とドメイン層(業務知識)」に分離される。こうした層の分け方は、採用するアーキテクチャパターン(例:レイヤード、クリーン、オニオンなど)によって名称や構造が多少変わってくる。

DDDの思想と、レイヤードアーキテクチャなどの構造的なパターンは混同されがちだが、それぞれの役割を切り分けて理解しておくと設計の選択肢が広がる。仕事上は厳密に区別しなくても困らないことが多いが、設計力を高めたいなら意識しておくとよいだろう。

参考:「ドメイン駆動設計を知る必要があるのか」→結論:現場で意識している人あまりいない。→ユビキタス言語を整備し、ドメインエキスパートと協働するのは、ユーザーとエンジニアの認識のギャップを埋めるため。エンジニアだけがDDDを意識して設計しても、片手落ちのDDDになる。DDDの本質は、ドメインに関する対話とモデリングにあり、コーディング手法やアーキテクチャのパターンは本質ではない。

レイヤードアーキテクチャ

クリーンアーキテクチャやオニオンベースアーキテクチャはレイヤードアーキテクチャの一種でいろいろなタイプのアーキテクチャがある。

クリーンアーキテクチャ

ビジネスロジックを他の要素と分離する。中央にエンティティ/ドメインモデルがあり、その外側にアプリケーション/ユースケースを持ち、その外側にインターフェースを持つ。さらにその外側にプレゼンテーション層を持つ。

特にこの4層でなければならないという決まりがあるわけではなく、開発現場により呼び名は様々。あくまで層を構成しており結合関係を中央に向かって定義するところに大きな特徴がある。

オニオンアーキテクチャ

クリーンアーキテクチャとほぼ同じだが違う人物が提唱した概念で、ヘキサゴナルアーキテクチャとも親和性が高い。クリーンアーキテクチャかオニオンアーキテクチャかで区別するよりは、DIPや分離原則を守った設計にすることが望ましい。

ヘキサゴナルアーキテクチャ

提唱者が六角形で図示したのでヘキサゴナルアーキテクチャと呼ばれるが、ポートとアダプタからなるモジュールの疎結合化が主な特徴のため、ポート&アダプタ アーキテクチャという。この名称の方が先であるらしい。現在のところあまり仕事の現場では出会わないと思われ、そういうものがある程度に記憶に留めておけばいいのではないか。

MVCモデルのその先は?

どのアーキテクチャで開発するのがいいのか?についてMVCモデルでなんとなく開発していた人は、とりあえず以下のように実装がオススメといえるのではないか?(これはオニオンアーキテクチャの一種だと言える)

「プレゼンテーション層」→「ユースケース層」→「ドメイン層」←「インフラストラクチャ層」

※ユースケース層でドメインの切り分けをする場合には、インフラストラクチャ層からユースケース層に向く矢印を発生させてもよい。

徒然草2.0
スポンサーリンク
シェアする
gomiryoをフォローする
ごみぶろぐ

コメント

タイトルとURLをコピーしました