実務Webアプリ開発編です。前回まではPart II(要件定義と設計)で、MentorApp の要件定義と設計を通して、何を作るかを整理してきました。

今回からPart III(アーキテクチャ概論) に入り、最初にクリーンアーキテクチャの考え方を学びます。

この記事では、4層構成の役割依存方向のルール、そして具体的な題材(MentorApp)でその考え方がどう形になっているかを見ていきます。

以下のような方に役立つ内容となっています。

  • アプリが大きくなるとコードが散らかってしまい、整理の考え方を知りたい
  • クリーンアーキテクチャという言葉は聞くが、何がうれしいのかまだ腹落ちしていない
  • 実際のプロジェクトで Domain / Application / Infrastructure / Web をどう分けるのか知りたい

以下のようなMentorAppを題材として進めます。

GitHubにドキュメント・コードの一式があります。

プロ太

クリーンアーキテクチャは、コードをフォルダに分けて整理するためだけのものではありません。

変更しやすく、テストしやすく、長く育てやすい構造を作るための考え方です。一緒に整理していきましょう。

なぜクリーンアーキテクチャが必要なのか

小さなアプリを作るときは、画面から直接データベースにアクセスしても、とりあえず動かせます。

ですが機能が増えると、画面・業務ルール・データアクセスが一か所に混ざり、修正のたびに影響範囲が読みにくくなります。

たとえば「ユーザーのロール変更操作に制約を付けたいと思っても、そのロジックが UI のコードや DB アクセスのコードの中に埋まっていると、安心して直しにくくなります。

この「影響範囲が読みにくい」という問題は、コードが互いに絡み合って依存し合っていることが根本原因です。

クリーンアーキテクチャは、こうした混線を避けるために、責務ごとに層を分け、依存の向きを制御する考え方です。

プロ美

とりあえず動くなら、そのままでもよさそうに見えるけど、何が困るの?

プロ太

最初は困らなくても、変更が入った瞬間に困りやすいです。今の修正がどこまで波及するかが読めない構造になるからです。

特に MentorApp のように、認証・永続化・画面・ドメインルール(アプリ固有の業務上の決まりごと)をすべて持つアプリでは、最初から整理しておく価値があります。

クリーンアーキテクチャの基本

クリーンアーキテクチャでは、アプリをいくつかの層に分けます。この構造は同心円のようにイメージするとわかりやすいです。

中心を「内側」、周囲を「外側」と呼び、大事なのは単に分けることよりも、外側の詳細に内側が振り回されないようにすることです。

データベース、Web フレームワーク、認証プロバイダーのような技術要素は便利ですが、将来変わる可能性があります。

一方で、「このアプリは何を守るべきか」という業務ルールは、アプリの中心に置きたい情報です。

そのため、クリーンアーキテクチャでは中心に近いほど本質的なルール、外側ほど技術的な詳細を置きます。

ここで重要なのは、層が縦に一列につながることではなく、依存の向きが常に外側から内側へ向くことです。

以下はDomain・Application・Infrastructure・Web の4層を例にした概念的なイメージです(この4層構成はよく使われる代表例です。各層詳細は次のセクションで説明します。)

各層のうち、Domain(中心の層)はデータベースライブラリや UI フレームワーク・認証といった外側の技術を知りません。逆にWeb側は、必要に応じて内側の層を利用します。

プロ美

外側の層は内側を使える」けど、「内側は外側を知らない」ようにするってことだね。

プロ太

その理解で大丈夫です。これにより、UI や DB の変更があっても、ドメインの考え方を守りやすくなります

4層それぞれの役割

クリーンアーキテクチャでは、アプリを役割ごとの層(レイヤー)に分けて構成します。代表的な構成として、Domain・Application・Infrastructure・Web の 4 層があります。

それぞれの層に置くものを最初にざっくり決めておくと、コードの置き場で迷いにくくなります。

主な役割置くものの例
Domainビジネスルールの中心を表現するエンティティ、値オブジェクト、ドメインサービス、リポジトリインターフェース
Applicationユースケースを組み立てるアプリケーションサービス、DTO、入力と出力の契約
Infrastructure外部技術との接続を担当するEF Core 実装、認証実装、永続化、DI 登録
Webユーザーとの接点を担当する画面コンポーネント(Blazor など)、コントローラー(Web API の場合)、ルーティング定義、エントリポイント

表中の用語や技術名に馴染みがなくても問題ありません。それぞれの詳細は、Part IV 以降の実装編で順を追って扱っていきます。

Domain は、このアプリで何が正しい状態かを表す場所です。

Application は、画面や API から受け取った操作を、どの順番でドメインに流すかを整理する場所です。いわばユースケースの司令塔です。

