UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【Architecture】Clean Architectureの話

クリーンアーキテクチャについての説明で「世界一わかりやすい」とあったので読んだら確かにわかりやすかったのでメモ www.nuits.jp

クリーンアーキテクチャへの見解は以前書いた気がするが、お気持ち程度のことしか書けなかったので、今回の記事を読んでかなり腑に落ちた uga-box.hatenablog.com

まず、クリーンアーキテクチャの誤解

  • あの図は決してソフトウェアの関心をControllerやUseCase、Entityに分離しろという意味でもなく、レイヤーをこの4つに分割しろという意味ではない
  • データや処理の流れを一方通行にしろという意味ではない、Presentationを古典的なMVCのように設計しろと言っている訳でもない

本当に大切なことは、依存性は外から中だけに向かっていなくてはいけないということ

クリーンアーキテクチャでおさえるべき三つのこと

  1. 依存性は、より上位のレベルの方針にのみ向けよ
  2. 制御の流れと依存方向は分離しコントロールせよ
  3. 上位レベルとは相対的・再起的であることを留意せよ

記事の流れ

レイヤーアーキテクチャの問題点

クリーンアーキテクチャを適用する

依存性は、より上位のレベルの方針にのみ向けよ

まず、単純なレイヤーアーキテクチャは、Presentation・Usecase・Infrastructureの三つに分割する

Presentation・Usecase・Infrastructureは以下のような依存関係にある

Presentation -> Usecase -> Infrastructure

このときの一般論として、依存する側(->の左)は依存される側(->の右)の変更に影響を受けてしまい「安定度が低くなる」が、依存する側を変更しても依存される側には影響がないので「柔軟性は高い」と言える

単純なレイヤーアーキテクチャの問題点として、Presentationは変更頻度が多いので「柔軟性が高い」依存する側(->左)にあるので良いが、Usecaseはアプリケーションの本質的なところを担っており変更頻度が少ないため「安定度の高い」依存される側(->右)にあるべきである

なので、制御の流れは上記で良いが、依存関係は以下になるのが望ましい

Presentation -> Usecase <- Infrastructure

つまり、制御の流れと依存関係を分離する必要がある

制御の流れと依存方向は分離しコントロールせよ

依存関係はレイヤー間の「コントラクト(契約)」がどちらにあるかによって決まり、「コントラクト」がある方が依存される側になる

なので、Usecaseレイヤーに「コントラクト」を定義するようにする

例えば、Infrastructureは外部APIのレスポンスをそのままをUsecaseに戻すのではなく、Usecaseが扱えるように結果を変換してから戻すようにするなど

こうすることで下の依存関係にすることができる

Presentation -> Usecase <- Infrastructure

これはまさにクリーンアーキテクチャの同心円の図となる

上位レベルとは相対的・再起的であることを留意せよ

Usecaseはこのアプリの中では「上位レベル」であるにもかかわらず、Infrastructureが外部APIに依存しているのは良いのか?

Presentation -> Usecase <- Infrastructure -> 外部API

これはサービスの本質が「外部APIを自分なりにカスタマイズして使いやすくする」であれば問題ない

なので、以下のように捉えることができる

(Presentation -> Usecase <- Infrastructure) -> (外部のソリューション)

もしかしたら、外部のソリューションが他のアプリからも依存されていることもあるかもしれない

(Presentation -> Usecase <- Infrastructure) -> (外部のソリューション)<- (別のアプリ)

この時、中心の外部のソリューションも別のアプリも同じような構造になっているはずである

つまり、「上位レベル」というのは相対的かつ再帰的であり、それに留意する必要がある

ソフトウェアアーキテクチャとは何か

最後の「ソフトウェアアーキテクチャとは何か」の話しがまるで哲学のようであって面白かった

答えはまだ誰にも出せていないとのことだが、共通認識として「システムアーキテクチャのうちのソフトウェア領域のアーキテクチャである」という定義はできる(システムは「IT」のことではなく、元来の「制度・組織・体系・系統」のことを指す)

他に、ソフトウェアアーキテクチャの3種の神器(関心の分離、疎結合、依存性逆転の原則)を模した図もわかりやすかった

そして、最後に「クリーンアーキテクチャというのは、ソフトウェアアーキテクチャの3種の神器(関心の分離、疎結合、依存性逆転の原則)を適用した、リファレンスアーキテクチャのひとつ」という定義は腑に落ちた

抽象と具象

クリーンアーキテクチャの「フレームワークやデータベースなどの開発環境やツールの意思決定を遅らせられるよう、それらに依存しないように設計する」はUIフレームワーク、データベースを使わない非ライブラリ依存で実装するという意味なのでなかなか難しい

なのでPresentation内の「上位レベルの決断」に限定して利用であれば許容する

むしろ早い段階で受け入れることで、コストや開発期間の圧縮や、品質の向上を図ることも検討するのが良い

これらの方針はとても同意できることで、特にフロントエンドはフレームワークによって大きく作り方が変わるので早めの具象の受け入れが大事と感じた

とてもわかりやすい記事だった