まえおき
MVPアーキテクチャとか、クリーンアーキテクチャとかで、Presenterというものが出てきます。
ビジネスロジックをごにょごにょした結果などをActivityやFragmentに映し出すためのインターフェース、みたいなやつです。
個人的に、Presenterというものが「なんかしっくりこないなー」と思ってるところを書いてみただけなんですが、みなさんどうやって設計してるんでしょう・・・
つらいPresenter
Presenterそのものがつらいというよりは、ベースの設計思想がこういうパターンのやつ。
- API通信を開始
- プログレスを表示
- API通信が終わったらプログレスを消す
みたいなのをActivityやFragmentが主導でやるようなやつ。
UseCase/Presenter/Repositoryがきれいに分かれていたとしても、RxJavaでコールバック地獄は回避したとしても、ベースの考えがこういうやつだと、ただただ状態管理が複雑化することが多いです。
interface XXXPresenter {
void showProgress();
void hideProgress();
}
みたいなのが1つでもあれば、すでに、つらい設計パターンです。
なにがつらいか?
showProgress()
はActivityやFragmentでくるくる表示をすればいい、というのは軽率で、
実際にはActivityやFragmentは独自にAndroidフレームワークが規定するライフサイクルを持っています。
showPregress()
が onResume()〜onPause() の間に限って呼ばれるのか、ライフサイクルガン無視で呼ばれるのかは、結局ユースケースとかリポジトリとかを見てみないとわからない・・・みたいなことになりがちです。
あとは、くるくるを出している間は、処理をブロッキングする必要があるのか、ブロッキングしなくていいのか。
ブロッキングする必要があるなら、
interface XXXPresenter {
void showProgress();
void hideProgress();
void enableEditor();
void disableEditor();
}
のようにメソッドを足せばいい?それ、ActivityやFragmentでやりたいことが増えるたびに、Presenter増やしてやるの?
editorのオンオフはやるけど、前の画面に戻るのをブロックするの?しないの?
みたいな感じで、だんだんと状態が増えてわけがわからなくなる。
そもそも、PresenterってそんなにActivityやFragmentの事情を知ってるべきなんだっけ・・・?って考えにもなってきます。
(比較的)つらくないPresenter
一見、さっきよりもコンポーネントが増えて、複雑化してるじゃん、と思うかもしれないけど、ポイントはそこではありません。
画面の状態遷移がなくなっているというのが最大のポイントです。
Activity/Fragmentは、自分のライフサイクルを考慮して、状態モデルを subscribe
/unsubscribe
し、状態をそのまま画面に写像する、という考えです。
この場合、UseCase/Presenterは
class XXXXUsecase {
void postMessage(String body);
void subscribeFetchingState();
void unsubscribeFetchingState();
void subscribeMessageList();
void unsubscribeMessageList();
}
interface XXXXPresenter {
presentFetchingState(int state);
presentMessageList(List<Message> messages);
}
のようになるでしょう。
具体的に通信中に何をすべきか、はActivity/Fragmentにゆだねていて、くるくるを出すのも、UIをブロックするのもすべてActivity/Fragmentの自由です!
あと、UseCaseでsubscribeしてからunsubscribeするまでだけ、presentXXX() が呼ばれる、というルール付けがあることで、ライフサイクルの考慮もしやすくなります。
おわりに
android-architectures のコード読んでも、実際に作ってみても、いまいちパッとしないところをなんとなく書いてみただけです・・・。ショボい記事ですんません。
皆さんどういう設計にしてるんでしょう、このあたり・・・