AndroidのMVCとMVP

6435 ワード

一、mvcとmvpとは何か
mvc:mvcはmodel,view,controllerです.Androidではmodleがデータエンティティであることは間違いなく、viewはlistview、view pagerなどのビューコンポーネントです.Controllerコントローラ、viewとmodleのインタラクションはcontrollerによって処理され、activityによってcontrollerの役割を果たす.
mvp:modle,view,presenter.mvc開発モデルと同様にmodleはデータエンティティであり、viewはactivityであり、presenterはカスタムリーダーであり、modleとviewのインタラクションはそれによって実現される.
 
二、区別と長所と短所
両者の区別
Mvc開発モードのcontrollerはactivityで機能し,実際のactivityはmodleとviewインタラクションの処理に加えてビュー初期化作業も処理するため,その機能は単一ではない.ビジネスロジックが複雑な場合、activityは肥大化し、メンテナンスが容易ではありません.
Mvp開発モデルactivityはviewとしてpresenter中間者によってmodleとのインタラクションを実現し,デカップリングと良好に実現し,プロジェクトの拡張性とメンテナンス性を大幅に強化した.
メリットとデメリット
Mvcはmvpに比べて中間者presenterを作成する必要がなく、多くのインタフェースファイルを減らすことができ、機能の簡単なプロジェクトに適しており、迅速で敏捷です.しかし、大規模なプロジェクトでは、ビジネスも機能も複雑で、mvcのメンテナンス性、拡張性、さらにはコードの読みやすさが悪くなります.
総合的には、mvp開発モデルを推奨します.もちろん、前述したような機能の簡単な小さなプロジェクトは、mvcを採用してより迅速にプロジェクトを開発することができます.
三、コードプレゼンテーション
mvcを用いた開発が非常に熟練しているため,ここでは主にmvp開発を示す.
例えば、ログイン機能を実現するには、ログインページが必要です.
mvpコード基本作成プロセス:
1.viewつまりActivityを書く
注意:通常、BaseActivity実装IBaseViewに継承されます(汎用プロパティ動作を定義します)
2.view関連業務に基づいてインタフェースを定義し実現させる
注意:presetnerはmがvと対話することを処理するので、持つ参照タイプはここのインタフェースタイプです.
3.presentの定義
注意:通常、抽象basepresenter定義汎用属性動作、ライフサイクルメソッドが定義されます.
4.viewビジネスインタフェースタイプリファレンスとmodelリファレンスをpresenterに渡してインタラクションを実現する.
LoginActivity.java
public class LoginActivity extends BaseActivity implements View.OnClickListener ,ILoginView{

    private Button mLoginBtn;
    private LoginPresenter mLoginPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentLayout(R.layout.activity_main);
    }

    @Override
    public void getViews() {
        mLoginBtn = (Button) findViewById(R.id.btn_login);
    }

    @Override
    public void bindData() {

    }

    @Override
    public void setListeners() {
        mLoginBtn.setOnClickListener(this);
    }

    @Override
    public void showToast(String msg) {
        Toast.makeText(this,msg,Toast.LENGTH_LONG).show();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_login:
                showLoadingLayout();
                mLoginPresenter.login();
                break;
        }
    }

    @Override
    public BasePresenter getPresenter() {
        if(mLoginPresenter==null) {
            mLoginPresenter = new LoginPresenter(this,this,this);
        }
        return mLoginPresenter;

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mLoginPresenter.onDestroy();
    }

    @Override
    public void login(String msg) {
        showToast(msg);
    }
}

modelとviewはpresenterによるインタラクションが必要です.そのためPresenterはmodelとviewの参照を持つ必要があり、より良い服用と拡張のためにpresenterとactivityは抽象的な親クラスを定義し、baseactivityはIbaseViewインタフェース定義の共通の行為を実現し、loginActivityはILoginViewインタフェース定義のViewの具体的な業務属性を実現した.
  LoginPresenter
   public class LoginPresenter extends BasePresenter {
    public static final String LOGIN_TAG = "login_tag";
    private final ILoginView mLoginView;

    public LoginPresenter(Context context, IBaseView callbackView, ILoginView loginView) {
        super(context,callbackView);
        this.mLoginView = loginView;
    }

    public void login() {
        //       
        new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                    EventBus.getDefault().post("    ");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onLogin(String msg) {
        mLoginView.login(msg);
        mViewCallBack.hideLoadingLayout();
    }

    @Override
    public void onCreate() {
        EventBus.getDefault().register(this);
    }

    @Override
    public void onDestroy() {
        mViewCallBack = null;
        EventBus.getDefault().unregister(this);
    }
}

BaseActivity
public abstract class BaseActivity extends AppCompatActivity implements IBaseView {

    private FrameLayout mParentLayout;
    private ProgressBar mLoadingPb;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.base_layout);

        initViews();

        if(null!=getPresenter()) {
            getPresenter().onCreate();
        }
    }

    @Override
    public void initViews() {
        mParentLayout = (FrameLayout) findViewById(R.id.fl_content);
        mLoadingPb = (ProgressBar) findViewById(R.id.pb_loading);
    }

    @Override
    public void setContentLayout(int resId) {
        View.inflate(this,resId,mParentLayout);
        getViews();
        bindData();
        setListeners();
    }

    @Override
    public void showLoadingLayout() {
        mLoadingPb.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideLoadingLayout() {
        mLoadingPb.setVisibility(View.GONE);
    }

    public abstract BasePresenter getPresenter();

    public abstract void getViews();
    public abstract void bindData();
    public abstract void setListeners();

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(null!=getPresenter()) {
            getPresenter().onDestroy();
        }
    }
}

BasePresenter
public abstract class BasePresenter {
    protected Context mContext;
    protected V mViewCallBack;

    public BasePresenter(Context context,V viewCallBack) {
        this.mContext = context;
        this.mViewCallBack = viewCallBack;
        initModel();
//        onCreate();
    }

    public void initModel() {}
    public abstract void onCreate();
    public abstract void onDestroy();
}

IBaseViewはBaseActivity共通属性動作を定義する
public interface IBaseView {
    void initViews();
    void setContentLayout(int resId);
    void showToast(String msg);
    void showLoadingLayout();
    void hideLoadingLayout();
}

ILoginViewは、LoginActivityの基本的なビジネス属性を定義します.
public interface ILoginView {
    void login(T t);
}

githubプロジェクトアドレス