1. 程式人生 > >[Android學習]Android中MVP模式初探1

[Android學習]Android中MVP模式初探1

前言:
1. 初識MVP模式時,看到它缺點是需要增加一倍的類的維護量。所以就暫時沒用它。但是,當一個類的程式碼行數達到一定的量(1000行以上),這時候維護類變得好麻煩,主要是功能變得多了,方法數量也變多了。這個時候真的是需要給類“瘦瘦身”。
2. 這時候重新看了MVP模式,確實發現了“寶”。

一、簡單定義

Model層:將功能邏輯等封裝才model層中,其中包括了Data的互動(資料庫、網路等),一般用作為介面實現來給Presenter層呼叫。
View層:一般是Activity或fragment,主要是封裝好用於互動介面用的方法,也是一般用作為介面實現來給Presenter層呼叫和呼叫Presenter反饋介面互動。
Presenter層:我認識它是作為MVP模式中關鍵的一層,使用者互動的操作通過View層傳到這裡,Presenter呼叫Model層和View層的方法來完成功能的流程(我們可以理解View層和Model層的方法大部分都不會在自己內部被呼叫,而是通過例項被Presenter層呼叫),然後通過View層反饋給使用者。

二、使用一個簡單的例子來實現一下

這裡我們寫個簡單計算器的Demo來實現下。

Model層

先定義介面,這裡我們寫的方法都是功能邏輯的處理。

public interface CalcModel
{
    /**
     * 這裡做一個簡單的計算
     * @param num1
     * @param num2
     * @return
     */
    int doSimpleCalc(int num1, int num2);
}

寫實現類,與該層中沒有持有其他層的引用。

public class CalcModelImpl
implements CalcModel {
@Override public int doSimpleCalc(int num1, int num2) { return num1+num2; } }

View層

同樣,先寫介面,這裡我寫的方法都是和介面互動相關的。

public interface CalcView
{
    /**
     * 初始化
     */
    void init();

    /**
     * 獲取數1的值
     * @return
     */
    int getNum1();

    /**
     * 獲取數2的值
     * @return
*/
int getNum2(); /** * 顯示結果值 * @param result */ void setCalcResult(int result); }

再寫實現類(Activity),持有Presenter的引用。

public class MainActivity extends Activity implements CalcView,View.OnClickListener
{
    private EditText mEtNum1;
    private EditText mEtNum2;
    private TextView mTvResult;
    private Button mBtnCalc;

    private CalcPresenter mPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 例項化Presenter層
        mPresenter=new CalcPresenterImpl(this);
        // 初始化
        mPresenter.onCreate();
    }

    @Override
    public void init()
    {
        mEtNum1= (EditText) findViewById(R.id.et_num1);
        mEtNum2= (EditText) findViewById(R.id.et_num2);
        mTvResult= (TextView) findViewById(R.id.tv_result);

        mBtnCalc= (Button) findViewById(R.id.btn_calc);
        mBtnCalc.setOnClickListener(this);
    }

    @Override
    public int getNum1()
    {
        try{
            return Integer.parseInt(mEtNum1.getText().toString());
        }
        catch (Exception e){
        }
        return 0;
    }

    @Override
    public int getNum2()
    {
        try{
            return Integer.parseInt(mEtNum2.getText().toString());
        }
        catch (Exception e){
        }
        return 0;
    }

    @Override
    public void setCalcResult(int result)
    {
        mTvResult.setText(result+"");
    }

    @Override
    public void onClick(View v)
    {
        switch (v.getId()){
            case R.id.btn_calc:
            {
                mPresenter.onClickCalc();
                break;
            }
            default:
                break;
        }
    }
}

Presenter層

寫介面類,一般為呼叫Model和View的方法。

public interface CalcPresenter
{
    /**
     * 初始化
     */
    void onCreate();

    /**
     * 按鈕點選計算
     */
    void onClickCalc();
}

寫實現類,Presenter持有View與Model的引用。

public class CalcPresenterImpl implements CalcPresenter
{
    CalcView mView;
    CalcModel mModel;

    public CalcPresenterImpl(CalcView mView){
        this.mView=mView;
        mModel=new CalcModelImpl();
    }

    @Override
    public void onCreate()
    {
        mView.init();
    }

    @Override
    public void onClickCalc()
    {
        mView.setCalcResult(mView.getNum1()+mView.getNum2());
    }
}

執行

總結與思考

關於Presenter持有Model與View的引用,還有View層持有Presenter的思考。這裡我覺得可以,將例項化用靜態工廠模式的方式來建立例項,會比較好些。