バックエンド開発におけるアーキテクチャパターンの選択と実践
はじめに
これまでバックエンド開発を中心に仕事をしてきた中で、最初にクリーンアーキテクチャを採用したプロジェクトがありました。それ以来、このアーキテクチャを使い続けてきたんですが、振り返ってみると、毎回クリーンアーキテクチャが最善の選択だったのか疑問に感じることもありました。そこで、アーキテクチャの本質をもう少し深く理解したいと思い、この記事を書いています。
この記事は、私自身の学びを整理した内容なので、他の方法を否定するものではありません。間違いやアドバイスがあれば、ぜひ優しく教えてもらえると嬉しいです🙏
前提知識
ここでは、理解するための前提知識をざっくりとまとめておきます。
関心の分離
- 凝集性
- 関連性の強い要素がまとまっている度合いのこと。
- 結合性
- 異なる責務を持つ要素同士が強く関連してしまう状態のこと。
- 依存性
- 一方が他方に依存する関係性のこと。
SOLID原則
https://qiita.com/baby-degu/items/d058a62f145235a0f007
個人的に納得した考え方
バックエンドのアーキテクチャには、ヘキサゴナルアーキテクチャ、レイヤードアーキテクチャ、オニオンアーキテクチャ、クリーンアーキテクチャなどいくつかの種類があります。どれもSOLID原則、特に単一責任原則と依存性反転原則を実現することを目指しています。単一責任原則は、単体テストをシンプルにするのに役立ち、依存性反転原則はダミーオブジェクトやモックを使ってテストを簡単にしてくれます。これらの原則を守ることで、将来的に外部モジュールやデータベースの技術的変更が楽になることも期待できます。
また、オニオンアーキテクチャやクリーンアーキテクチャは、DDD(ドメイン駆動設計)との相性も良く、DDDを採用するプロジェクトでは特に好まれます。さらに、これらのアーキテクチャを使うと、ファイル配置や記述方法が統一されるため、チーム全体でコードを理解しやすくなり、デバッグの効率も上がります。
結局のところ、単一責任原則と依存性反転原則が守れれば、特定のアーキテクチャにこだわる必要はなく、アーキテクチャ通りに実装しなくても問題ありません。ただし、アーキテクチャに忠実に実装すること自体にもメリットがあるので、プロジェクトのニーズやチームのスキルに応じて判断すると良いと思います。
プロジェクトの規模が小さくて、素早いデリバリーが求められる場合、従来はレイヤードアーキテクチャが使いやすいと言われてきました。しかし、最近ではGitHub Copilotや他のAIツールの進化により、冗長なコードや開発スピードの低下といったクリーンアーキテクチャのデメリットがかなり軽減されています。そのため、プロジェクトの規模が小さくても、クリーンアーキテクチャのディレクトリ構成のテンプレートを作成し使いまわすという方法も十分に有効だと思います。
アーキテクチャの関係性を個人的な解釈で図解
アーキテクチャを使用するメリット・デメリット
メリット
- テストがしやすい
- 技術的な柔軟性
- 技術スタックの変更や更新がスムーズに行える。
- ルールに基づいた開発
- 方針が明確になり、無秩序に開発するのではなく、ルールに沿ってコードが書けるようになる。これにより、エンジニアはルールの範囲内で自由に開発できる。
- コードの理解が進む
- コードの配置が規則的なので、新しいメンバーでもコードを理解しやすい。
- デバッグが楽になる
- どこに何が書かれているかが分かりやすいので、問題の特定と解決がスムーズ。
デメリット
- 実装が冗長になりがち[1]
それぞれのアーキテクチャについて
1.レイヤードアーキテクチャ
出展) https://www.researchgate.net/figure/DDD-Layered-Architecture-2_fig3_353246528
レイヤードアーキテクチャは、1990年代から一般的に使われているアーキテクチャです。このアーキテクチャは、アプリケーションをプレゼンテーション、ビジネスロジック、データアクセス、サービスといった層に分けることで、開発の簡素化やコンポーネントの再利用を促進します。
この設計では、上層が下層に依存し、下層は上層を意識しない構造になっています。
問題点
ドメイン層がインフラ層に依存しているため、特定のデータベースやライブラリに依存しやすく、アーキテクチャの柔軟性が制限されることがあります。
2. ヘキサゴナルアーキテクチャ
ヘキサゴナルアーキテクチャは2000年代初頭にAlistair Cockburnが提唱しました。このアーキテクチャの目的は、アプリケーションのビジネスロジックを外部要素から隔離して、テストをしやすくすることです。「ポート&アダプター」とも呼ばれ、コアとなる部分がポートを通じて外部コンポーネントと接続します。これにより、外部依存に左右されず、ビジネスロジックを効率的に開発できます。
3. オニオンアーキテクチャ
オニオンアーキテクチャは、2008年にJeffrey Palermoが提案したもので、アプリケーションの中心にドメインモデルを置き、外側にアプリケーション層やインフラ層を配置します。これによって、ドメインロジックが外部の影響を受けにくくなります。ヘキサゴナルアーキテクチャと似た構造ですが、よりドメイン中心の設計を重視しています。
https://www.youtube.com/watch?v=80NeuPXs2J0&list=PLXMIJq1G-_66F9woQpidJfe4HHCFxdXaA&index=6
4. クリーンアーキテクチャ
クリーンアーキテクチャは2012年にロバート・マーティン(Uncle Bob)が提唱しました。オニオンアーキテクチャの原則をさらに進化させ、全層にわたる依
存性の逆転を徹底しています。これにより、外部の変更がビジネスロジックに影響を与えにくくし、アプリケーションの独立性とテストのしやすさを高めています。
DDDとは
ドメイン駆動設計(DDD)は、2003年にエリック・エヴァンスによって提唱された手法です。ビジネスの複雑さをモデル化し、そのモデルを中心にソフトウェア開発を進めます。クリーンアーキテクチャやオニオンアーキテクチャとの相性が良く、複雑なビジネスドメインをリッチなドメインモデルで表現していくことを目指しています。
(※このセクションは今後のアップデートで詳細を追加予定です。)
https://www.youtube.com/watch?v=HgtCKlOzRiQ&list=PLXMIJq1G-_66F9woQpidJfe4HHCFxdXaA&index=3
参照
https://www.youtube.com/watch?v=yVPNvfpH_qU&t=73s
-
ただし、AIツールの進化でこのデメリットはかなり減少している(例:GitHub Copilot) ↩︎
Discussion