LoginSignup
12
8

More than 5 years have passed since last update.

[android-architecture] Model-View-Presenter(MVP)+αを読んでみる

Last updated at Posted at 2018-12-16

はじめに

「Androidの世界標準的には、どんなパッケージ/クラス構成が良いんだろう?」

ずっと独学でやっていると「○○パターンは経験ありますよ」とは言えても
「△△の場合は○○パターンが一般的ですよ」なんて事は言えません(くやしい)。

「一般的」なんてのは、時と場合と作るものによって全然違うんでしょうけど
少しでも引き出しを増やしたいと思い、GoogleSamples(android-architecture)を読んでみました。

その中から、独断と偏見で印象に残った内容を書きます。
量が多いので、何個かの記事に分割して投稿します。
元のソースは、随所のリンク先でご確認ください。

バックナンバー

1. Model-View-Presenter(MVP)+αを読んでみる
2. Clean Architectureを読んでみる
3. MVVM & DataBindingを読んでみる
4. MVVM & LiveDataを読んでみる

以下、本編です。

GoogleSamples(android-architecture)とは?

異なるアーキテクチャで同じ仕様のアプリを作ったんだそうです。
「同じ仕様でも複数のアプローチができるよ。参考にしてね。」って事ですね。

Model‑View‑Presenter (MVP)

ソースを要約すると、以下の様な構造。
Model は Repository パターンで管理しています。

パッケージ構成
com.example.(...).xxx;
com.example.(...).yyy;
com.example.(...).zzz;
...
x, y, z は機能名機能毎にパッケージを切っている感じ
BaseView
public interface BaseView<T> {
    void setPresenter(T presenter);
}
BasePresenter
public interface BasePresenter {...}
Xxx機能
package com.example.(...).xxx;

public interface XxxContract {
    interface View extends BaseView<Presenter> {...}
    interface Presenter extends BasePresenter {...}
}

public class XxxActivity extends AppCompatActivity {...}

public class XxxFragment extends Fragment implements XxxContract.View {
    private XxxContract.Presenter presenter;
    ...
}

public class XxxPresenter implements XxxContract.Presenter {...}
Xxx機能(リソース)
xxx_act.xml
xxx_frag.xml
Repository
public interface DataSource {...}

public class LocalDataSource implements DataSource {...}

public class RemoteDataSource implements DataSource {...}

public class Repository implements DataSource {
    private static Repository INSTANCE = null;
    private final DataSource mRemote;
    private final DataSource mLocal;
}

MVP - Dagger

Dagger2 の使い方を見ることができます。
こちらはMVPと異なる部分だけ要約します。
Dagger2 については、筆者も過去に Component / Module の定義を検討してまして。
宜しければ、ご参考まで → (Dagger2を使ったらUnitTestが楽になるか考えてみた

Component / Module 部分は、おおよそ「公式サイト」通りなので割愛します。

Xxx機能
package com.example.(...).xxx;

public class XxxActivity extends DaggerAppCompatActivity {
    @Inject
    XxxPresenter presenter;
    @Inject
    Lazy<XxxFragment> fragmentProvider;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        XxxFragment fragment = (XxxFragment) getSupportFragmentManager().findFragmentById(R.id.aaa);
        if (fragment == null) {
            fragment = fragmentProvider.get();
            ...
        }
        ...
    }
}

@ActivityScoped
public class XxxFragment extends DaggerFragment implements XxxContract.View {
    @Inject
    XxxContract.Presenter mPresenter;
    @Inject
    public TasksFragment() {...}
}

なるほど、 Lazy (遅延初期化) なんて出来るんですね。
DaggerActivity / DaggerFragment というのもあるみたいです。
これを継承するのは、時と場合を選びそうですね。

MVP - RxJava

Repository を RxJava 使って書いている程度で、他は目立った変更は無いです。
筆者が個人的に印象に残ったのは、バッググラウンド処理を「Schedulers.io()」を使っている所。
(「schedulers.io vs schedulers.newthread」なんて検索ワードが出てくるくらい、皆さん迷ってますね)

いかがでしたでしょうか

今回はさほど難しくなく、非常にシンプルでオーソドックスでした。
次回は、MVP - Clean Architectureについて記載します。

参考

Github : googlesamples/android-architecture

12
8
0

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
12
8