MVVM(Model-View-ViewModel)
是一種基于數(shù)據(jù)綁定的架構(gòu)模式,用于設(shè)計(jì)和組織應(yīng)用程序的代碼結(jié)構(gòu)。它將應(yīng)用程序分為三個(gè)主要部分:Model(模型)、View(視圖)和ViewModel(視圖模型)。
- Model(模型):負(fù)責(zé)處理數(shù)據(jù)和業(yè)務(wù)邏輯。它可以是從網(wǎng)絡(luò)獲取的數(shù)據(jù)、數(shù)據(jù)庫(kù)中的數(shù)據(jù)或其他數(shù)據(jù)源。Model層通常是獨(dú)立于界面的,可以在多個(gè)界面之間共享。
- View(視圖):負(fù)責(zé)展示數(shù)據(jù)和與用戶進(jìn)行交互。它可以是Activity、Fragment、View等。View層主要負(fù)責(zé)UI的展示和用戶輸入的響應(yīng)。
- ViewModel(視圖模型):連接View和Model,作為View和Model之間的橋梁。它負(fù)責(zé)從Model中獲取數(shù)據(jù),并將數(shù)據(jù)轉(zhuǎn)換為View層可以直接使用的形式。ViewModel還負(fù)責(zé)監(jiān)聽(tīng)Model的數(shù)據(jù)變化,并通知View進(jìn)行更新。ViewModel通常是與View一一對(duì)應(yīng)的,每個(gè)View都有一個(gè)對(duì)應(yīng)的ViewModel。
MVVM的特點(diǎn)和優(yōu)勢(shì)
- 解耦合:MVVM通過(guò)將View和Model解耦合,使得它們可以獨(dú)立開(kāi)發(fā)和測(cè)試。ViewModel作為中間層,將數(shù)據(jù)從Model傳遞給View,避免了直接在View中處理業(yè)務(wù)邏輯的情況。
- 可維護(hù)性:MVVM的分層結(jié)構(gòu)使得代碼更易于維護(hù)。View只負(fù)責(zé)展示數(shù)據(jù)和用戶交互,ViewModel負(fù)責(zé)處理業(yè)務(wù)邏輯和數(shù)據(jù)轉(zhuǎn)換,Model負(fù)責(zé)數(shù)據(jù)的獲取和存儲(chǔ)。這種分離使得代碼更加清晰和可讀,也方便進(jìn)行單元測(cè)試。
- 數(shù)據(jù)驅(qū)動(dòng)UI:MVVM采用數(shù)據(jù)綁定的方式,將Model的數(shù)據(jù)與View進(jìn)行綁定。當(dāng)Model的數(shù)據(jù)發(fā)生變化時(shí),ViewModel會(huì)自動(dòng)更新View的顯示,無(wú)需手動(dòng)更新UI。這種方式可以減少手動(dòng)更新UI的代碼量,提高開(kāi)發(fā)效率。
- 可測(cè)試性:由于MVVM的分層結(jié)構(gòu)和數(shù)據(jù)驅(qū)動(dòng)UI的特點(diǎn),可以更容易地進(jìn)行單元測(cè)試。ViewModel中的業(yè)務(wù)邏輯可以獨(dú)立于View進(jìn)行測(cè)試,而不需要依賴(lài)于Android系統(tǒng)或UI組件。
常見(jiàn)架構(gòu)模式(MVC和MVP)區(qū)別
- MVC(Model-View-Controller):MVC模式中,Controller負(fù)責(zé)處理用戶輸入和業(yè)務(wù)邏輯,Model負(fù)責(zé)數(shù)據(jù)和業(yè)務(wù)邏輯,View負(fù)責(zé)展示數(shù)據(jù)。與MVC相比,MVVM將Controller分離為ViewModel,將數(shù)據(jù)綁定的方式集成進(jìn)來(lái),使得代碼更加簡(jiǎn)潔和清晰。
- MVP(Model-View-Presenter):MVP模式中,Presenter負(fù)責(zé)處理用戶輸入和業(yè)務(wù)邏輯,Model負(fù)責(zé)數(shù)據(jù)和業(yè)務(wù)邏輯,View負(fù)責(zé)展示數(shù)據(jù)。與MVP相比,MVVM將Presenter分離為ViewModel
MVVM三個(gè)核心組件
在MVVM模式中,有三個(gè)核心組件:Model(模型)、View(視圖)和ViewModel(視圖模型)。它們各自具有不同的職責(zé)和作用,并通過(guò)數(shù)據(jù)綁定機(jī)制實(shí)現(xiàn)彼此之間的關(guān)系和交互。
Model(模型):
- 職責(zé):負(fù)責(zé)處理數(shù)據(jù)和業(yè)務(wù)邏輯。它可以是從網(wǎng)絡(luò)獲取的數(shù)據(jù)、數(shù)據(jù)庫(kù)中的數(shù)據(jù)或其他數(shù)據(jù)源。Model層通常是獨(dú)立于界面的,可以在多個(gè)界面之間共享。 - 作用:提供數(shù)據(jù)和處理數(shù)據(jù)的方法,封裝業(yè)務(wù)邏輯。 - 示例代碼:
java public class User { private String name; private int age; // getter and setter methods // 數(shù)據(jù)獲取的方法 public LiveData getUser() { // 從網(wǎng)絡(luò)或數(shù)據(jù)庫(kù)獲取用戶數(shù)據(jù) return userRepository.getUser(); } // 數(shù)據(jù)更新的方法 public void updateUser(User user) { // 更新用戶數(shù)據(jù) userRepository.updateUser(user); } // ... }
View(視圖):
- 職責(zé):負(fù)責(zé)展示數(shù)據(jù)和與用戶進(jìn)行交互。它可以是Activity、Fragment、View等。View層主要負(fù)責(zé)UI的展示和用戶輸入的響應(yīng)。 - 作用:將ViewModel中的數(shù)據(jù)展示給用戶,并將用戶的輸入傳遞給ViewModel。 - 示例代碼:
java public class MainActivity extends AppCompatActivity { private UserViewModel userViewModel; private TextView nameTextView; private TextView ageTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); nameTextView = findViewById(R.id.nameTextView); ageTextView = findViewById(R.id.ageTextView); userViewModel = new ViewModelProvider(this).get(UserViewModel.class); userViewModel.getUser().observe(this, user -> { // 更新UI顯示 nameTextView.setText(user.getName()); ageTextView.setText(String.valueOf(user.getAge())); }); } // 處理用戶輸入的方法 public void onUpdateUserClick(View view) { // 從UI獲取用戶輸入 String name = nameEditText.getText().toString(); int age = Integer.parseInt(ageEditText.getText().toString()); // 更新ViewModel中的數(shù)據(jù) User user = new User(name, age); userViewModel.updateUser(user); } // ... }
ViewModel(視圖模型):
- 職責(zé):連接View和Model,作為View和Model之間的橋梁。它負(fù)責(zé)從Model中獲取數(shù)據(jù),并將數(shù)據(jù)轉(zhuǎn)換為View層可以直接使用的形式。ViewModel還負(fù)責(zé)監(jiān)聽(tīng)Model的數(shù)據(jù)變化,并通知View進(jìn)行更新。ViewModel通常是與View一一對(duì)應(yīng)的,每個(gè)View都有一個(gè)對(duì)應(yīng)的ViewModel。 - 作用:處理View層的數(shù)據(jù)展示和用戶交互,并與Model層進(jìn)行交互。 - 示例代碼:
java
public class UserViewModel extends ViewModel {
private User user;
private UserRepository userRepository;
?
? public UserViewModel() {
? userRepository = new UserRepository();
? user = new User();
? }
?
? // 獲取數(shù)據(jù)的方法 public LiveData<User> getUser() {
? return user.getUser();
? }
?
? // 更新數(shù)據(jù)的方法
? public void updateUser(User user
?
) {
user.updateUser(user);
}
?
// ...
}
ViewModel通過(guò)數(shù)據(jù)綁定機(jī)制將Model的數(shù)據(jù)與View進(jìn)行綁定,實(shí)現(xiàn)數(shù)據(jù)的自動(dòng)更新。當(dāng)Model的數(shù)據(jù)發(fā)生變化時(shí),ViewModel會(huì)自動(dòng)通知View進(jìn)行更新。這種數(shù)據(jù)綁定的方式減少了手動(dòng)更新UI的代碼量,提高了開(kāi)發(fā)效率。
下面是一個(gè)示意圖,說(shuō)明了MVVM模式中Model、View和ViewModel之間的關(guān)系和交互方式:
+-------------+
| Model |
+-------------+
|
|
v +-------------+
| ViewModel |
+-------------+
|
|
v
+-------------+
| View |
+-------------+
在這個(gè)示意圖中,ViewModel通過(guò)數(shù)據(jù)綁定機(jī)制將Model的數(shù)據(jù)綁定到View上,當(dāng)Model的數(shù)據(jù)發(fā)生變化時(shí),ViewModel會(huì)自動(dòng)通知View進(jìn)行更新,從而實(shí)現(xiàn)UI的自動(dòng)刷新。用戶的輸入通過(guò)View傳遞給ViewModel,ViewModel再將數(shù)據(jù)傳遞給Model進(jìn)行處理。
通過(guò)MVVM模式,Model、View和ViewModel之間的分離和解耦合,使得代碼更易于維護(hù)和測(cè)試。ViewModel作為中間層,負(fù)責(zé)處理業(yè)務(wù)邏輯和數(shù)據(jù)轉(zhuǎn)換,使得View層只關(guān)注UI的展示和用戶交互,而不關(guān)心具體的業(yè)務(wù)邏輯和數(shù)據(jù)處理。這種分層結(jié)構(gòu)和數(shù)據(jù)綁定的方式使得代碼更加清晰、可讀性更強(qiáng),并提高了開(kāi)發(fā)效率和代碼質(zhì)量。
MVVM數(shù)據(jù)綁定機(jī)制
在MVVM模式中,數(shù)據(jù)綁定是實(shí)現(xiàn)View和ViewModel之間數(shù)據(jù)同步的關(guān)鍵機(jī)制。它允許將View中的UI元素(如TextView、EditText)與ViewModel中的數(shù)據(jù)屬性進(jìn)行綁定,當(dāng)數(shù)據(jù)發(fā)生變化時(shí),自動(dòng)更新UI,同時(shí)用戶的輸入也會(huì)自動(dòng)同步到ViewModel中。
數(shù)據(jù)綁定的原理是通過(guò)觀察者模式和反射機(jī)制實(shí)現(xiàn)的。當(dāng)ViewModel中的數(shù)據(jù)發(fā)生變化時(shí),會(huì)觸發(fā)相應(yīng)的通知,通知綁定的View進(jìn)行更新。而當(dāng)用戶在View中輸入數(shù)據(jù)時(shí),數(shù)據(jù)綁定也會(huì)將輸入的數(shù)據(jù)自動(dòng)同步到ViewModel中。這種雙向的數(shù)據(jù)同步機(jī)制,使得View和ViewModel之間實(shí)現(xiàn)了數(shù)據(jù)的實(shí)時(shí)同步。
在Android中,可以使用數(shù)據(jù)綁定庫(kù)(如Data Binding)來(lái)實(shí)現(xiàn)MVVM模式中的數(shù)據(jù)綁定。Data Binding庫(kù)提供了一組注解和工具類(lèi),可以簡(jiǎn)化數(shù)據(jù)綁定的實(shí)現(xiàn)過(guò)程。
以下是在Android中使用Data Binding庫(kù)實(shí)現(xiàn)MVVM模式中的數(shù)據(jù)綁定的步驟:
- 配置Data Binding庫(kù):在項(xiàng)目的build.gradle文件中,添加Data Binding的插件和依賴(lài)項(xiàng)。
// ...
dataBinding {
enabled = true
}
}
?
dependencies {
// ...
implementation 'androidx.databinding:databinding-runtime:7.0.2'
}
- 創(chuàng)建布局文件:在布局文件中,使用標(biāo)簽包裹布局,并使用標(biāo)簽定義綁定的變量和表達(dá)式。
<data>
<variable name="user"
type="com.example.mvvm.User" />
</data>
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.name}" />
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf(user.age)}" />
</LinearLayout>
</layout>
- 創(chuàng)建ViewModel類(lèi):創(chuàng)建一個(gè)與View對(duì)應(yīng)的ViewModel類(lèi),并在其中定義與布局文件中綁定的變量。
java
public class UserViewModel extends BaseObservable {
private String name;
private int age;
?
// getter and setter methods
?
@Bindable public String getName() {
return name;
}
?
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
?
@Bindable public int getAge() {
return age;
}
?
public void setAge(int age) {
this.age = age;
notifyPropertyChanged(BR.age);
}
}
- 綁定數(shù)據(jù):在Activity或Fragment中,使用DataBindingUtil類(lèi)將布局文件與ViewModel進(jìn)行綁定,并設(shè)置ViewModel的數(shù)據(jù)。
public class MainActivity extends AppCompatActivity {
private UserViewModel userViewModel;
?
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
?
// 創(chuàng)建ViewModel實(shí)例
userViewModel = new UserViewModel();
userViewModel.setName("John");
userViewModel.setAge(25);
?
// 綁定ViewModel和
?
布局文件 ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setUser(userViewModel);
}
}
通過(guò)以上步驟,我們將布局文件和ViewModel進(jìn)行了綁定,同時(shí)設(shè)置了ViewModel的數(shù)據(jù)。當(dāng)ViewModel中的數(shù)據(jù)發(fā)生變化時(shí),布局文件中相應(yīng)的UI元素會(huì)自動(dòng)更新。同時(shí),當(dāng)用戶在UI元素中輸入數(shù)據(jù)時(shí),Data Binding庫(kù)也會(huì)自動(dòng)將輸入的數(shù)據(jù)同步到ViewModel中。
使用數(shù)據(jù)綁定的好處是能夠簡(jiǎn)化代碼,減少手動(dòng)更新UI的代碼量,提高開(kāi)發(fā)效率。它還能夠降低代碼的耦合性,使得UI和數(shù)據(jù)邏輯的修改更加靈活和獨(dú)立。另外,數(shù)據(jù)綁定還能夠提高代碼的可讀性和可維護(hù)性,使得代碼更易于理解和調(diào)試。《更多內(nèi)容可查了主頁(yè)信息,可捕獲進(jìn)階知識(shí)》
MVVM架構(gòu)模式發(fā)展趨勢(shì)
MVVM模式在Android開(kāi)發(fā)中已經(jīng)得到廣泛應(yīng)用,并且在未來(lái)仍然有著較大的發(fā)展?jié)摿?。以下是一些未?lái)發(fā)展趨勢(shì):
Jetpack Compose:
Jetpack Compose是Google推出的一種全新的UI框架,它采用了聲明式UI的方式,與MVVM模式非常契合。Jetpack Compose能夠簡(jiǎn)化UI開(kāi)發(fā)流程,提供更加靈活和響應(yīng)式的UI編程方式。
數(shù)據(jù)驅(qū)動(dòng)UI:
未來(lái),數(shù)據(jù)驅(qū)動(dòng)UI的概念將會(huì)更加普及和強(qiáng)調(diào)。MVVM模式的數(shù)據(jù)綁定和觀察者模式是實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)UI的重要手段,未來(lái)可能會(huì)有更多的框架和工具出現(xiàn),進(jìn)一步簡(jiǎn)化數(shù)據(jù)和UI的綁定過(guò)程。
更強(qiáng)大的ViewModel組件:
Android Jetpack中的ViewModel組件已經(jīng)為開(kāi)發(fā)者提供了很多便利,但未來(lái)可能會(huì)有更多功能和特性被添加進(jìn)來(lái),以進(jìn)一步提高ViewModel的靈活性和可擴(kuò)展性。
跨平臺(tái)開(kāi)發(fā):文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-663673.html
MVVM模式的解耦特性使得代碼更具可移植性,未來(lái)可能會(huì)有更多的跨平臺(tái)開(kāi)發(fā)框架和工具出現(xiàn),使得開(kāi)發(fā)者能夠更輕松地在不同平臺(tái)上使用MVVM模式進(jìn)行開(kāi)發(fā)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-663673.html
到了這里,關(guān)于Android MVVM架構(gòu)模式,詳詳詳細(xì)學(xué)習(xí)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!