Infrastructure は、データベース保存や外部認証のような技術的な実装詳細を引き受けます。

Web は、Blazor の画面やルーティングなど、ユーザーに見える入口を担当します。

初心者のうちは「どの層にもロジックを書けそう」に感じやすいです。

迷ったら、その処理は業務ルールか、ユースケースの流れか、技術実装か、画面表示かを問い直すと整理しやすくなります。

プロ太

実際の開発では、フレームワーク都合・実装スピード・チームメンバの理解度等によって、完全な責務分離は現実的ではない場合も多いです。

実務では「理想を知ったうえで、どこを守り、どこを割り切るかを決める」ということが重要になります。

このような判断については、Part IV 以降(実装)で具体的に解説します。

依存方向のルールが重要な理由

クリーンアーキテクチャで特に重要なのは、層の名前よりも依存方向のルールです。

もしDomainがDBライブラリ(EF Core など)やUI フレームワーク(Blazorなど)に直接依存すると、ビジネスルールがフレームワーク都合に引っ張られやすくなります。

すると、テストを小さく書きにくくなったり、別の UI や保存方法へ差し替えにくくなったりします。

逆に、内側を独立させておくと、外側の都合を切り離しやすくなります。

  • 変更に強い:UI や DB の変更が、中心のルールへ波及しにくい
  • テストしやすい:ドメインやユースケースを外部依存なしで確認しやすい
  • 責務が見えやすい:どこに何を書くべきかを判断しやすい

もちろん、層を増やせば自動的に良くなるわけではありません。大事なのは、依存の向きが守られているかと、各層が本来の責務からはみ出していないかです。

プロ美

「4層に分かれている」より、「どちら向きに依存しているか」のほうが本質なんだね。

プロ太

その通りです。見た目だけ層を分けても、内側が外側に依存していたら、保守しやすさはあまり得られません。

MentorApp ではどう対応しているか

MentorApp のソリューションは、クリーンアーキテクチャの考え方に沿って、プロジェクト単位で構成されています。

実際のフォルダ構成を見ると、4 層がそのまま src 配下のプロジェクトとして分かれています。

src/
├── MentorApp.Domain
├── MentorApp.Application
├── MentorApp.Infrastructure
└── MentorApp.Web

依存関係も、内側へ向かう形で整理されています。

MentorApp.Domain          ← 依存なし
MentorApp.Application     ← Domain を参照
MentorApp.Infrastructure  ← Domain, Application を参照
MentorApp.Web             ← Domain, Application, Infrastructure を参照

ここで注目したいのは、Domain が単独で存在している点です。

ビジネスルールの中心を、Web や EF Core から切り離して置くことで、次回から扱う DDD(ドメイン駆動設計)の考え方による実装とも相性が良くなります。

また、Application にはユースケース(例:「メンタリング申請を受け付けて承認する」といった一連の操作の流れ)が置かれます。

そして、Infrastructure には EF Core や OIDC(OpenID Connect:認証プロトコル)の実装、Web には Blazor の画面がそれぞれ置かれます。

つまり MentorApp は、4 層構成を単なる説明図で終わらせず、プロジェクト構成として実際に反映しているわけです。

プロ美

こういう構造になっていると「その処理は Domain ではなく Application では?」みたいに、レビューのときも責務基準で会話しやすそうだね!

次回以降は、この土台のうえでDDD の用語や実装パターンを見ていきます。ここで全体像を持っておくと、後のコードがかなり読みやすくなります。

まとめ

クリーンアーキテクチャは、アプリを長く育てていくために、責務の分離と依存方向の制御を行う考え方です。

特に重要なのは、中心にある Domain を外側の技術詳細から守ることです。その結果として、変更しやすさとテストしやすさが得られます。

  • クリーンアーキテクチャの目的:変更しやすく、保守しやすい構造を作ること
  • 4層の基本:Domain / Application / Infrastructure / Web に役割を分ける
  • 依存方向のルール:外側から内側へ依存し、内側は外側を知らない
  • MentorApp での実例:4つのプロジェクト構成として実際に反映されている

次回は、クリーンアーキテクチャの中心に置かれるDDDの考え方を整理していきます。

プロ太

クリーンアーキテクチャは、あとで楽をするための整理術です。構造の意味が見えると、実装の一つひとつがぐっと理解しやすくなります。

引き続き、ドメイン駆動設計(DDD)の考え方について一緒に学んでいきましょう!

ABOUT ME
プロ太
ソフトウェア開発を楽しく、効率的に行う方法を追求しています。 開発者の視点から技術的課題に向き合い、「純粋な技術的興味に基づく探求」と「実践的な課題解決」という二つの柱を両輪として活動しています。