android mvc mvp 区别,谈谈Android框架 MVC、MVP、MVVM的区别
今天寫寫Android的MVC、MVP、MVVP三個框架的對比,并加深自己對這三個框架的理解。
548b9bea8dc18.gif
一 . MVC:Model-View-Controller
MVC全名是:Model(模型) View(視圖) Controller(控制器) 是軟件[架構(gòu)]中最常見的框架,簡單來說,就是通過Controller的控制去操作Model層的數(shù)據(jù),并且返回給View作展示。
1.MVC的工作原理?
Paste_Image.png
1. View接受用戶的交互請求。
2. View將請求轉(zhuǎn)交給Controller。
3. Controller操作Model進(jìn)行數(shù)據(jù)更新。
4. 數(shù)據(jù)更新之后,Model通知View數(shù)據(jù)變化。
5. View顯示更新之后的數(shù)據(jù)。
2.MVC優(yōu)點(diǎn)?
1)把業(yè)務(wù)邏輯全部分離到Controller中,模塊化程度高。當(dāng)業(yè)務(wù)邏輯變更的時候,不需要變更View和Model,只需要更換Controller就行了。
2)須手動或通過觀察者模式進(jìn)行多視圖更新。
3.MVC缺點(diǎn)?
1)Controller測試?yán)щy。Controller不知道任何View的細(xì)節(jié),一個Controller能被多個View使用。
2)View無法組件化,復(fù)用性較差。View是強(qiáng)依賴特定的Model的,如果需要把這個View抽出來作為一個另外一個應(yīng)用程序可復(fù)用的組件就困難了,因?yàn)椴煌绦虻牡腗odel是不一樣的。
4.使用場景?
適用于較小,功能較少,業(yè)務(wù)邏輯較少的項(xiàng)目。
二 . MVP:Model-View-Presenter
Presenter將Model的變化返回給View。和MVC不同的是,presenter會反作用于view,不像controller只會被動的接受view的指揮。正常情況下,發(fā)現(xiàn)可以抽象view,暴漏屬性和事件,然后presenter引用view的抽象。這樣可以很容易的構(gòu)造view的mock對象,提高可單元測試性。在這里,presenter的責(zé)任變大了,不僅要操作數(shù)據(jù),而且要更新view。
在Passive View中,為了減少UI組件的行為,使用controller不僅控制用戶事件的響應(yīng),而且將結(jié)果更新到view上。可以集中測試controller,減小view出問題的風(fēng)險。
1.MVP的工作原理?
Paste_Image.png
1. View接受用戶的交互請求
2. View將請求轉(zhuǎn)交給Presenter
3. Presenter操作Model進(jìn)行數(shù)據(jù)庫更新
4. 數(shù)據(jù)更新之后,Model通知Presenter數(shù)據(jù)發(fā)生變化
5. Presenter更新View的數(shù)據(jù)
2.MVP優(yōu)點(diǎn)?
1.便于測試。
Presenter對View是通過接口進(jìn)行,在對Presenter進(jìn)行不依賴UI環(huán)境的單元測試的時候。可以通過Mock一個 View對象,這個對象只需要實(shí)現(xiàn)了View的接口即可,單元測試的時候就可以完整的測試Presenter業(yè)務(wù)邏 輯的正確性。
2.View可以進(jìn)行組件化。
在MVP當(dāng)中,View不依賴Model。這樣就可以讓View從特定的業(yè)務(wù)場景中脫離出來,可以說View可以做到對業(yè)務(wù)邏輯完全無知。它只需要提供一系列接口提供給上層操作。
3.View高度復(fù)用。
4.解耦。
3.MVP缺點(diǎn)?
1.維護(hù)比較困難。
Presenter中除了業(yè)務(wù)邏輯以外,還有大量的View->Model,Model->View的手動同步邏輯,造成Presenter比較笨重,維護(hù)起來會比較困難。
4.使用場景?
視圖界面不是很多的項(xiàng)目中。
5 . 代碼示例
Paste_Image.png
Paste_Image.png
MainActivity
public class MainActivity extends Activity implements IUserInfoShow {
private static final String TAG = "MVP";
private UserInfoPresenter mUserInfoPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mUserInfoPresenter = new UserInfoPresenter(this, new GetUserInfoImpl());
mUserInfoPresenter.getUserInfo(123);
}
@Override
public void beforeLoding() {
Log.i(TAG, "beforeLoding");
}
@Override
public void getUserInfoSucceed(User user) {
Log.i(TAG, "id:"+user.getId()+" realName:"+user.getRealName());
}
@Override
public void getUserInfoFailed(String msg) {
Log.i(TAG, "msg=" + msg);
}
@Override
public void afterLoading() {
Log.i(TAG, "afterLoading");
}
}
User
/**
* @創(chuàng)建 HaiJia
* @時間 2017/2/7 13:51
* @描述 UserBean
*/
public class User {
private int id;//用戶ID
private String realName;//用戶真實(shí)姓名
public String getRealName() {
return realName;
}
public void setRealName(String realName) {
this.realName = realName;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
IUserInfoShow
public interface IUserInfoShow {
void beforeLoding();
void getUserInfoSucceed(User user);
void getUserInfoFailed(String msg);
void afterLoading();
}
// MainActivity extends Activity implements IUserInfoShow
UserInfoPresenter
public class UserInfoPresenter {
private IGetUserInfo mIGetUserInfo;
private IUserInfoShow mUserInfoShow;
public UserInfoPresenter(IUserInfoShow mUserInfoShow, IGetUserInfo mIGetUserInfo) {
this.mUserInfoShow = mUserInfoShow;
this.mIGetUserInfo = mIGetUserInfo;
}
public void getUserInfo(int id){
mUserInfoShow.beforeLoding();
mIGetUserInfo.getUserInfo(id, new OnUserInfoListener() {
@Override
public void getUserInfoSuccess(User user) {
mUserInfoShow.getUserInfoSucceed(user);
mUserInfoShow.afterLoading();
}
@Override
public void getUserInfoFailure(String msg) {
mUserInfoShow.getUserInfoFailed(msg);
mUserInfoShow.afterLoading();
}
});
}
}
IGetUserInfo
/**
* @創(chuàng)建 HaiJia
* @時間 2017/2/7 14:00
* @描述 TODO
*/
public interface IGetUserInfo {
void getUserInfo(int id,OnUserInfoListener listener);
}
OnUserInfoListener
/**
* @創(chuàng)建 HaiJia
* @時間 2017/2/7 14:01
* @描述 TODO
*/
public interface OnUserInfoListener {
void getUserInfoSuccess(User user);
void getUserInfoFailure(String msg);
}
GetUserInfoImpl
/**
* @創(chuàng)建 HaiJia
* @時間 2017/2/7 14:03
* @描述 實(shí)現(xiàn)類
*/
public class GetUserInfoImpl implements IGetUserInfo {
@Override
public void getUserInfo(final int id, final OnUserInfoListener listener) {
// 模擬數(shù)據(jù)
new Thread(new Runnable() {
@Override
public void run() {
if (id == 123){
User user = new User();
user.setId(123);
user.setRealName("黃海佳");
listener.getUserInfoSuccess(user);
}else{
String msg = "用戶數(shù)據(jù)出錯,請回你的火星去";
listener.getUserInfoFailure(msg);
}
}
}).start();
}
}
三 . MVVM:Model-View-ViewModel
Paste_Image.png
MVVM是在原有領(lǐng)域Model的基礎(chǔ)上添加一個ViewModel,這個ViewModel除了正常的屬性意外,還包括一些供View顯示用的屬性。例如在經(jīng)典的MVP中,view有一個屬性ischeck,需要在presenter中設(shè)置view的ischeck值。但是在MVVM中的presenter也會有一個ischeck屬性來同步view的ischeck屬性,可能會用到observer模式同步ischeck的值。在MVVM中,presenter被改名為ViewModel,就演變成了你看到的MVVM。在支持雙向綁定的平臺,MVVM更受歡迎。例如:微軟的WPF和Silverlight。
1.MVVM優(yōu)點(diǎn)?
1.提高可維護(hù)性。
解決了MVP大量的手動View和Model同步的問題,提供雙向綁定機(jī)制。提高了代碼的可維護(hù)性。
2.簡化測試。
因?yàn)橥竭壿嬍墙挥葿inder做的,View跟著Model同時變更,所以只需要保證Model的正確性,View就正確。大大減少了對View同步更新的測試。
3.ViewModle易于單元測試。
2.使用場景?
適用于界面展示的數(shù)據(jù)較多的項(xiàng)目。
3.代碼示例
Paste_Image.png
在Module的build.gradle中添加下面代碼,注意的是保證Gradle插件版本不低于1.5.0-alpha1
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
...
dataBinding {
enabled true//添加這個
}
}
activity_main
name="user"
type="User" />
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{String.valueOf(user.id)}" />
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{user.realName}" />
MainActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setUser(new User(123,"黃海佳"));
}
}
就是這么簡單就搞定了MVVM的框架,但是這里面有很多細(xì)節(jié),下一篇文章在詳細(xì)介紹一下data binding框架。
參考
總結(jié)
以上是生活随笔為你收集整理的android mvc mvp 区别,谈谈Android框架 MVC、MVP、MVVM的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 如何打开s3db,[转载
- 下一篇: android opengl es 纹理