Android MVP模式直接用版本

引言

        如果對於mvp和mvc不太熟悉的童鞋,請花一點時間閱讀下面文字內容,純手工打些本人一點粗糙的見解。或者問問度娘多多學習。熟悉者可直接跳過看乾貨,擼代碼階段。

      在說mvp之前,相信大家應該都熟悉了mvc(model 、 view 、 control)。在Android的架構中Activity,fragment,佈局的xml相當於View。然而在實際的開發過程中,Android的View層任務太繁重,大家將V和C都糅雜在Activity、Fragment中,這就導致了在實際開發中View層太過累贅,一不小,幾次代碼迭代過後,一個Activity或者Fragment中的代碼就有幾千行,有時候修改個功能在笨重的代碼中摸爬滾打半天才找到關鍵點,對於不熟悉代碼的開發者來說(或者前人編寫代碼質量太低)那代碼迭代接手後簡直是妙不可言。所以將視圖和業務邏輯代碼分開勢在必行。

       基於這個現狀,我們偉大的Google粑粑設計了一個更優的框架模式來解決這個問題。就是目前實際開發中火熱的MVP模式(model 、 view 、presenter)。用presenter將model和view隔離開來,一切業務邏輯處理都是通過presenter來進行操作,也就是說presenter是視圖的數據的橋樑,視圖和數據相隔兩端,“可遠觀而不可褻玩”。強制只能使用presenter作爲“郵遞員”來”通信“。



正文

            上圖最爲直接,區別:mvc結構,一眼便知,model和view並沒有隔離,view一隻手悄悄的碰到了model層。而mvp中presenter完全壟斷了與數據實體的”貿易“。視圖要數據必須通過presenter。這樣將業務邏輯剝離出去,視圖層專注view的展現。

            萬事萬物,有優點就有缺點,偉大的孟子大學者就曾說過”魚與熊掌不可兼得“。

            優點:最大的優點剝離了視圖層和業務邏輯層,讓各個類的分工更爲明確,邏輯更爲清晰,代碼擴展性更高,後期代碼迭代更新更加容易,同時也方便了單元測試的編寫,以前將視圖與業務混合在一起的時候,要寫單元測試很多時候真的是無從下手。相對於MVP模式來說寫單元測試就更加容易了。因爲職責更加清晰,測試的目標就明確多了。

            缺點:相對而言,MVP模式的代碼量就多了,類文件也多了,簡單的一個業務邏輯操作就要各方來配合協作(即是需要presenter 和 view的接口)。但是這個問題完全在可以接收的範圍。完全符合Java的抽象封裝設計原則(接口隔離,開閉原則,里氏代換不熟悉的童鞋闊以問問偉大的度娘)。



MVC模式

                        


MVP模式



   

   代碼結構

            首先是View和presenter的接口,抽象出view對象的綁定方法。

            IView.java

            public interface IView {

                    void bindView();

                    void UnbindView();

            }

IPresenter.java

public interface IPresenter {

    void register(V view);

    void unRegister();

}

    BasePresenter實現IPresenter接口,爲業務邏輯層presenter的基類。用弱引用來接收View的對象,在取消註冊的時候銷燬view對象,保證View不會造成內存泄漏。

BasePresenter.java

public class BasePresenter implements IPresenter {

    protected WeakReference iView;

    @Override

    public void register(V view) {

        Log.i(TAG, "BasePresenter register: ");

        iView = new WeakReference(view);

    }

    @Override

    public void unRegister() {

        Log.i(TAG, "BasePresenter unRegister: ");

        iView.clear();

    }

}

    BaseActivity實現IView接口,爲視圖層的基類(也就是Activity的基類),這是一個抽象類,實現了視圖層到業務邏輯層的綁定與解綁,抽象方法createPresenter()子類必須實現,來確保不通的業務邏輯層。

BaseActivity.java

public abstract class BaseActivity

extends Activity implements IView{

    protected P iPresenter;

    @Override

    protected void onCreate(@Nullable Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        bindView();

    }

    @Override

    protected void onDestroy() {

        super.onDestroy();

        UnbindView();

    }

    @Override

    public void bindView() {

        iPresenter = createPresenter();

        iPresenter.register(this);

    }

    @Override

    public void UnbindView() {

        iPresenter.unRegister();

    }

    protected abstract P createPresenter();

}

    接下來是具體的使用MVP的流程了,定義三方交接接口

public interface DemoContract {

    interface View{

        void demoView(String test);

    }

    interface Presenter{

        void demoPresenter();

    }

    interface Model{

        void demoModel(ModelListener modelListener);

        interface ModelListener{

            void completed(String test);

        }

    }

}

    視圖層DemoActivity.java基層BaseAcitivity實現createPresenter()方法,DemoContract.View接口。

public class DemoActivity extends BaseActivity implements DemoContract.View {

    @Override

    protected void onCreate(@Nullable Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        iPresenter.demoPresenter();

    }

    @Override

    protected DemoPresenter createPresenter() {

        return new DemoPresenter();

    }

    @Override

    public void demoView(String test) {

        Toast.makeText(this, test, Toast.LENGTH_LONG).show();

    }

}

    業務邏輯層DemoPresenter.java基層BasePresenter實現DemoContract.Presenter接口

public class DemoPresenter extends BasePresenter implements DemoContract.Presenter {

    DemoContract.Model model = new DemoModel();

    @Override

    public void demoPresenter() {

        model.demoModel(new DemoContract.Model.ModelListener() {

            @Override

            public void completed(String test) {

                iView.get().demoView(test);

            }

        });

    }

}

數據實體層DemoModel.java實現DemoContract.Model接口,用接口回調異步返回數據。

public class DemoModel implements DemoContract.Model{

    @Override

    public void demoModel(ModelListener modelListener) {

        modelListener.completed("mvp test");

    }

}



最後附上源碼傳送門:https://github.com/pffo/mvp

*請大神多多指教*


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章