97干视频,99国产精品懂色,亚洲精品99久久久久中文字幕,伊人五月丁香综合AⅤ,国产精品成人免费999

當前位置: 移動互聯(lián)網(wǎng)學(xué)院 > Android開發(fā) > android開發(fā)學(xué)習(xí):關(guān)于Android MVP模式的思考
android開發(fā)學(xué)習(xí):關(guān)于Android MVP模式的思考 時間:2017-03-14     來源:Android開發(fā)學(xué)習(xí)網(wǎng)

Android MVP模式概述

MVP是指Model,View和Presenter的縮寫,是MVC模式的一種改進版。MVP是一種非常適合Android應(yīng)用的開發(fā)模式,它 將把邏輯相關(guān)代碼從presentation Layer中分離出去 ,所以,所有界面應(yīng)該顯示什么和界面如何顯示這些是相互分離的, 在理想狀態(tài)下,MVP模式可以隨意切換視圖顯示的形式。

但是,需要首先聲明的是,MVP并不是 一個框架模式 ,它只負責presentation Layer。在Android項目中,還可能存在Domain Layer和Data Layer,它們分別負責業(yè)務(wù)邏輯和數(shù)據(jù)存儲。

Android MVP模式概述
Android MVP模式概述

The presenter

The presenter充當?shù)氖莢iew和model模塊中間人的角色。它從model模塊獲得數(shù)據(jù)并發(fā)送給view模塊。 但是不同于MVC,presenter模塊也決定用戶和界面交互時界面如何響應(yīng) 。

The View

View模塊,一般由Activity或者Fragment實現(xiàn),每個View實例一般都包含一個presenter實例的引用,并負責實例化presenter。理想情況下,你可以使用dagger來實現(xiàn)依賴注入。view的任務(wù)就是當用戶操作界面時,調(diào)用presenter實例的功能來進行響應(yīng)。

The Model

在設(shè)計良好的分層架構(gòu)中,model應(yīng)該只是domain layer和業(yè)務(wù)邏輯的入口,比如說, clear architecture 。但是你也可以把所有界面顯示無關(guān)的邏輯都作為model。
 

Android MVP模式示例

關(guān)于MVP架構(gòu)的實例有很多,比如 google官方架構(gòu) 。這里我就給出一下我重構(gòu)項目一個模塊的類圖,然后大致說一下實現(xiàn)。

Android MVP模式示例
Android MVP模式示例

首先定義了 BaseView 和 BasePresenter 兩個接口,實現(xiàn)了 BaseActivity 和 BaseFragment 兩個基礎(chǔ)類。需要注意的是,因為每個View都需要持有一個特定類型的presenter對象,所以,在 BaseView 定義時,使用了范型。除此之外,你可以在 initPresenter 函數(shù)中構(gòu)造出所需要的presenter對象。 showLoading 和 stopLoading 函數(shù)是所有視圖進行網(wǎng)絡(luò)數(shù)據(jù)加載時所需要的方法,其具體使用場景后邊可以看到,這里這兩個接口是在 BaseActivity 中實現(xiàn)的。

public interface BaseView {

void showLoading();

void stopLoading();

void initPresnter();

T getPresenter();

}

public interface BasePresenter {

}

public class BaseActivity extends Activity{

public void showLoading() {

}

public void stopLoading() {

}

}

public class BaseFragment extends Fragment {

public void showLoading() {

}

public void stopLoading() {

}

}

然后是data模塊中的相關(guān)類和接口的定義。我們在 DataContract 接口中定義所有相關(guān)的view和data。

public interface DataContract {

interface DataView extends BaseView {

void showFragment(BaseFragment fragment);

}

interface DataPresenter extends BasePresenter {

void switchToDataList();

void switchToDataTree();

}

interface DataListView extends BaseView {

void showDataList(List data);

}

interface DataListPresenter extends BasePresenter {

void loadDataList();

}

interface DataTreeView extends BaseView {}

interface DataTreePresenter extends BasePresenter {}

}

在 DataContract 接口中,我們可以清晰的看到這個模塊中所有的view和presenter類型和他們的接口。這樣無疑可以幫助其他程序員快速了解本模塊的業(yè)務(wù)邏輯。下面,我們來看一下 DataListFragmnet 和 DataListPresenter 的實現(xiàn)。

public class DataListFragment extends BaseFragment implements DataContract.DataListView {

private DataContract.DataListPresenter mPresenter;

@Override

public void initPresnter() {

mPresenter = new DataListPresenter(this);

}

@Override

public DataContract.DataListPresenter getPresenter() {

return mPresenter;

}

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

initPresnter();

//需要加載數(shù)據(jù)或者接收到界面點擊事件時,調(diào)用presenter接口進行初始化或者響應(yīng)。

mPresenter.loadDataList();

}

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

return inflater.inflate(R.layout.fragment_data_list, container, false);

}

@Override

public void showDataList(List data) {

//將數(shù)據(jù)傳給adapter等數(shù)據(jù)展示的視圖

}

}

public class DataListPresenter implements DataContract.DataListPresenter {

private DataContract.DataListView mView;

public DataListPresenter(DataContract.DataListView view) {

super();

this.mView = view;

}

@Override

public void loadDataList() {

//調(diào)用baseview的接口,這些接口實現(xiàn)在baseFragment或者BaseActivity中

mView.showLoading();

//getdata from network

mView.stopLoading();

mView.showDataList(Arrays.asList("a","b","c"));

}

}

上述代碼中有很多可以好好思考的地方。首先是 showLoading 和 stopLoading 這兩個函數(shù)。這兩個函數(shù)接口定義在 BaseView ,實現(xiàn)在 BaseFragment ,所以當 DataListFragment 繼承了 BaseFragment 并且實現(xiàn)了 BaseView 時,它并不需要再次定義上述兩個接口,畢竟在一個app中,網(wǎng)絡(luò)加載時的laoding動畫一般都是一致的。然后是view和presenter之間函數(shù)調(diào)用的問題。首先,view在需要初始化或者需要處理點擊事件時,需要調(diào)用presenter的函數(shù),而不是自己來進行處理。而且二者之間的數(shù)據(jù)傳遞必須是presenter調(diào)用view的接口傳遞給view數(shù)據(jù),而不是view調(diào)用presenter接口獲得數(shù)據(jù)然后自己展示。