着手
前回の記事で宣言したとおり、勉強用日記アプリのMVP化に取り掛かりました。
で、
当然PresenterをViewとModelの間に設置する事になる。
みたいな事書きましたが、いきなりPresenterをおきました!なんて実装は普通しません。
(普通しません、なんて言い出したら途中からアーキテクチャ変えるなんて修正の方がありえませんが、勉強用として反面教師にしといてください。)
MVP化ブランチは
https://github.com/poin-settia/Diary/tree/feature-MVP
として専用に切り分けました。万が一を考えて元のブランチは master
として残しておきます。
執筆時点ではPresenter / Repository / Contract の新規作成がコミットされたところです。
今回着手したこと
コミット名にも書きましたが新しく Presenter
とRepository
、Contract
クラスを増やしました。Presenterを増やすだけでなくRepositoryクラスも必要になったのです。
前回の記事でクラス図を展開しましたがModelにはPersonRealmHelperという名前のRealmDBのクエリをまとめたクラスがあります。
かといってFragmentにごちゃまぜになってるDB操作をHelperに移設する訳にもいかないので、
そこらへんのデータ整形はRepositoryにお願いする事になります。
Contract
MVP化のあかつきにはModel,View,Presenterは皆Contractインタフェースを実装することになります。
Contractの中身はMVPがそれぞれどんな役割を持っているのかを明確に縛る為、事前に機能の切り出しが必要になります。
機能の切り出し準備
最大の問題点である Fragmentに色んな機能ごちゃまぜな件
を解決するべく、まずはこんな事から始めました。
// 元の場所
int fromIndex = viewHolder.getAdapterPosition();
// 移動後の場所
int toIndex = target.getAdapterPosition();
// ★リストの入れ替えイベント・Presenter
// ★インデックスの入れ替えを行う・Model
indexReplace(fromIndex,toIndex);
// ★入れ替え後の通知を行う・View
mAdapter.notifyItemMoved(fromIndex,toIndex);
return true;
★マークが入ったコメントがありますね。
ここはItemTouchHelper内のonMove、つまりリストの入れ替えイベントが発生した歳に呼び出されるわけですが、機能でいうと3つに分けられます。
- リストの入れ替えイベントが発生する
- インデックスの入れ替えを行う
- 入れ替え後の通知を行う
ちょうどPresenter、Model、Viewの順番で機能が細分化できそうなので、コメント末尾に移管先のクラス名をつけておきました。Contractには★コメントに沿って実装していけば良いわけです。
MVP化のあかつきには - Presenterにリストの入れ替えイベントが通知される、
- PresenterがModel(Repository)に対してインデックスの入れ替えを指示する
- Modelからの完了通知をうけて、PresenterはViewに対して入れ替え後の通知を行うよう指示を出す
といった切り分けが叶いそうですね。
困難は分割せよ
最後になんかそれっぽい事書いてますが、MVPもMVVMも機能が分割することによって役割が明確化され、難しい困難も分割できてゆくのではないのではしょうか。
結局のところ、困難になる前にちゃんと設計してMVPで書いておけばよいって話になるんですが、そこは勉強用、ということで割きましょう。
次回
★マーク通りにContractは実装しており、あとは機能の移管を勧めていくことになると思う。
きっとRepositoryの移管作業らへんでRxJavaを導入しそうな気配。