轉(zhuǎn)載請(qǐng)注明版權(quán)
寫在前面
? ? ? ?接到公司的需求,把之前那個(gè)實(shí)在維護(hù)不動(dòng)的項(xiàng)目重構(gòu)一下(之前項(xiàng)目是eclipse+沒有架構(gòu)寫的韵卤,跟平鋪差不多),臨時(shí)組建了4個(gè)人的Android開發(fā)小組,確定架構(gòu)的時(shí)候全票通過了MVP。
? ? ? ?之前雖然用過MVP刁笙,可總意會(huì)不到MVP的精髓所在,反而經(jīng)常被繞暈谦趣。也看了很多關(guān)于MVP的技術(shù)博客疲吸。怎么寫的都有,很多分不清M層和P層的職責(zé)所在前鹅,為了發(fā)揮MVP的優(yōu)勢(shì)摘悴,特地找到了Google官方發(fā)布的MVP源碼〗⒒妫總算發(fā)現(xiàn)了新大陸蹂喻。(本文不會(huì)講解官方的源碼,只針對(duì)個(gè)人理解進(jìn)行敘述捂寿,大神至此請(qǐng)無視)
啥是MVP
? ? ? ?Model View Presenter俗稱MVP口四,該架構(gòu)是從著名的MVC架構(gòu)演變而來的。
? ? ? ?Android應(yīng)用開發(fā)類似MVC架構(gòu)秦陋。開發(fā)中將XML文件視為MVC中的View角色蔓彩,將Activity則視為MVC中的Controller角色。但是在實(shí)際應(yīng)用開發(fā)中Activity大多充當(dāng)Controller和View的合體驳概。于是Activity既要負(fù)責(zé)視圖的顯示赤嚼,又要負(fù)責(zé)對(duì)業(yè)務(wù)邏輯的處理。使得Activity過于臃腫顺又。為了優(yōu)化這一情況特地提出MVP架構(gòu)模式更卒,使得每層各盡其職,條理清晰稚照。
用一張圖來描述下他們之間的關(guān)系
M:邏輯層逞壁,數(shù)據(jù)邏輯流济,網(wǎng)絡(luò)邏輯全寫在這
P:調(diào)度層,M層和V層的交互需要P層調(diào)度
V:UI層腌闯,一般指Activity Fragement等等ui界面
咋用的MVP绳瘟?
? ? ? ?在實(shí)際的使用使用中,我采用了Google官方的那種寫法姿骏,除了MVP三層以外還增加了一個(gè)Contract契約類,將邏輯接口以及UI接口全部寫在了Contract契約類中糖声。然后Presenter和View分別實(shí)現(xiàn)Contract類中各自的接口。這么做的目的是方便管理分瘦,提高代碼的可讀性蘸泻。打開Contract后一目了然,能非常清晰快速的了解到本模塊的所有邏輯結(jié)構(gòu)嘲玫。
說了半天到底怎么個(gè)意思悦施?
我們還是擼下代碼吧,還是擼代碼來的實(shí)在一點(diǎn)去团,首先我們看一張類結(jié)構(gòu)圖
? ? ? ?BaseView和BasePresenter兩個(gè)類抡诞,命名上就能看出這倆類是V層與P層的基類,主要實(shí)現(xiàn)所有View和Presenter都需要使用的接口土陪。
? ? ? ?MainContract:該類為契約類昼汗,集成了View層的ui更新接口以及Presenter層調(diào)用邏輯接口。
public class MainContract {
interface View extends BaseView<Presenter> {
void showView(String data);
}
interface Presenter extends BasePresenter {
void loadData(int condition);
}
}
? ? ? ?MainModel:該類為M層的邏輯處理類鬼雀,所有的邏輯處理以及聯(lián)網(wǎng)等均在此類中進(jìn)行顷窒,最后通過P層調(diào)用從而實(shí)現(xiàn)邏輯驅(qū)動(dòng)。
public class MainModel {
/**
* 處理邏輯
*
* @param condition 處理?xiàng)l件
* @return 處理結(jié)果
*/
public String getData(int condition) {
switch (condition) {
case 1: {
return "處理結(jié)果為1";
}
case 2: {
return "聯(lián)網(wǎng)處理結(jié)果為2";
}
default: {
}
break;
}
return "處理結(jié)果為:沒找到處理?xiàng)l件";
}
}
? ? ? ?MainActivity:該類為V層的UI處理類源哩,實(shí)現(xiàn)MainContract.View接口鞋吉。主要負(fù)責(zé)Presenter,Model的初始化励烦,以及UI的更新操作坯辩。
public class MainActivity extends AppCompatActivity implements MainContract.View {
MainContract.Presenter mPresenter;
TextView tv;
Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
btn = (Button) findViewById(R.id.btn);
//Model和Presenter初始化
new MainPresenter(new MainModel(), this);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mPresenter.loadData(1);
}
});
}
@Override
public void setPresenter(MainContract.Presenter presenter) {、
//獲取Presenter
this.mPresenter = presenter;
}
@Override
public void showView(String data) {
//更新UI
tv.setText(data);
}
}
? ? ? ?MainPresenter:該類為P層的調(diào)度處理類崩侠,主要負(fù)責(zé)調(diào)用View層以及Model層的方法或接口以實(shí)現(xiàn)調(diào)度的職責(zé)漆魔。該類構(gòu)造函數(shù)中接收Activity初始化好的Model和View,并通過View設(shè)置Presenter使得每一個(gè)實(shí)現(xiàn)MainContract.View接口的View均可得到Presenter對(duì)象却音,以方便后續(xù)操作改抡。
public class MainPresenter implements MainContract.Presenter {
MainModel mMainModel;
MainContract.View mView;
public MainPresenter(@NonNull MainModel mainModel, @NonNull MainContract.View view) {
this.mMainModel = mainModel;
this.mView = view;
mView.setPresenter(this);
}
@Override
public void loadData(int condition) {
//調(diào)用過程
mView.showView(mMainModel.getData(condition));
}
}
? ? ? ?至此,完整的MVP架構(gòu)已經(jīng)敘述完畢了系瓢,通過以上的描述我們可以清楚的了解到MVP目前比較火的架構(gòu)之一阿纤。他能最大程度的降低代碼耦合程度以及維護(hù)成本,提高代碼的維護(hù)性和可讀性夷陋。從而達(dá)到以不變應(yīng)萬變的目的欠拾。
以上是本人對(duì)MVP的全部理解胰锌。如果疑問和建議歡迎留言指點(diǎn)。