はじめに
はい、ということで今回はアーキテクチャの図はみた!
でもうまくわからんから文字に起こしてくれ!
という方に向けた雑多な記事です。
画像の説明?うるせえ!知らねえ!ファイナルファンタジーというかたは実装に落とし込む
というとこまでスクロールしてもらって大丈夫です。
例の画像と1番の外周
あの丸っこい図がありますよね。
これですこれ
見飽きたよ、ややこしいよ!
わかります。自分も初めて見たときなんだぁ?てめぇ?ってなりました。
ただ、見方さえわかってしまえばなんてことないんですよね。
cleanArchitecture
ってどのプラットフォームの開発でも使える汎用的な設計思想なんです。
つまり、一番外周は各プラットフォームだと思ってもらえばいいです。無視しておk
2個目の円
ViewModelなどがここにあたりますUIのママです。
UIという子供が食べやすいようにUseCaseから受け取ったものを加工してくれたり、逆にあまり意思の疎通ができない子供のUIくんが頼みたいものを代わりにUseCaseという店員さんに注文してくれます。
3個目の円
UseCaseです。
もうそのまま、共通化できて使う状況などによって切り分けられていく処理です。
基本的には1つのUseCaseには1つの関数のみが存在すべきです。
複数あったらUseCaseって名前の意味ほぼないですからね。
4個目の円
データです。
ただそれだけ、ドシンプル。
実装に落とし込む
これで最初の疑問に戻りますね、わかってんだよ!とどうしろってんだよ!っていう風に思いますよね。
図にしてみたり、どれに当たるのかを説明してみたりしましたが、要は依存も認知も一方通行にしてねということです。
マルチモジュールにしろ、シングルモジュールにしろまずは下記を抑えましょう。
- Dataモジュール(フォルダ)にあるstructやDataClassなどはデータソースとのやりとり
- Domainモジュール(フォルダ)にあるstructやDataClassなどはUIとのやりとり
- Data層からデータを取得したいときはDomainにInterfaceを実装してDataでClassを実装する
もし、マルチモジュールの場合は、Internalなどを付与して秘匿を忘れずに。
そして、データの流れとしては下記のようになるべきです。
data -> datasource -> repositoyImpl -> repository -> domain -> useCaseImpl -> useCase
こうすることで、implで実装された内側は誰が使おうがどこから使おうが、認知しているのは自分より前に存在しているものか、並列に存在しているものになります。
逆にInterface
で実装されているただのrepository
やuseCase
はimplで本実装されているものにのみ依存していることになります。
最後に
自分も最初のころは何が何だかわからなかったので、右に倣えで既に実装されているものなどを参考に実装を進めていた時期もありましたが、新機能開発などをするようになるとPRでの指摘やあとから見返した時の違和感などで自己嫌悪に陥ります。
そうならないためにも少しでもお役に立てたらさいわいです