13
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

つらいPresenterと、つらくないPresenter

Last updated at Posted at 2017-06-05

まえおき

MVPアーキテクチャとか、クリーンアーキテクチャとかで、Presenterというものが出てきます。
ビジネスロジックをごにょごにょした結果などをActivityやFragmentに映し出すためのインターフェース、みたいなやつです。

個人的に、Presenterというものが「なんかしっくりこないなー」と思ってるところを書いてみただけなんですが、みなさんどうやって設計してるんでしょう・・・

つらいPresenter

Presenterそのものがつらいというよりは、ベースの設計思想がこういうパターンのやつ。

b21cfbaa-a8cd-226e-dc56-9caf0d2a7fdf.png

  1. API通信を開始
  2. プログレスを表示
  3. 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

3028f1c9-8f76-47c9-7a59-d4115b873431.png

一見、さっきよりもコンポーネントが増えて、複雑化してるじゃん、と思うかもしれないけど、ポイントはそこではありません。
画面の状態遷移がなくなっているというのが最大のポイントです。

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 のコード読んでも、実際に作ってみても、いまいちパッとしないところをなんとなく書いてみただけです・・・。ショボい記事ですんません。

皆さんどういう設計にしてるんでしょう、このあたり・・・

13
14
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?