MVP(Model + View + Presenter)
なんでMVP?
- MVCで書いてるとActivityがViewとControllerの役割を担ってしまうためFatActivity(Activityに処理が集まってしまう)になってくらしい。
- 実質Activity=ViewなのでControllerの機能だけでも引きはがしたい。
- ○○Listenerでイベント受け取って処理しなければいけないのはどうしようもない。
- なので「○○Listener」での処理の中身はActivity外に移そうよ(Presenter)って方針になったぽい。
ひとまず結論
簡単なTodoアプリで実装してみたけどあんまり恩恵は感じなかった
ちゃんとFatControllerに対して適用したらよい感じなんだろうなー...
調べた
- 上のやつはFragmentを使う場合ぽい
Fragment
は共通レイアウト用意して、コンテンツだけ差し替えるときとかに使うと良いらしい。 - インターフェースでContractorなるものを作成して、ViewとPresenterでそれぞれ実装される機能を定義しておく。
これはViewとPresenterが何やってるか分かりやすくするためだと思われ。 - Activityに定義されているものに関してはActivityに実装
- Fragmentの実装がまるっとContractor.Viewに寄せられるのでActivityの見通しは良くなりそう
interface HogeContractor{
interface View {
// ViewのimplementはFragmentと継承して実施
}
interface Presenter {
// おそらく外部とのやり取り回りをまとめる
}
}
実装してみた
先のTodoアプリをMVPに書き直してみた。
ソースはこちら
一旦、上記のgooglesamplesを参考にしてやったこと。
Activity(onCreate)の処理なくなった
Presenterの作成とPresenter.start()呼び出すだけ。これはいいのか?
ディレクトリ構成変わった
機能ごとにディレクトリ作るらしい
PresenterとViewの役割がわけわからんことになった
お互い呼び出せるのでちゃんと役割分担はっきりさせないとあっち行ったりこっち行ったりになりそう。
##※1.の参考で脳内実装してみた
上記のやつだとシンプルなMVPにならなそうだったので再度※1の参考から脳内で実装をシミュレーション。
やることはシンプルでListenerやonCreateなどのメソッド内部の処理をPresenterに実装する。
// ActivityではPresenterの初期化と画面のイベントリスナー回りを設定するだけ
// 実処理はPresenterに委譲する
class HogeActivity: AppCompatActivity() {
private lateinit var presenter: HogePresenter;
override fun onCreate(){
super.onCreate(savedInstanceState)
setContentView(R.layout.xxxxxxx)
// presenterの初期化
presenter = HogePresenter(getContext(), this)
// presenterに初期化処理を委譲
presenter.onCreate()
}
}
// Activityでの処理の中身
class HogePresenter(val mContext: Context, val activity: HogeActivity){
fun onCreate(){
}
}
もうちょい設計について学ばないとなー