寫在前面
接到公司的需求,把之前那個(gè)實(shí)在維護(hù)不動(dòng)的項(xiàng)目重構(gòu)一下(之前項(xiàng)目是eclipse+沒(méi)有架構(gòu)寫的,跟平鋪差不多),臨時(shí)組建了4個(gè)人的Android開發(fā)小組,確定架構(gòu)的時(shí)候全票通過(guò)了MVP。 之前雖然用過(guò)MVP,可總意會(huì)不到MVP的精髓所在,反而經(jīng)常被繞暈。也看了很多關(guān)于MVP的技術(shù)博客。怎么寫的都有,很多分不清M層和P層的職責(zé)所在,為了發(fā)揮MVP的優(yōu)勢(shì),特地找到了Google官方發(fā)布的MVP源碼??偹惆l(fā)現(xiàn)了新大陸。(本文不會(huì)講解官方的源碼,只針對(duì)個(gè)人理解進(jìn)行敘述,大神至此請(qǐng)無(wú)視)
啥是MVP
Model View Presenter俗稱MVP,該架構(gòu)是從著名的MVC架構(gòu)演變而來(lái)的。 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過(guò)于臃腫。為了優(yōu)化這一情況特地提出MVP架構(gòu)模式,使得每層各盡其職,條理清晰。
用一張圖來(lái)描述下他們之間的關(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)。
說(shuō)了半天到底怎么個(gè)意思?
我們還是擼下代碼吧,還是擼代碼來(lái)的實(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)行,最后通過(guò)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é)果為:沒(méi)找到處理?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,并通過(guò)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)用過(guò)程
mView.showView(mMainModel.getData(condition));
}
}
至此,完整的MVP架構(gòu)已經(jīng)敘述完畢了,通過(guò)以上的描述我們可以清楚的了解到MVP目前比較火的架構(gòu)之一。他能最大程度的降低代碼耦合程度以及維護(hù)成本,提高代碼的維護(hù)性和可讀性。從而達(dá)到以不變應(yīng)萬(wàn)變的目的。
以上是本人對(duì)MVP的全部理解。如果疑問(wèn)和建議歡迎留言指點(diǎn)。
|