2022-08-15 投稿

〜MVCとDDD〜設計手法を学んで脱初級者を目指そう

エンジニアを始めたての頃、Webアプリケーション開発といえばMVCに従うことが正しいと思い込んでいました。 そこから一歩脱却し、設計手法のひとつであるDDD(ドメイン駆動設計)の考え方とMVCのそれを比較しながら、良い設計とは何かを考えたいと思います。

MVC(Model-View-Controller)

アプリケーションをデータ層を扱うモデル(Model)、ユーザーインターフェースを扱うビュー(View)、 そしてその仲介を行うコントローラー(Controller)に分別したもの。 1970年代後半ごろに生まれた、ある意味伝統的な設計手法である。

やりがちな失敗

ビューやコントローラにだらだらとロジックを書いてしまいがち。 コントローラの一つのメソッドが数十行単位になってしまっているのはよく見る。 共通の処理はメソッドに切り出したり、親クラスに持たせたりするなどして、コントローラーではなるべくビジネスロジックを書かないほうがいい。 そして、データに直接関係するロジックについてはモデルに書くのが望ましい。

MVCに+αがあるとコードの見通しがよくなる

そのDBテーブルに関連するビジネスロジックはモデルに書くのがいいと書いた。 ただし、複数のテーブルやモデルにまたがる処理というのがどうしても出てくる。 その場合はあらたにサービス(Service)などの層を作り、そこにビジネスロジックを書くと綺麗にまとまることが多い。

サードパーティライブラリや、ビジネスロジックと直接関係ない処理(例えば住所と緯度経度の変換処理など)については、 ヘルパー(Helper)などに分けるほうが良い。サービス(Service)と立ち位置は似ているが、あくまでアプリケーションの処理を補助するもの、という意味あいが強くなる。

DDD(Domain-Driven Design)

DDDでは、よりビジネスロジックに焦点を当てている。 システム化の対象とするビジネスから、ドメインという要素(例えば「ユーザー」「商品」など)を抽出し、それぞれのドメインの定義やふるまいなどを コードで表現していく。うまく導入できればコード自体が仕様書になるくらい見通しの良さが得られる。

また、直接DDDと関係があるわけではないが、「依存関係逆転の原則」という言葉がDDDの文脈でよく出てくる。 これは、従来のWebシステムがデータアクセス層などに依存する(モデルが一番上流にあり、ビジネスロジックがそれに従う)という考え方から、 (ビジネスロジックを担うドメインが最上流にあり、データアクセス層を含め、その他の要素がそれに従う)という考え方に逆転するというものである。

コード上では、ビジネスロジック層がデータアクセス層を継承するのではなく、データアクセス層がビジネスロジック層を継承することになる。 これにより、ドメインが個別のRDBMSに依存しないコードを書けることになる。

DDDの問題点

DDDを真面目に実践しようとすると、コード量がかなり莫大になるので、立ち上げ時は大変な傾向がある。 (コードがドキュメント化するので、うまく導入できれば運用コストは下げることができる。) またMVCに則ったフレームワークを使っている場合、その良さや便利さを打ち消してしまうことがある。 フレームワークの良さとDDD等の設計手法の良さの両方のバランスをとった設計を試行錯誤して見つけるのが良いのではないかと思う。