初学者がクリーンアーキテクチャを学ぶ前に知っておいたほうがいいと思う4つのこと

# はじめに

この記事は**[and factory Advent Calendar 2019](https://qiita.com/advent-calendar/2019/andfactory)**の**22日目の記事**です
ちなみに明日も[別のアドベントカレンダー](https://qiita.com/advent-calendar/2019/laravel)入ってたせいで大変な状態になってます。

# クリーンアーキテクチャを学ぶ前に知りたかった知識

自分が勉強する際にいろいろな方が書かれたクリーンアーキテクチャの記事をあさってた時、ほとんどの説明があらゆる知識を把握している前提で書かれているのが多かった為、すんなりと頭に入ってこず理解できなかったことがほとんどでした。
前提知識を学んで再度クリーンアーキテクチャについて調べると**何となくわかってきた（？）**ので、自分的に事前に知っておきたかった知識についてここでまとめておきます。
どこかの誰かの学習時間の短縮になれば我幸いです。

（特に自分みたいにLaravelやRailsなどフレームワークのMVCパターンしかやったことがない方とかには参考になるのではないかと勝手に思ってます。）

# クリーンアーキテクチャとは

**Robert C. Martin**さんが2012年に提唱した**アーキテクチャ**（ここではアプリケーションの構造を指す）のことです。

以下の図が有名ですね
![CleanArchitecture.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85815/21a042b0-6d4f-0319-e7ad-ff5d2879ab55.jpeg)

- [Clean Coder Blog - The Clean Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)

**日本語翻訳版**

- [クリーンアーキテクチャ(The Clean Architecture翻訳) | blog.tai2.net](https://blog.tai2.net/the_clean_architecture.html)

最初、日本語訳を読んだ時「**んーなるほど完全に理解した**」状態になると思いますが一度は読んでおきましょう

# そもそもの話

## ①「レイヤードアーキテクチャ」というのがある

**アーキテクチャの一つで昔から存在する「レイヤードアーキテクチャ」**というものがあります

![コメント 2019-12-18 105010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85815/5b55ee94-9578-533a-41a1-de19c0aebd0e.png)

- レイヤごとに関心関心事を分離する
- 上位のレイヤは下位のレイヤにのみ依存する※
  - ※[1分でわかる依存関係逆転の原則(DIP) - Qiita](https://qiita.com/wanko5296/items/29e74cc7dd7562624d08)

ということが基本的なルールみたいで、MVCパターンに慣れている方なら何となくわかってもらえるかと思います。
超簡単に言うと、「**処理の種類やコードによって書く場所を分けて整理整頓しよう**」という考えのアーキテクチャです。

## ②「クリーンアーキテクチャ」は「レイヤードアーキテクチャ」の一種

先ほどの「**レイヤードアーキテクチャ**」は「**クリーンアーキテクチャ**」の**祖先**みたいなものと考えたらいいのかもしれません。
で、「レイヤードアーキテクチャ」から派生したアーキテクチャはほかにもあり、
よく**「ヘキサゴナルアーキテクチャ」**が合わせて説明されていることが多い気がします。

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

![FireShot Capture 015 - ヘキサゴナルアーキテクチャ .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85815/dbd57f21-b395-581b-fcdd-fd395d6685a1.png)


[**「ヘキサゴナルアーキテクチャ」**でググる](https://www.google.com/search?q=%E3%83%98%E3%82%AD%E3%82%B5%E3%82%B4%E3%83%8A%E3%83%AB%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3&source=lnms&tbm=isch&sa=X&ved=2ahUKEwjqvszOjcPmAhV0NKYKHV6nB-AQ_AUoAXoECA0QAw&biw=1280&bih=657)と六角形の図が出てくると思いますがこれがそうです。

どういったものか超簡単に書きますと、

**「ヘキサゴナルアーキテクチャ」**はアプリケーションを**「内」**、アプリケーション以外を**「外」**に置き、**ユーザー**や**テスト**、**バッチ処理**などからも同じように駆動できるように設計されたアーキテクチャです。

別名「**Ports & Adapter**」という名前の通り、**アプリケーション部分（内）**を**PC**、**それ以外の部分（外）**を**キーボード**や**マウス**、**SSD（HDD）**と考えるとわかりやすいかもしれません。
**外から内への依存関係の場合**、新しいキーボードをつなげてもSSDを交換した場合でもデータを移行してあげれば**今まで通り動く**という利点があります。

（ほかにも「**オニオンアーキテクチャ**」というものもありますがここでは割愛させていただきます。）

この記事（[[DDD]ドメイン駆動設計で実装を始めるのに一番とっつきやすいアーキテクチャは何か - Qiita](https://qiita.com/little_hand_s/items/ebb4284afeea0e8cc752)）がとても参考になりました。

個人的には「ヘキサゴナルアーキテクチャ」は単純でわかりやすいかなーと思ってます。

## ③MVCアーキテクチャ（MVCパターン）との違いは

それぞれの**Model、View、Controller**（特に**Model**）の責務をさらに**詳細にレイヤーに分けた**ことが大きく違うところだと思います。

### MVCの難点「モデルの肥大化」を解決できる

**ファットコントローラを避けるために何でも処理をModelへ書いた経験はないですか？**
自分はとりあえずファットコントローラはいけないと思いDB処理とともにビジネスロジックなど諸々の処理をModelへ書いて**カオスな状態になった経験があります**。
これが解決できるのはありがたいです


## ④クリーンアーキテクチャに出てくる4つの層（レイヤ）からなる円について

4つの層を見る前にまず**各層の依存は基本的に内に向けてのみで外側の層については知らなくていい**ということを頭に入れておいてください。

**外部のことを知らなくても良いように作ることで仕様変更時の影響範囲が狭くなり、改修・修正が楽になります。**
（例：DBがMySQLからPostgreSQLに代わっても問題なく動く）


以上を踏まえた上で、4つの円について理解するためのポイントを箇条書きぽい感じで書いていきます。

### ■Frameworks & Drivers（青い層）

**フレームワークやらDBやらのツールで構成される層**
要は後から変更される可能性があるDBなどを外側に置くことで変更を容易にしている（**DIP：依存関係逆転の原則**）
→ [1分でわかる依存関係逆転の原則(DIP) - Qiita](https://qiita.com/wanko5296/items/29e74cc7dd7562624d08)

### ■Interface（緑の層）

**リクエストなどで受けたパラメータやらを内部用に変換する**
あくまで**「数値に変換する」**といった技術的な処理を書くのであって**ビジネス的な処理をここには書かない**

- `Controller`が上層（**Frameworks & Drivers**（view））からきたデータを受けて下層（Use case層）へ渡す
- `Presenter`が結果を下層（**Use case**層）から受けて上層（**Frameworks & Drivers**（view））へ渡す

### ■Usecase（赤の層）

**ビジネス的なルールやロジックを書くところ**
（例：深夜割増のための計算処理、部署ごとに先頭番号が異なるID発行処理 など）

### ■Entities（中心・黄の層）

**ビジネス特有のデータ、メソッドをもつオブジェクト**
（例：ユーザーの年齢、部署の名前 とか）

ちなみに**厳密に4層にする必要はない**らしいので、プロジェクトによってこの辺りは変えていいみたいです

# おわり
- アーキテクチャの記事を書く人によって、出てくる言葉（階層名）が異なるのが混乱の元なのかなーと思っています。
- 例えばですが、**Entitiesの部分がModelになっていたり**、**Domainになっていたり**、**Domainの中にEntitiesがいたり**・・・この辺の説明が曖昧な場合が多い気がしました。
- というわけで**クリーンアーキテクチャ完全に理解した（何もわからん）**ので間違いとか理解がおかしいとかあったらマサカリしてください。

# 参考URL

- [Clean Architectureは全てのプログラマにお奨めしたい良著｜erukiti｜note](https://note.mu/erukiti/n/n36fee4a014d9)
- [持続可能な開発を目指す ~ ドメイン・ユースケース駆動（クリーンアーキテクチャ） + 単方向に制限した処理 + FRP - Qiita](https://qiita.com/kondei/items/41c28674c1bfd4156186)
- [まだMVC,MVP,MVVMで消耗してるの？ iOS Clean Architectureについて - Qiita](https://qiita.com/koutalou/items/07a4f9cf51a2d13e4cdc)