前言
以前有學(xué)過(guò)豹储,感覺(jué)理解不了桃漾,然后又用不到坏匪,就不了了之了 ,現(xiàn)在因?yàn)閷?shí)習(xí)公司的項(xiàng)目有用到撬统,如果不學(xué)的話感覺(jué)根本看不懂項(xiàng)目(其實(shí)學(xué)完之后還是看不懂??)适滓,所以就重新學(xué)過(guò),順便記錄一下恋追。
從全局的觀念來(lái)看凭迹,mvp模式只是一個(gè)思想,并沒(méi)有具體的苦囱,標(biāo)準(zhǔn)的編碼規(guī)定嗅绸,下面所說(shuō)的預(yù)備知識(shí),是為優(yōu)化MVP模式所服務(wù)的撕彤。
預(yù)備知識(shí)
- 面向接口的編程思想
- 向上轉(zhuǎn)型的概念
- 解耦
面向接口編程
接口的概念:
在Java程序設(shè)計(jì)語(yǔ)言中鱼鸠,接口不是類(lèi),而是對(duì)希望符合這個(gè)接口的類(lèi)的一組需求(出自《Java核心卷一》p222頁(yè))
面向接口編程呢,就是在開(kāi)始開(kāi)發(fā)前蚀狰,先定義好接口(可以理解為先列出一組需求)漆弄,然后再進(jìn)行開(kāi)發(fā)
向上轉(zhuǎn)型
即父類(lèi)引用指向子類(lèi)對(duì)象(即多態(tài)),看完下面的代碼應(yīng)該更好理解些
public interface IStudent {
String getName();
}
public class Student implements IStudent{//此時(shí)IStudent是父類(lèi)造锅,Student是子類(lèi)
@Override
public String getName() {
return "任我行";
}
}
public class Test {
public static void main(String[] args) {
IStudent iStudent;
iStudent=new Student();//父類(lèi)引用指向子類(lèi)的對(duì)象撼唾,這里做了向上轉(zhuǎn)型
System.out.println("學(xué)生的名字是:"+iStudent.getName());//打印結(jié)果:學(xué)生的名字是:任我行
}
}
解耦
解耦即降低依賴(lài)性
MVP模式
我覺(jué)得MVP模式的靈魂就是presenter層同時(shí)持有view層和model層的引用(請(qǐng)聯(lián)系上邊的向上轉(zhuǎn)型的概念)。
照此邏輯哥蔚,我們簡(jiǎn)單實(shí)現(xiàn)一個(gè)常見(jiàn)的登錄模塊倒谷。根據(jù)面向接口編程,我們首先列出我們的接口(需求):
/**
* View層的需求
*/
public interface IView {
//1. 獲取用戶的輸入信息
public User getViewUser();
//2. 登錄成功的操作
public void loginSuceess();
//3. 登錄失敗后的操作
public void loginFail();
}
/**
* Model層的需求
*/
public interface IModel {
//判斷信息是否正確
public boolean isOk(User user);
}
/**
* presenter層的需求
*/
public interface IPresenter {
//登錄操作
public void login();
}
好了糙箍,接口寫(xiě)完渤愁,現(xiàn)在去實(shí)現(xiàn)接口:
public class View extends AppCompatActivity implements IView{
private EditText mUsername;
private EditText mPassword;
private Button mButton;
private IPresenter iPresenter;//present的引用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mUsername = findViewById(R.id.et_username);
mPassword = findViewById(R.id.et_password);
mButton = findViewById(R.id.btn_login);
iPresenter = new Presenter(this);//父類(lèi)引用指向子類(lèi)對(duì)象,向上轉(zhuǎn)型深夯,這個(gè)this指向的是View本身抖格,也就是是傳入了一個(gè)IView的子類(lèi)對(duì)象
//此時(shí)Presenter同時(shí)持有Model層和View層的對(duì)象
mButton.setOnClickListener(new android.view.View.OnClickListener() {
@Override
public void onClick(android.view.View v) {
iPresenter.login();//此操作會(huì)執(zhí)行Pressenter對(duì)象的login方法
}
});
}
//實(shí)現(xiàn)IView的需求
@Override
public User getViewUser() {
return new User(mUsername.getText().toString(),mPassword.getText().toString());
}
@Override
public void loginSuceess() {
Toast.makeText(this, "登錄成功!", Toast.LENGTH_SHORT).show();
}
@Override
public void loginFail() {
Toast.makeText(this, "登錄失敼窘雹拄!", Toast.LENGTH_SHORT).show();
}
}
public class Model implements IModel{
//IModel的需求
@Override
public boolean isOk(User user) {
if (user.getUsername().equals("root")&&user.getPassword().equals("123")){
return true;
}
return false;
}
}
我覺(jué)得mvp模式的核心在此
//presenter層,聯(lián)系model和view的樞紐
public class Presenter implements IPresenter {
private IModel iModel;
private IView iView;
public Presenter(IView iView) {
this.iModel = new Model();//向上轉(zhuǎn)型
this.iView = iView;//向上轉(zhuǎn)型
}
//IPresenter的需求
@Override
public void login() {//當(dāng)View層點(diǎn)擊button的時(shí)候掌呜,將會(huì)調(diào)用到這個(gè)方法
if (iModel.isOk(iView.getViewUser())){
iView.loginSuceess();//執(zhí)行view層的loginSuceess
}else {
iView.loginFail();//執(zhí)行view層的loginFail
}
}
}
model滓玖,view,presenter的接口质蕉,就像是三條引子势篡,把它們聯(lián)系在了一起
實(shí)際的開(kāi)發(fā)中
感覺(jué)mvp模式比普通的開(kāi)發(fā)模式好不到哪里去,而且每次使用還都要定義一大堆接口模暗,麻煩死咯禁悠,不過(guò)好處是邏輯更加清晰了些(好像就只有這個(gè)好處。兑宇。)