Architecture: Live Q&A - MAD Skillsメモ

これを書いている時点では正確な字幕はまだ手に入らなかったのと、かなり意訳なので直接見てみてください
結構普段の開発で論点になる部分が多いので、面白かったです。
なにか致命的な間違いなどがあれば教えて下さい :pray:
また、わかりにくければ動画を見てみてください

https://www.youtube.com/watch?v=_2BtE1P6MPE

## LiveDataはdeprecated？

そうする必要はないので、deprecatedになっていないので、使い続けてOK。
ただ、StateFlowもFirst classでサポートしている。

## なぜBusiness logicをデータレイヤーに持っていくのか？そのモチベーションは何？

single source of truthを実現して、並行実行や再利用性の管理もできる。 

## strings.xmlのようなリソースにViewModelでどのようにアクセスするべきか？

ViewでもComposableでも基本的にViewModelはアクセスすべきでない。
なぜ持つべきではないのかと言うとConfiguration changeによってリソースが変わるため。例えばDark modeなど。
contextはViewModelと違うライフサイクルを持つのでリークする可能性もある。

## ComposableとServiceがViewModelとやり取りするにはどうすればいい？

例えば直接参照を持つなどの直接やり取りするべきではない。その代わりに同じインスタンスのクラスを使って、source of truthを作る。このクラスは基本的にrepositoryになって、それはViewModelやServiceから呼ぶことができる。これによってデータを変更したときに自動的に変わるようになる。

## KMPへのスムーズな移行をするベストプラクティスは？

難しい。ベストプラクティスは人々が失敗したりしてできたりするので。
一つ言えることとしてはKMPのためにコードベースの抽象化を始めないでください。もし具体的な計画があるのであればよいが、不要な抽象化は利益をもたらさない。

## ViewModelってただのStateHolderだと思うけどMVVMのViewModelに相当するものって何？
StateHolderはMVVMのViewModelになれる。StateHolderはUIの再利用可能なUIの単位でできるのでAACのViewModelになることもあればならないこともある。
画面レベルのState holderにViewModelを使うことをすすめる。

## レイヤー分けによるモジュール分けに関してなにかおすすめの変更あった？
そのガイダンスを作成中。今年中に出したい。
2分のビデオがあるから見てみてね

https://www.youtube.com/watch?v=HB_r9wn49Gc

## データソース、UseCase、RepositoryでFlowを使うべき？
DataSourceではネットワークから取得するならsuspend function、なぜならワンショットだから。Roomから取得するなら時間とともに変わるのでFlowを使う。
Repositoryはコンフリクトを解決し、データベースからのデータもハンドルし、それらをマージし、それらが時間とともに変化することを考慮すると、Flowを使いたくなる。

## UseCaseはいつ使ったらいいの？自分のチームではViewModelのロジックを減らすのとに使っている。
UseCaseを使ういいメリットは、ViewModelのコンストラクタを見るだけでViewModelが何をするのかがわかるのが良いメリットである。

## ViewModelがUIに違う画面やFragmentに移動することを教えるおすすめのパターンは？

Stateとして保持して、そのStateを受け取ったら消す。
よくあるユースケースのログインの場合はstateの変更なので、普通にlogin状態に変えて、それを使うだけ。
UIイベントはよく議論が起こる話題。メインのポイントはViewModelの命令をイベントとして考えずにアプリケーションの状態として考えるようにしていること。
ユーザーがイベントを消費するのではなく、このメッセージを見たと知らせている。

## ユーザー設定によってnavigation graphを変えるにはどうしたら良い？

例えばログイン状態だったらそのログインとログインしていない状態のnested graphを定義して使うと良い。

## WorkManagerやServiceはMVVMやClean Arhictectureでどこに置けばいい？
どこにでもAndroidのアーキテクチャに置けるので、何をさせるかによる。ただ、WorkManagerは終わるまでリトライするような場合（persistent）のみ使うので、単にAIのモデルをUserのために取得するような場合は必要なくただのコルーチンで良い。

## なぜサンプルのRepositoryでIODispatcherを時々使って、時々使わないの？

例えばRoomだとsuspend functionをサポートしていて、suspend functionの場合はバックグラウンド実行に自動的に移る。そのため、IO Dispatcherに移したりする必要はない。
DBだったらDBなどがDispacherを移動する責務があるので、そのクラス以外が移すべきではない。

## メモリセンシティブデータを画面間で受け渡すには？

メモリセンシティブデータが何かわからないが、多分diskに書きたくないデータかな？
昔はActivityからデータを渡したりしていたけど、今はRepositoryとかを使う。
単に大きくてparcelで渡せないような場合は、activity contracts APIを見てみてね。


## MVIとMVVM、どっちがComposeにいいの？

どっちでもComposeはうまくうごく。

## プロジェクトが大きくになるにつれて、ドメインやデータレイヤーのモジュールを作る必要がある？

作ったほうが良い。データレイヤーを一つにまとめるかどうかは、Repositoryを分けておくことをおすすめする。

## どのようにViewの構造をメンテナンスするべき？なるべく浅くするべき？

Android ViewではConstraintLayoutがいい解決策。Composableではそのパフォーマンスペナルティがないので、メンテナンス性を重視して、決めて良い。
Composeでは不必要なrecompositionを避けるべき。

## 他のレイヤーからPresentation Layerにエラーを返す一番良い方法は？

Functional mecanismを使っている場合はResultなどをよしなに処理しても良いし、Kotlinは例外の仕組みがあり低いレイヤーでキャッチできる。単にcatchしてResultに変換しているだけの場合は特に役に立たず、コードを書きにくくし複雑にするのみ。

## ドメインモデルとAPIやDB modelとのmapperはどこのレイヤーに書くべき？

modelはcoreみたいな見られるところにあったとしましょう。
dataモジュールにはreposiotryやnetworkがあってnetwork modelはUIが見られるべきではなく、networkのモジュールにあるべき、そしてreposiotryはアプリがデータを消費できるようにするものなので、Repositoryでマッピングが行われるべき。commonモジュールにすべてを置かない理由は、変更時にアプリ全体をビルドし直す必要があるため。

## UI layer -> Domain layer -> Data layerパターンはWidgetとかAndroid AutoとかWearとかでも使える？

使える。さらにAndroid Autoなどではデータレイヤーを共有することもできる。

## Multiple Activityか Single activity multiple fragmentか

Picture in Pictureのときは使いたい場合があるかも。複数のエントリーポイントがアプリにあるときに使える。

単にスクリーンを移動したいだけの場合はActivityを使わないで、Actiivtyによる方法はOSとやり取りして画面を出すことになるため。
またComposeの場合はFragmentさえ必要ない。 
エントリーポイントというのはOSや別のアプリがアプリを起動できてアプリがその処理を行うことができるもの。LauncherActivityなどを持つのも良い。