多層アーキテクチャにおける責務の分離とレビューの位置づけ
はじめに
多層アーキテクチャ(Layered Architecture)は、機能の関心ごとを層ごとに分離することで、変更に強く再利用しやすい設計を実現する手法である。
MVCやDDD、クリーンアーキテクチャなどはその代表的な応用例だ。
しかし、実際の現場ではこの層の責務が曖昧になり、コードの属人化や保守困難性を招く事例が後を絶たない。
レビューアーはこのような構造に対し、機能コードではなくアーキテクチャ的責務配置の妥当性を評価する立場にある。
本稿では、その際に用いる視点・指摘方法・典型的な失敗パターンを明確にする。
層構造の役割を再確認する
まず基本的な構造と役割を押さえておく。以下は典型的な3層構造(Controller / UseCase / Repository)をモデル化したものだ。
各層の責務は次のように定義される。
| 層 | 主な責務 |
|---|---|
| Controller層 | リクエストの受信と入力バリデーション |
| UseCase層 | 業務ロジック(アプリケーションの振る舞い) |
| Repository層 | DB・外部APIアクセスなどの永続化処理 |
この役割分担を崩さないことが、構造保守性の鍵となる。
典型的な責務混在パターンとレビュー観点
Controller肥大化:ユースケースが侵食される構造
Controller内に複雑なビジネスロジックが記述されている場合、それはユースケース層が設計上存在していても機能的に不在であることを意味する。
def register_user():
data = request.json
if not validate_email(data['email']):
return {"error": "Invalid email"}, 400
hashed = hash_password(data['password'])
db.insert_user(data['name'], data['email'], hashed)
return {"status": "ok"}, 201@Reviewer: 入力検証・ハッシュ化・DB登録と、複数の責務が1関数に混在しています。ユースケース層への分離が必要です。レビュー視点:
- DBや暗号処理など、アプリケーション全体で再利用可能なロジックがControllerに直書きされていないか?
- Controllerが複数の関心事を持ち始めていないか?
UseCase層の中立性喪失:ドメインを持たないサービスの乱立
UseCase層がただのServiceクラスの集合になり、ロジックを受け渡すだけのパイプと化している構造も危険である。
本来この層は「なぜその処理をするか」「どんな条件で失敗するか」といった業務上の振る舞い判断を行う責任がある。
class UserService:
def create_user(self, data):
return self.repo.save(data)@Reviewer: 本クラスはデータ転送に終始しており、ユースケース層の判断責務が存在していません。エラー条件やルール処理を定義すべき箇所です。レビュー視点:
- ユースケースが単なるCRUD操作の中継点になっていないか?
- 処理の判断(バリデーション、条件分岐、例外補足)は適切にここで担われているか?
Repository越境:外部アクセスロジックの漏れ
Repository層が担うべき外部データ取得や永続化処理が、ユースケース層やControllerに無意識に分散して記述されているケースも多い。
class RegisterUserUseCase:
def execute(self, data):
user = create_user_entity(data)
if not check_blacklist(user.email): # 外部API呼び出し
raise ValueError("Blocked")
self.repo.save(user)@Reviewer: ブラックリストチェックは外部システム依存であり、RepositoryまたはGateway層での実装が適切です。レビュー視点:
- I/O処理(DB・API・メール送信など)が責務を越えて書かれていないか?
- ユースケース層に「知っているべきでない技術的詳細」が混入していないか?
層の分離が破綻する原因と背景
責務の混在は偶発的に起こるのではなく、以下のような開発文脈の中で発生しやすい。
- 開発初期にアーキテクチャ設計が明文化されていない
- ユースケースが形骸化し、単なるService呼び出し層となる
- フレームワーク主導の構造に過剰依存している(Django, Railsなど)
- レビュー時に層の役割まで踏み込んで議論されていない
設計ルールが共有されていない場合、どこに処理を置くべきかが属人判断になり、チームの構造的な品質が揺らぐ。
レビュー時に見るべき層構造チェック観点
- Controllerがユースケースを通さず、直接DBやAPI呼び出ししていないか?
- UseCaseにルール判断・状態管理・例外処理が書かれているか?
- Repository層が単なるラッパーに終わらず、I/Oと抽象層をきちんと分離しているか?
- 「層」の粒度が一定か?(層間でコード量や密度の極端な偏りはないか?)
- 逆依存(ドメイン層がインフラ層に依存するなど)が混入していないか?
補助視点:ドメインの方向性と構造への介入度
レビューアーとしては、コード単体ではなく設計思想や責務配置の意図を感じ取る必要がある。
たとえば以下のような判断を行うことで、コードの「違和感」に論理的根拠を与えることができる。
- この処理は「いつでも変わるもの」か、それとも「安定した業務仕様」か?
- このコードは「ビジネス判断」か、それとも「技術的手段」か?
- 今後他のユースケースでも使われる抽象か?
おわりに
多層アーキテクチャをレビューするとは、単に層の存在を確認することではない。
それぞれの層に与えられた責務が守られているか、越境が発生していないか、設計意図が構造に宿っているかを読み取る行為である。
コードの中に設計図があるとは限らない。
レビューアーはその構造を読み解き、必要であれば設計そのものにフィードバックを返す視点を持つことが求められる。
