【備忘録】クリーンアーキテクチャ


# はじめに
[【備忘録】オブジェクト指向入門](https://qiita.com/miya1221/items/92ad0933be00e9ac8ef4)
この記事の続きで、今回も備忘録として残します。

# 今回の資料
- [実践クリーンアーキテクチャ 音ズレ修正Ver.【プログラミング】](https://youtu.be/BvzjpAe3d4g?si=ELhancGzJ7ndzU-1)
- [先行開発！Javaでクリーンアーキテクチャ / Clean architecture with java](https://speakerdeck.com/nrslib/clean-architecture-with-java)

# 内容

## ヘキサゴナルアーキテクチャ（Hexagonal Architecture）

- **Application（アプリケーションの本体）**
    - ビジネスロジックやユースケースの中核部分
    - 別名「ポートアンドアダプター」
    - これ以外を交換可能（プラガプル）にする

ゲームを例に説明されているのが、非常にわかりやすくて、説明がすっと入ってくる


## **Clean Architecture（クリーンアーキテクチャ）**

### Entities（エンティティ）  
- Enterprise Business Rules
- ドメインオブジェクト
- ドメイン＝ソフトウェアで解決しようとする対象の領域のこと

ドメインモデルやビジネスルールの核・中心になるところかな。


### Use Cases（ユースケース）  
- Application Business Rules 
- アプリケーションとして、ビジネス上の問題をどう解決するかを定義するようなところ

Entitiesが「どうあるべきか」ならUse Casesは「どうやって解決するか」になるのかな。

### Interface Adapters（インターフェースアダプタ）

- 構成：Controllers, Presenters, Gateways
- 例：
  - Controller：ゲームのコントローラー
  - Presenter：ディスプレイ
  - Gateway：データ保存・Mockなど

## クリーンアーキテクチャにおけるユースケースの処理の流れ（インタラクション）

![スクリーンショット 2025-04-06 14.59.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/392216d1-b443-42d7-9e36-0aa9f33e3cbc.png)
>資料より抜粋(赤枠のところ)


### Frameworks & Drivers（フレームワークとドライバ）  
- 中心（ビジネスロジック）には依存されない
- フレームワークを変更しても、ビジネスロジックに影響しない

DIPってのは、こういうイメージかな
- DIP（Dependency Inversion Principle / 依存性逆転の原則）
    - 決めたルールに合ってれば良い
    - ルール（インターフェース）に頼ることで、使う側と作る側を分けられる
    - 差し替え・変更しやすい

### 依存の方向
- 内側の変更は外側に影響する
- 外側の変更は内側に影響しない
- この設計により、UIやDBが変わってもビジネスロジック（中心部）は変更しなくて済むようになる


## SOLID原則（調べたので一緒にメモ）
- 以下の記事参考

- [イラストで理解するSOLID原則](https://qiita.com/baby-degu/items/d058a62f145235a0f007)
- [SOLID原則完全に理解した！になるための本](https://zenn.dev/nakurei/books/solid-principle-kanzen-rikai/viewer/about)

| 略称 | 原則名                             | 説明                                                |
|------|----------------------------------|---------------------------------------------------------------------|
| S    | 単一責任の原則（SRP）              | 1つのクラスは「1つのこと」だけやる                          |
| O    | オープン・クローズド原則（OCP）     | 拡張できるけど、元のコードは変更しない              |
| L    | リスコフの置換原則（LSP）           | 子クラスは親クラスの代わりになれるようにする                         |
| I    | インターフェース分離の原則（ISP）   | インターフェースは分けよう。必要な機能だけ教える        |
| D    | 依存性逆転の原則（DIP）             | 具体じゃなくて抽象（インターフェース）に依存する       |


## 実装例

- 以下の図を元に実際にコードみながら説明あり。細かい説明でわかりやすい。

![スクリーンショット 2025-04-06 15.18.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/02b3ce9f-c19d-4bda-8ca4-794e76b6b57c.png)
>資料より抜粋

- Controller：アプリケーションが要求するデータに入力を変換
- Input Data：データをまとめて、1つのオブジェクトにしてやり取りするためのもの
- Input Boundary：ユースケースへの入り口(インターフェース)。どういった入力データが必要なのか定義する
- UseCase Interactor：アプリケーションロジック。ビジネスロジックを使って「何をするか」。入力を受けて、処理して、出力するところ
- Data Access Interface：Repositoryのインターフェース。データベースとやりとりをするインターフェイスのこと。クリーンアーキテクチャでいうGatewayになる
- Data Access：データベースと実際にやり取りするコードを書くところ
- Entities：ドメインオブジェクト。データモデルとは違うので注意（LaravelでいうEloquentとは違うって意味なのかな）
- Output Data：ユースケースの結果を外に渡すための入れ物のようなもの。inputと同じようにDTOを定義（データだけを持つ構造体みたいなもの）
- Output Boundary：Presenterインターフェースの定義
- Presenter：ユースケースの結果（OutputData）を、画面に表示する
- ViewModel：「表示用」に整形された、出力専用のDTO
- View：画面、CLI出力、JSONなど

### メモ
- 何がどこに書いてあるかわかること＝整理整頓されているか
- データベースは決まっていないけど、ロジック組みたい時に、構造化して、大元の処理は変わらないので、期待した結果を返すことができるってことかな

## 課題
![スクリーンショット 2025-04-06 16.24.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/0351f3fb-1ed2-4826-afe0-a2449b94df1a.png)
>資料P217より抜粋

### 1.MVC FrameworkでPresenter使えない問題
- MVCフレームワークではPresenterがはさみにくいので、Presenterを捨てて、戻り値で返すようにする。Controllerはちょっと太るけど、守るべきロジックは独立してるためクリーンアーキテクチャの思想には沿っている

### 2.コントローラのフィールド増えすぎ問題
- MessageBus：「やりたいこと（命令）」を、メッセージ（コマンド）として投げて、誰か（ハンドラ）に処理してもらう仕組み。メッセージバスがUseCaseを仲介してくれる仕組みみたいなものかな

### 3.定義するもの多すぎ問題
- 面倒なところは自動生成のツール作成して、解決する

## アーキテクチャの役割
- 「入力→処理→出力」の流れを「どう流すか、どう分けるか」 のルールを整えてるのがアーキテクチャ（レールのような役割）自由に開発できるようにするための線路のようなものってイメージで咀嚼

## 最後に
- 依存関係逆転の原則（DIP）：抽象（＝ルールやインターフェース） は、詳細（＝具体的な実装） に依存しない。詳細が 抽象に従って動くようにする

# まとめ
youtubeと資料みながら、わからないことは調べながら、進めれたと思う。ふわっとしたイメージしかなったけど、ある程度自分の中で落とし込みできたかなと思っている。