はじめに
この記事は**and factory Advent Calendar 2019の22日目の記事**です
ちなみに明日も別のアドベントカレンダー入ってたせいで大変な状態になってます。
クリーンアーキテクチャを学ぶ前に知りたかった知識
自分が勉強する際にいろいろな方が書かれたクリーンアーキテクチャの記事をあさってた時、ほとんどの説明があらゆる知識を把握している前提で書かれているのが多かった為、すんなりと頭に入ってこず理解できなかったことがほとんどでした。
前提知識を学んで再度クリーンアーキテクチャについて調べると**何となくわかってきた(?)**ので、自分的に事前に知っておきたかった知識についてここでまとめておきます。
どこかの誰かの学習時間の短縮になれば我幸いです。
(特に自分みたいにLaravelやRailsなどフレームワークのMVCパターンしかやったことがない方とかには参考になるのではないかと勝手に思ってます。)
クリーンアーキテクチャとは
Robert C. Martinさんが2012年に提唱したアーキテクチャ(ここではアプリケーションの構造を指す)のことです。
日本語翻訳版
最初、日本語訳を読んだ時「んーなるほど完全に理解した」状態になると思いますが一度は読んでおきましょう
そもそもの話
①「レイヤードアーキテクチャ」というのがある
**アーキテクチャの一つで昔から存在する「レイヤードアーキテクチャ」**というものがあります
- レイヤごとに関心関心事を分離する
- 上位のレイヤは下位のレイヤにのみ依存する※
ということが基本的なルールみたいで、MVCパターンに慣れている方なら何となくわかってもらえるかと思います。
超簡単に言うと、「処理の種類やコードによって書く場所を分けて整理整頓しよう」という考えのアーキテクチャです。
②「クリーンアーキテクチャ」は「レイヤードアーキテクチャ」の一種
先ほどの「レイヤードアーキテクチャ」は「クリーンアーキテクチャ」の祖先みたいなものと考えたらいいのかもしれません。
で、「レイヤードアーキテクチャ」から派生したアーキテクチャはほかにもあり、
よく**「ヘキサゴナルアーキテクチャ」**が合わせて説明されていることが多い気がします。
●ヘキサゴナルアーキテクチャ(Hexagonal Architecture)
**「ヘキサゴナルアーキテクチャ」**でググると六角形の図が出てくると思いますがこれがそうです。
どういったものか超簡単に書きますと、
「ヘキサゴナルアーキテクチャ」はアプリケーションを「内」、アプリケーション以外を**「外」に置き、ユーザーやテスト**、バッチ処理などからも同じように駆動できるように設計されたアーキテクチャです。
別名「Ports & Adapter」という名前の通り、アプリケーション部分(内)をPC、それ以外の部分(外)をキーボードやマウス、SSD(HDD)と考えるとわかりやすいかもしれません。
外から内への依存関係の場合、新しいキーボードをつなげてもSSDを交換した場合でもデータを移行してあげれば今まで通り動くという利点があります。
(ほかにも「オニオンアーキテクチャ」というものもありますがここでは割愛させていただきます。)
この記事([DDD]ドメイン駆動設計で実装を始めるのに一番とっつきやすいアーキテクチャは何か - Qiita)がとても参考になりました。
個人的には「ヘキサゴナルアーキテクチャ」は単純でわかりやすいかなーと思ってます。
③MVCアーキテクチャ(MVCパターン)との違いは
それぞれのModel、View、Controller(特にModel)の責務をさらに詳細にレイヤーに分けたことが大きく違うところだと思います。
MVCの難点「モデルの肥大化」を解決できる
ファットコントローラを避けるために何でも処理をModelへ書いた経験はないですか?
自分はとりあえずファットコントローラはいけないと思いDB処理とともにビジネスロジックなど諸々の処理をModelへ書いてカオスな状態になった経験があります。
これが解決できるのはありがたいです
④クリーンアーキテクチャに出てくる4つの層(レイヤ)からなる円について
4つの層を見る前にまず各層の依存は基本的に内に向けてのみで外側の層については知らなくていいということを頭に入れておいてください。
外部のことを知らなくても良いように作ることで仕様変更時の影響範囲が狭くなり、改修・修正が楽になります。
(例:DBがMySQLからPostgreSQLに代わっても問題なく動く)
以上を踏まえた上で、4つの円について理解するためのポイントを箇条書きぽい感じで書いていきます。
■Frameworks & Drivers(青い層)
フレームワークやらDBやらのツールで構成される層
要は後から変更される可能性があるDBなどを外側に置くことで変更を容易にしている(DIP:依存関係逆転の原則)
→ 1分でわかる依存関係逆転の原則(DIP) - Qiita
■Interface(緑の層)
リクエストなどで受けたパラメータやらを内部用に変換する
あくまで**「数値に変換する」といった技術的な処理を書くのであってビジネス的な処理をここには書かない**
-
Controller
が上層(Frameworks & Drivers(view))からきたデータを受けて下層(Use case層)へ渡す -
Presenter
が結果を下層(Use case層)から受けて上層(Frameworks & Drivers(view))へ渡す
■Usecase(赤の層)
ビジネス的なルールやロジックを書くところ
(例:深夜割増のための計算処理、部署ごとに先頭番号が異なるID発行処理 など)
■Entities(中心・黄の層)
ビジネス特有のデータ、メソッドをもつオブジェクト
(例:ユーザーの年齢、部署の名前 とか)
ちなみに厳密に4層にする必要はないらしいので、プロジェクトによってこの辺りは変えていいみたいです
おわり
- アーキテクチャの記事を書く人によって、出てくる言葉(階層名)が異なるのが混乱の元なのかなーと思っています。
- 例えばですが、Entitiesの部分がModelになっていたり、Domainになっていたり、Domainの中にEntitiesがいたり・・・この辺の説明が曖昧な場合が多い気がしました。
- というわけで**クリーンアーキテクチャ完全に理解した(何もわからん)**ので間違いとか理解がおかしいとかあったらマサカリしてください。