MVC架構(gòu):
MVC就是Model-View-Controller,它們的作用是:
(數(shù)據(jù)模型)Model:數(shù)據(jù)的封裝和保存矗漾,業(yè)務(wù)邏輯和實體模型
(視圖)View:視圖界面嬉挡,對應(yīng)于布局文件
(控制器)Controller:業(yè)務(wù)邏輯续室,對應(yīng)于Activity、Fragment等
它們之間的關(guān)系如下圖所示:
View傳送指令到Controller,Controller完成業(yè)務(wù)邏輯后,改變Model的狀態(tài),Model將新的數(shù)據(jù)發(fā)送到View膜楷,這就是MVC模式的處理邏輯。
MVP架構(gòu):
MVP是Model-View-Presenter,它們的作用如下:
Model:業(yè)務(wù)邏輯和實體模型挑围,用來操作實際的數(shù)據(jù),包含Bean和Model的抽象接口來降低耦合贮勃。
View:就是Android中的視圖贪惹,需要建立一個View的抽象接口View Interface。通過實現(xiàn)View的接口來實現(xiàn)View與Presenter的交互寂嘉,從而降低耦合奏瞬。對應(yīng)于Activity,負責(zé)View的繪制與用戶交互泉孩;
Presenter:View和Model的中間樞紐硼端,處理和用戶交互的邏輯。
MVP和MVC的對比:
MVP架構(gòu):
View不直接與Model交互寓搬,而是通過與Presenter交互來與Model間接交互珍昨。
Presenter與View的交互是通過接口來進行的。
通常View與Presenter是一對一的句喷,但復(fù)雜的View可能綁定多個Presenter來處理邏輯镣典。
MVC架構(gòu):
View可以與Model直接交互。
Controller是基于行為的唾琼,并且可以被多個View共享兄春。
可以負責(zé)決定顯示哪個View。
通過一個簡單的例子來理解MVP模式:
View層:
/**
* ViewInterface
* 定義一些通用的view接口
*/
public interface LoadDataView {
/***
* 耗時操作锡溯,加載數(shù)據(jù)赶舆,顯示Progress
*/
void showLoading();
/***
* 隱藏Progress
*/
void hideLoading();
}
/**
* 更細小的,用來顯示圖書細節(jié)的View接口
*/
public interface LoadBookView extends LoadDataView {
void showDetailsView(BookEntity entity);
}
/***
* Fragment,屬于View層祭饭,實現(xiàn)了ViewInterface(LoadBookView)
*/
public class BookDetailFragment extends Fragment implements LoadBookView{
/**圖書條形碼ISBN號*/
public static final String ISBN = "9787121060748";
/**持Presenter對象*/
private BookDetailsPresenter presenter;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initWidget();
presenter = new BookDetailsPresenter(getActivity(), ISBN); // 實例化一個presenter對象
presenter.setView(this); //讓Presenter持一個ViewInterface實例(LoadBookView)
presenter.loadData(); //告訴Presenter快給我加載Data
}
@Override
public void showDetailsView(BookEntity entity) {
//更新UI等操作
}
@Override
public void showLoading() {
rlProgress.setVisibility(View.VISIBLE);
}
@Override
public void hideLoading() {
rlProgress.setVisibility(View.GONE);
}
}
2芜茵、Presenter層:
public class BookDetailsPresenter {
/**持一個Model層的對象,用來從網(wǎng)頁接口Rest Api中提取數(shù)據(jù)*/
private RestApi restApi = null;
/**一個ViewInterface對象倡蝙,用來回調(diào)Data給View*/
private LoadBookView loadBookView;
private String isbn;
public BookDetailsPresenter(Context context, String isbn) {
restApi = new RestApiImpl(context);
this.isbn =isbn;
}
public void setView(LoadBookView loadBookView) {
this.loadBookView = loadBookView;
}
public void loadData() {
loadBookView.showLoading();
//耗時操作九串,開個線程異步的加載數(shù)據(jù)
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
restApi.getBookDetailByIsbn(isbn, bookDetailsCallback);
}
});
thread.start();
}
//匿名內(nèi)部類,接收bookDetailCallback的回調(diào)數(shù)據(jù)
private RestApi.BookDetailsCallback bookDetailsCallback = new RestApi.BookDetailsCallback() {
@Override
public void onBookEntityLoaded(BookEntity bookEntity) {
notifyDataLoadedSuccessful(bookEntity);
BookDetailsPresenter.this.loadBookView.hideLoading();
}
@Override
public void onError(Exception e) {
//異常后的相關(guān)處理
}
};
/***
* 通知獲取數(shù)據(jù)成功了寺鸥,趕快通知UI更新吧
*/
private void notifyDataLoadedSuccessful(final BookEntity bookEntity) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
BookDetailsPresenter.this.loadBookView.showDetailsView(bookEntity);
}
});
}
}
3蒸辆、Model層:
/***
* 整個應(yīng)用程序需要的數(shù)據(jù)實體類
*/
public class BookEntity {
//一些set征炼,get方法
}
/**
* 一個接口,用來從rest api api獲得數(shù)據(jù)躬贡,它的實現(xiàn)在RestApiImpl中
*/
public interface RestApi {
String API_ISBN_BASE_URL = "https://api.douban.com/v2/book/isbn/";
/***
* 更細小的接口谆奥,用來將獲取到的數(shù)據(jù),回調(diào)給它的調(diào)用者
*/
interface BookDetailsCallback {
void onBookEntityLoaded(BookEntity bookEntity);
void onError(Exception e);
}
/**
* 從網(wǎng)絡(luò)獲取數(shù)據(jù)拂玻,然后通過bookDetailCallback回調(diào)給Presenter
* @param isbn
* @param bookDetailsCallback
*/
void getBookDetailByIsbn(final String isbn, final BookDetailsCallback bookDetailsCallback);
}
參考文章:http://www.reibang.com/p/95c9088eef4f
http://www.codeceo.com/article/mvp-android.html