幾步教你怎么寫MVP

概述

首先我們應該是知道的是,軟件設計中,降低耦合度是很重要的,大名鼎鼎的MVC(Model-View-Controller)便是因此而生,而在android設計中MVP早就紅了半邊天,我也在簡書博客中看到一些文章 前端也在談這一套軟件設計模式,雖然如今大勢已經是MVVM,但是腳步得一扎一個穩, 我們先學習MVP是很有必要的。
MVP(Model-View-Presenter,模型-視圖-表示器)模式則是由IBM開發出來的一個針對C++和Java的編程模型,大概出現于2000年,是MVC模式的一個變種,主要用來隔離UI、UI邏輯和業務邏輯、數據。也就是說,MVP 是從經典的模式MVC演變而來,它們的基本思想有相通的地方:Controller/Presenter負責邏輯的處理,Model提供數據,View負責顯示。

MVP最簡單的模型

View層不再和Model層關聯,他們之間通過Presenter層關聯,這里就出明顯的感覺出P層的任務會比較重,邏輯會相對其他層復雜,同時也是MVP中最關鍵的層。而聯系M-P,P-V的紐帶,是接口,即本質是面向接口的編程,來降低各個模塊的耦合度,其實與Presenter相關的兩個接口ViewInterface、ModelInterface,View其實是ViewInterface的實現類,Model是ModelInterface實現類,然后通過接口Presenter便輕松的連接了Model與View(這只是最簡單的模型情況,事實上,Model與Presenter并不是簡單直接定義的類,實現時,有是繼承抽象類的,有繼承基礎的泛型類的,有實現某些接口的,我們在這里只編寫簡單的模型即可

谷歌官方也有MVPdemo todo_mvp,其將接口以內部類的形式封裝在一個總的接口類里,且我覺得其實現方法沒有鴻洋大神寫的好,同時送上鴻洋的MVP blog 鴻洋 MVP
同時,對于RxJava的MVP,則是另一套,以后學到時我會再整理一篇。

編寫

我們編寫一個簡單的demo,功能為每次開啟應用時顯示存儲在本地的名字,同時有一個按鈕,編輯名字后按該按鈕保存名字,下次啟動后便為上次的名字:

首先看目錄

目錄層次.png

編寫model
首先我們要知道model需要進行什么操作,我們需要進行名字的存儲和讀取操作,因此定義了如下接口

package com.example.mvpdemo.datamodel;

/**
 * Created by Xiamin on 2016/9/5.
 */
public interface IGetString {
    public String getName();
    public void saveName(String name);
}

我們編寫該接口的實現類,即我們的model具體實現

package com.example.mvpdemo.datamodel;

import android.content.Context;
import android.content.SharedPreferences;

import com.example.mvpdemo.MainActivity;

/**
 * Created by Xiamin on 2016/9/5.
 */
public class FileOperate implements IGetString {
    @Override
    public String getName() {
        String name;
        SharedPreferences sharedPreferences;
        sharedPreferences = MainActivity.getAppContext().getSharedPreferences("data", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        name = sharedPreferences.getString("name","");
        return name;
    }

    @Override
    public void saveName(String name) {
        SharedPreferences sharedPreferences;
        sharedPreferences = MainActivity.getAppContext().getSharedPreferences("data", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString("name",name);
        editor.commit();
    }
}

編寫view
我們的view有一個EditText,一個Button,我們需要進行EditText的數據讀取和填充操作,因此我們定義了如下接口

package com.example.mvpdemo.view;

/**
 * Created by Xiamin on 2016/9/5.
 */
public interface IGetStringView {

    public void showName(String name);
    public String getName();
}

view的實現類為

public class MainActivity extends AppCompatActivity implements IGetStringView{

    private EditText editText;
    private Button button;
    private GetStringPresenter presenter;
    private static Context mContext ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        editText = (EditText) findViewById(R.id.editText);
        button = (Button) findViewById(R.id.button);
        mContext = getApplicationContext();

        presenter = new GetStringPresenter(this);
        presenter.showName();

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                presenter.saveName();
            }
        });

    }

    @Override
    public void showName(String name) {
        editText.setText(name);
    }

    @Override
    public String getName() {
        return editText.getText().toString();
    }

    public static Context getAppContext()
    {
        return mContext;
    }

}

編寫presenter
Presenter編寫就很簡單了,多態獲取兩個接口的實現類,并進行相應操作

/**
 * Created by Xiamin on 2016/9/5.
 */
public class GetStringPresenter {
    private IGetString getString;
    private IGetStringView getStringView;

    public GetStringPresenter(IGetStringView view)
    {
        this.getStringView = view;
        getString = new FileOperate();
    }

    public void saveName()
    {
        getString.saveName(getStringView.getName());
    }

    public void showName()
    {
        getStringView.showName(getString.getName());
    }
}

總結

這樣我們一個簡單的mvp的demo便能運行起來了,通過閱讀代碼我們發現,view中未作任何數據操作,只負責與UI的交互,而Preneter中的操作也變得很簡單,因為之前接口的定義恰當, 我們僅僅是通過
getString.saveName(getStringView.getName());簡單的一句話就獲取 了數據并存儲到了本地。
希望大家都編寫自己的demo,編寫完做一些功能的修改,便會發現解耦帶來的莫大好處。希望通過跟著本文章的編寫,能給大家帶來更多的思考。

ps:新人一枚,請多多指教

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,466評論 25 708
  • 作者:李旺成 時間:2016年4月3日 “Android MVP 詳解(下)”已經發布,歡迎大家提建議。 MVP ...
    diygreen閱讀 129,019評論 86 1,321
  • 轉載至:http://www.lxweimin.com/p/9a6845b26856 “Android MVP 詳解...
    SnowDragonYY閱讀 10,356評論 5 241
  • 烏鎮,一幅淡雅的水墨畫,在如畫的江南山和水之間,慢慢的流淌,也流淌在我的心田。寧靜,雅致,悠閑和浪漫,最宜在濛濛細...
    絳心閱讀 1,044評論 0 6
  • 孔子說,三十而立,四十而不惑!在四十不惑之年,我曾經很多迷惑,終于有一天,幡然醒悟,人生就是不設限!想做就去做! ...
    雪飛老師閱讀 1,251評論 0 2