日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

mvvm模式和mvc的区别_Android 开发中的架构模式 -- MVC / MVP / MVVM

發布時間:2025/3/20 Android 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mvvm模式和mvc的区别_Android 开发中的架构模式 -- MVC / MVP / MVVM 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

預備知識

了解 Android 基本開發

看完本文可以達到什么程度

了解如何分析一個架構模式
掌握 MVC,MVP,MVVM 架構定義和實現

更多面試內容,面試專題,flutter視頻 全套,音視頻從0到高手開發。
關注GitHub:https://github.com/xiangjiana/Android-MS免費獲取面試PDF合集免費提供簡歷修改建議,獲取大廠面試PDF和視頻教程

文章概覽

一、什么是架構

關于架構的定義,其實在很多書籍和文章中都是不同的,很難做一個統一。這里列舉兩個定義:

在維基百科里是這樣定義的:

軟件架構是一個系統的草圖。軟件架構描述的對象是直接構成系統的抽象組件。各個組件之間的連接則明確和相對細致地描述組件之間的通訊。在實現階段,這些抽象組件被細化為實際的組件,比如具體某個類或者對象。

在 IEEE 軟件工程標準詞匯中是這樣定義的:

架構是以組件、組件之間的關系、組件與環境之間的關系為內容的某一系統的基本組織結構,以及指導上述內容設計與演化的原理。

在看過茫茫多的架構定義以后,我理解的架構是這樣的:

1.為了解決特定的問題而提出
2.按照特定的原則將系統整體進行模塊/組件/角色的劃分
3.建立模塊/組件/角色間的溝通機制

具體解釋一下,首先是要有特定的問題,沒有問題空談架構,仿佛是空中樓閣,沒有實用價值,而對應到不同的問題,會有不同的解決方式。
其次是模塊的劃分要根據特定的原則,沒有原則隨意劃分,也就無從去評估一個架構的好壞。最后就是模塊間的通信機制,讓系統成為一個整體.

最后,架構模式,其實更多的是一種思想,一種規則,往往一種架構模式可能會有不同的實現方式,而實現方式之間,只有合適與否,并沒有對錯之分。

二、如何分析一種架構模式

上面我們介紹了架構的定義,根據這個定義,我們在后面分析架構模式的時候,也會從這三方面進行。

2.1.架構解決了什么問題

知道了架構模式要解決的問題,我們才能針對性的去看,去想其解決方法是否得當,是否合適。

2.2.架構模式是如何劃分角色的

架構中最重要的就是角色 / 模塊的劃分,理解了架構模式中的角色劃分,才能更好的理解其結構。

2.3.角色間是如何通信的

角色間的通信也是重要的。相同的角色劃分,采用不同的通信方式,往往就構成了不同的架構模式。

角色間通信我們可以理解為數據的流向。在 Android 開發中,通信中的數據可以理解為兩種,一種是數據結構,也就是網絡請求,本地存儲等通信使用的 JavaBean,另一種是事件,也就是控件產生的動作,包括觸摸,點擊,滑動等等。我們在通信過程中,也主要關注這兩種數據。

三、常見的架構模式有哪些

對于我們 Android 開發者來說,常見的架構模式基本上就是 MVC,MVP,MVVM,這三種也是開發 GUI 應用程序常見的模式。

除此之外還有 分層模式,客戶端-服務器模式(CS模式),主從模式,管道過濾器模式,事件總線模式 等等。

這篇文章還是具體分析 MVC,MVP,MVVM 這三種架構模式。

四、不使用架構之前 App 是怎么開發的

我們在了解架構的定義以后,可能會想,為什么要用這些架構模式呢?在我們不了解這些模式之前,也是一樣的開發。類似設計模式,其實架構模式的目的不是為了讓應用軟件開發出來,而是讓結構更清晰,分工更明確,擴展更方便等等。

我們可以看看,在不使用架構模式之前我們是怎么開發的。
舉個簡單的栗子,我們界面上有 EditText,TextView,Button 三個控件,要實現的功能也比較簡單:

1.EditText 接受用戶輸入的內容
2.處理用戶輸入的數據
3.數據處理后輸出到 TextView 中
4.點擊 Button 清空用戶的輸入

界面如下:

我們看看不使用架構模式是怎么開發的,也就是我們一般常用的開發方式:

4.1. 首先在 xml 設計界面

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="10dp"tools:context=".MainActivity"><TextViewandroid:id="@+id/titleText"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Normal" /><EditTextandroid:id="@+id/edit"android:layout_width="match_parent"android:layout_height="50dp"android:textColor="@android:color/darker_gray" /><TextViewandroid:id="@+id/msgText"android:layout_width="wrap_content"android:layout_height="30dp"android:layout_marginTop="10dp"android:text="default msg"android:textColor="@android:color/darker_gray" /><TextViewandroid:id="@+id/clearText"android:layout_width="match_parent"android:layout_height="30dp"android:layout_marginTop="10dp"android:background="@color/colorPrimary"android:gravity="center"android:text="clear"android:textColor="@android:color/white" /></LinearLayout>

1.在 Activity / Fragment 中獲取 View,進行事件監聽
2.通過 View 事件獲取數據后進行處理
3.設置處理后的數據給 View

代碼如下:

class NormalFragment : Fragment() {companion object {fun newInstance(): Fragment {return NormalFragment()}}private val handler: Handler = Handler()override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {return inflater.inflate(R.layout.architecture, container, false)}override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)titleText.text = "NORMAL"edit.addTextChangedListener(object : TextWatcher {override fun afterTextChanged(s: Editable?) {handleData(s.toString())}override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}})clearText.setOnClickListener {edit.setText("")}}// 數據的處理,真實情況下可能是網絡請求,磁盤存取,大量計算邏輯等等private fun handleData(data: String) {if (TextUtils.isEmpty(data)) {msgText.text = "default msg"return}msgText.text = "handle data ..."handler.removeCallbacksAndMessages(null)// 延遲來模擬網絡或者磁盤操作handler.postDelayed({msgText.text = "handled data: $data"}, 3000)}}

默認開發方式的缺點:

我們來分析一下上面的代碼,一個明顯的特點就是處理邏輯都集中在了 Activity / Fragment 中,不管是對 View 的操作,還是對數據的處理。帶來的問題就是 Activity / Fragment 中邏輯臃腫,后續擴展牽一發而動全身。而且職責劃分不清晰,給后續維護也帶來了困難。

既然如此,我們看看使用架構模式改造后是什么樣子的。

五、MVC 架構

5.1 模式介紹

其實關于 MVC 架構,在不同的框架里,實現會有些差別,這也正說明了架構是一種思想。我們這里選用一種比較主流的實現。

5.1.1. 解決什么問題

我們可以看到,上面不使用架構進行開發,帶來的問題是 Activity / Fragment 邏輯臃腫,不利于擴展。所以 MVC 就要解決的問題就是:控制邏輯,數據處理邏輯和界面交互耦合。

這里先插一個題外話,其實我們作為程序員,寫代碼不僅要實現需求,還要讓代碼易讀,易擴展。這一點,往往也能體現功力,并不是說使用了各種奇技淫巧才是大神。

不知道大家是否有接觸過 Java Swing 桌面應用開發,在 Java Swing 中,界面 / 控件的設置,也是用 Java 代碼來實現的,如果不采用架構,最后的結果就是控制邏輯,數據處理以及頁面展示的代碼都集中在一個類中,讀者朋友們可以想象一下,這樣的代碼簡直是難以維護

5.1.2. 如何劃分角色

為了解決上面的問題,MVC 架構里,將邏輯,數據,界面的處理劃分為三個部分,模型(Model)-視圖(View)-控制器(Controller)。各個部分的功能如下:

  • Model 模型,負責數據的加載和存儲。
  • View 視圖,負責界面的展示。
  • Controller 控制器,負責邏輯控制。

5.1.3. 如何通信(數據的流向)

我們再看看三者之間是怎么通信的。

在介紹通信之前,我們先解釋一下通信中的數據是什么。其實在 Android 開發中,通信數據可以理解為兩種,一種是數據結構,也就是網絡請求,本地存儲等通信使用的 JavaBean,另一種是事件,也就是控件產生的動作,包括觸摸,點擊,滑動等等。我們在通信過程中,也主要關注這兩種數據。

在 MVC 架構中,View 產生事件,通知到 Controller,Controller 中進行一系列邏輯處理,之后通知給 Model 去更新數據,Model 更新數據后,再將數據結構通知給 View 去更新界面。

這就是一個完整 MVC 的數據流向

5.2 在 Android 中的具體實現

理解了 MVC 模式,我們看看其具體實現。

其實在 Android 開發中,其本身默認可以理解為 MVC 結構,把 View 放在 xml中與 Java 代碼解耦,然后 Activity / Fragment 充當 Controller 進行邏輯控制,但是 Android 本身并沒有對 Model進行劃分,所以往往我們會讓 Activity / Fragment 充當 Model 和 Controller 兩個角色。而且往往 xml 中的 View 操作也是在 Activity / Fragment 中,導致有時候 Activity / Fragment 也會充當一些 View 的角色。

所以我們在具體實現過程中,要把職責劃分清楚,這里我們讓 Fragment 充當 View 的角色,把 Model 和 Controller 的邏輯劃分清楚。

我們先定義三個接口如下:

// 數據模型接口,定義了數據模型的操作interface IModel {fun setView(view: IView)// 數據模型處理輸入的數據fun handleData(data: String)// 清空數據fun clearData()}// 視圖接口,定義視圖的操作interface IView {fun setController(controller: IController)// 數據處理中狀態fun dataHanding()// 數據處理完成,更新界面fun onDataHandled(data: String)}// 控制器接口,定義控制器的邏輯interface IController {fun setModel(model: IModel)// EditText 數據變化,通知控制器fun onDataChanged(data: String)// 清空按鈕點擊事件fun clearData()}

上面三個接口分別定義了 Model,View,Controller的操作。有一點注意的是,根據 MVC 的通信流程,View 需要持有 Controller,Controller 需要持有 Model,Model 需要持有 View,所以需要暴露相應的接口。

下面我們看看具體的實現:

  • Model 的實現

Model 中對數據的處理是添加了 "handled data: " 前綴,并增加了 3 秒的延遲

class HandleModel : IModel {private var view: IView? = nullprivate val handler: Handler = Handler(Looper.getMainLooper())override fun setView(view: IView) {this.view = view}// 接受到數據后,進行處理,這里設置了 3 秒的延遲,模擬網絡請求處理數據的操作override fun handleData(data: String) {if (TextUtils.isEmpty(data)) {return}view?.dataHanding()handler.removeCallbacksAndMessages(null)// 延遲來模擬網絡或者磁盤操作handler.postDelayed({// 數據處理完成,通知 View 更新界面view?.onDataHandled("handled data: $data")}, 3000)}// 接收到清空數據的事件,直接清空數據override fun clearData() {handler.removeCallbacksAndMessages(null)// 數據清空后,通知 View 更新界面view?.onDataHandled("")}}
  • Controller 的實現

Controller 的實現比較簡單,將操作直接轉發給 Model,實際上,對于復雜的業務場景,這里要處理很多業務邏輯。

class HandleController : IController {private var model: IModel? = nulloverride fun onDataChanged(data: String) {model?.handleData(data)}override fun clearData() {model?.clearData()}override fun setModel(model: IModel) {}}
  • View 的實現

這里 Fragment 充當了 View 的角色,主要負責將 View 的事件傳遞給 Controller,以及接受到 Model 的數據進行界面更新。

class MVCFragment : Fragment(), IView {companion object {fun newInstance(): Fragment {return MVCFragment()}}private val model: IModel = HandleModel()private var controller: IController = HandleController()override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {return inflater.inflate(R.layout.architecture, container, false)}override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)setController(controller)model.setView(this)titleText.text = "MVC"edit.addTextChangedListener(object : TextWatcher {override fun afterTextChanged(s: Editable?) {// 通知 Controller 輸入的數據產生變化controller?.onDataChanged(s.toString())}override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}})clearText.setOnClickListener {// 通知 Controller 清空數據事件controller?.clearData()}}// Model 數據變化,進行界面更新override fun onDataHandled(data: String) {if (TextUtils.isEmpty(data)) {edit.setText("")msgText.text = "default msg"} else {msgText.text = data}}// Model 數據變化,進行界面更新override fun dataHanding() {msgText.text = "handle data ..."}override fun setController(controller: IController) {this.controller = controller}}

這樣我們就實現了一個簡單的 MVC 結構。

5.3 MVC 架構模式的優缺點

優點:

  • 結構清晰,職責劃分清晰
  • 降低耦合
  • 有利于組件重用

缺點:

  • 其實我們上述的示例,已經是經過優化的 MVC 結構了,一般來說,Activity / Fragment 會承擔 View 和 Controller 兩個角色,就會導致 Activity / Fragment 中代碼較多
  • Model 直接操作 View,View 的修改會導致 Controller 和 Model 都進行改動
  • 增加了代碼結構的復雜性

六、MVP 架構

6.1 模式介紹

6.1.1. 解決什么問題

MVP 要解決的問題和 MVC 大同小異:控制邏輯,數據處理邏輯和界面交互耦合,同時能將 MVC中的 View 和 Model 解耦。

6.1.2. 如何劃分角色

MVP 架構里,將邏輯,數據,界面的處理劃分為三個部分,模型(Model)-視圖(View)-控制器(Presenter)。各個部分的功能如下:

  • Model 模型,負責數據的加載和存儲。
  • View 視圖,負責界面的展示。
  • Presenter 控制器,負責邏輯控制

6.1.3. 如何通信(數據的流向)

我們可以看到,MVP 中的各個角色劃分,和 MVC 基本上相似,那么區別在哪里呢?區別就在角色的通信上。

MVP 和 MVC 最大的不同,就是 View 和 Model 不相互持有,都通過 Presenter 做中轉。View 產生事件,通知給 Presenter,Presenter中進行邏輯處理后,通知 Model 更新數據,Model 更新數據后,通知數據結構給 Presenter,Presenter 再通知 View 更新界面。

這就是一個完整 MVP 的數據流向。

6.2 在 Android 中的實現

理解了 MVP 之后,我們看一下其具體實現。

首先我們定義三個接口:

// 模型接口,定義了數據模型的操作interface IModel {fun setPresenter(presenter: IPresenter)// 梳理數據fun handleData(data: String)// 清除數據fun clearData()}// 視圖接口,定義了視圖的操作interface IView {fun setPresenter(presenter: IPresenter)// 數據處理中視圖fun loading()// 數據展示fun showData(data: String)}// 控制器,定義了邏輯操作interface IPresenter {fun setView(view: IView)fun setModel(model: IModel)// Model 處理完成數據通知 Presenterfun dataHandled(data: String)// Model 清除數據后通知 Presenterfun dataCleared()// View 中 EditText 文字變化后通知 Presenterfun onTextChanged(text: String)// View 中 Button 點擊事件通知 Presenterfun onClearBtnClicked()}

上面定義了 View,Model,Presenter 三個接口,其中 View 和 Model 會持有 Presenter,Presenter持有 View和 Model。

接著看下接口的實現:

  • Model 的實現
class HandleModel : IModel {private var presenter: IPresenter? = nullprivate var handler = Handler(Looper.getMainLooper())override fun handleData(data: String) {if (TextUtils.isEmpty(data)) {return}handler.removeCallbacksAndMessages(null)// 延遲來模擬網絡或者磁盤操作handler.postDelayed({// 數據處理完成,通知 Presenterpresenter?.dataHandled("handled data: $data")}, 3000)}override fun clearData() {handler.removeCallbacksAndMessages(null)// 數據清理完成,通知 Presenterpresenter?.dataCleared()}override fun setPresenter(presenter: IPresenter) {this.presenter = presenter}}

Model 的實現和前面 MVC 中的實現基本一致,不過在 MVC 中 Model 直接操作 View 進行視圖展示,而在 MVP 里,要通知 Presenter 去中轉。

  • View 的實現

這里依舊是 Fragment 充當了 View 的角色,主要負責將 View 的事件傳遞給 Presenter,以及接受到 Presenter 的數據進行界面更新。

class MVPFragment : Fragment(), IView {companion object {fun newInstance(): Fragment {val presenter = Presenter()val fragment = MVPFragment()val model = HandleModel()fragment.setPresenter(presenter)model.setPresenter(presenter)presenter.setModel(model)presenter.setView(fragment)return fragment}}var mpresenter: IPresenter? = nulloverride fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {return inflater.inflate(R.layout.architecture, container, false)}override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)titleText.text = "MVP"edit.addTextChangedListener(object : TextWatcher {override fun afterTextChanged(s: Editable?) {// 傳遞 文字修改 事件給 Presentermpresenter?.onTextChanged(s.toString())}override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}})clearText.setOnClickListener {// 傳遞按鈕點擊事件給 Presentermpresenter?.onClearBtnClicked()}}override fun setPresenter(presenter: IPresenter) {this.mpresenter = presenter}// 展示數據處理中的視圖override fun loading() {msgText.text = "handling data ..."}// 展示處理后的數據override fun showData(data: String) {msgText.text = data}}
  • Presenter 的實現

這里 Presenter 的實現比較簡單,沒有太多的業務邏輯,實際應用中,這里會進行業務邏輯的處理。

class Presenter : IPresenter {private var model: IModel? = nullprivate var view: IView? = nulloverride fun setModel(model: IModel) {this.model = model}override fun setView(view: IView) {this.view = view}override fun dataHandled(data: String) {view?.showData(data)}override fun dataCleared() {view?.showData("")}override fun onTextChanged(text: String) {view?.loading()model?.handleData(text)}override fun onClearBtnClicked() {model?.clearData()}}

6.3 MVP 架構模式的優缺點

優點:

  • 結構清晰,職責劃分清晰
  • 模塊間充分解耦
  • 有利于組件的重用

缺點:

  • 會引入大量的接口,導致項目文件數量激增
  • 增大代碼結構復雜性

七、MVVM 架構

7.1 模式介紹

7.1.1. 解決什么問題

MVVM 要解決的問題和 MVC,MVP 大同小異:控制邏輯,數據處理邏輯和界面交互耦合,并且同時能將 MVC 中的 View 和 Model 解耦,還可以把 MVP 中 Presenter 和 View 也解耦。

7.1.2. 如何劃分角色

MVVM 架構里,將邏輯,數據,界面的處理劃分為三個部分,模型(Model)-視圖(View)-邏輯(ViewModel)。各個部分的功能如下:

  • Model 模型,負責數據的加載和存儲。
  • View 視圖,負責界面的展示。
  • ViewModel 控制器,負責邏輯控制。

7.1.3. 如何通信(數據的流向)

我們可以看到,MVP 中的各個角色劃分,和 MVC,MVP 基本上相似,區別也是在于角色的通信上。

我們上面說到,在 MVP 中,就是 View 和 Model 不相互持有,都通過 Presenter 做中轉。這樣可以使 View 和 Model 解耦。

而在 MVVM 中,解耦做的更徹底,ViewModel 也不會持有 View。其中 ViewModel 中的改動,會自動反饋給 View 進行界面更新,而 View中的事件,也會自動反饋給 ViewModel。

要達到這個效果,當然要使用一些工具輔助,比較常用的就是 databinding。

在 MVVM 中,數據的流向是這樣的:

View 產生事件,自動通知給 ViewMode,ViewModel 中進行邏輯處理后,通知 Model 更新數據,Model 更新數據后,通知數據結構給 ViewModel,ViewModel 自動通知 View 更新界面。

這就是一個完整 MVVM 的數據流向。

7.2 在 Android 中的實現

MVVM 的實現會復雜一點,我們先看下接口的定義:

// ViewModel 接口,定義了邏輯操作interface IViewModel {fun setModel(model: IModel)fun handleText(text: String?)fun clearData()fun dataHandled(data: String?)fun dataCleared()}// 模型接口,定義了數據操作interface IModel {fun setViewModel(viewModel: IViewModel)fun handleData(data: String?)fun clearData()}

MVVM 中的接口只定義了 ViewModel 和 Model,沒有 View 接口,是因為 View 是通過 databind 和 ViewModel 的。

我們再看看具體實現:

  • Model 實現Model 的實現和上面基本一致,就是對數據的處理,處理完成后通知 ViewModel。
class HandleModel : IModel {private var viewModel: IViewModel? = nullprivate var handler = Handler(Looper.getMainLooper())override fun handleData(data: String?) {if (TextUtils.isEmpty(data)) {return}handler.removeCallbacksAndMessages(null)// 延遲來模擬網絡或者磁盤操作handler.postDelayed({// 數據處理完成通知 ViewModelviewModel?.dataHandled("handled data: $data")}, 3000)}override fun clearData() {handler.removeCallbacksAndMessages(null)// 數據清理完成通知 ViewModelviewModel?.dataCleared()}override fun setViewModel(viewModel: IViewModel) {this.viewModel = viewModel}}
  • ViewModel 實現

ViewModel 的實現要有些不同,我們采用 databind 進行 ViewModel 和 View 的綁定。

其中會定義兩個變量,inputText 是和 EditText 雙向綁定的數據,handledText 是和 TextView 雙向綁定的數據。

當 EditText 中輸入的數據有變化,會通知到 inputText 注冊的監聽器中,而 handledText 值的改變,會自動顯示到界面上。

class ViewModel : IViewModel {private var model: IModel? = null// View 綁定的數據,inputText 和 handledText 更新后會自動通知 View 更新界面var inputText: MutableLiveData<String> = MutableLiveData()var handledText: MutableLiveData<String> = MutableLiveData()init {// 注冊數據監聽,數據改變后通知 Model 去處理數據inputText.observeForever {handleText(it)}handledText.value = "default msg"}override fun handleText(text: String?) {if (TextUtils.isEmpty(text)) {handledText.value = "default msg"return}handledText.value = "handle data ..."model?.handleData(text)}// 清空按鈕的點擊事件綁定override fun clearData() {model?.clearData()}override fun setModel(model: IModel) {this.model = modelmodel.setViewModel(this)}// Model 數據處理完成,設置 handledText 的值,自動更新到界面override fun dataHandled(data: String?) {handledText.value = data}// Model 數據處理完成,設置 inputText 的值,自動更新到界面override fun dataCleared() {inputText.value = ""}}
  • View 實現
    看一下 View 中的數據綁定。
class MVVMFragment : Fragment() {companion object {fun newInstance(): Fragment {return MVVMFragment()}}override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {// 使用 databind 進行數據綁定var binding: ArchitectureBindingBinding = DataBindingUtil.inflate(inflater, R.layout.architecture_binding, container, false)binding.lifecycleOwner = thisval viewModel = ViewModel()viewModel.setModel(HandleModel())binding.viewmodel = viewModelreturn binding.root}} <?xml version="1.0" encoding="utf-8"?><layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"><!--定義 View 中綁定的數據--><data><variablename="viewmodel"type="com.zy.architecture.mvvm.ViewModel" /></data><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="10dp"tools:context=".MainActivity"><TextViewandroid:id="@+id/titleText"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="MVVM" /><!--雙向綁定 inputText 到 EditText--><EditTextandroid:id="@+id/edit"android:layout_width="match_parent"android:layout_height="50dp"android:text="@={viewmodel.inputText}" android:textColor="@android:color/darker_gray" /><!--綁定 handledText 到 TextView--><TextViewandroid:id="@+id/msgText"android:layout_width="wrap_content"android:layout_height="30dp"android:layout_marginTop="10dp"android:text="@{viewmodel.handledText}"android:textColor="@android:color/darker_gray" /><!--綁定清空數據的點擊事件 到 TextView--><TextViewandroid:id="@+id/clearText"android:layout_width="match_parent"android:layout_height="30dp"android:layout_marginTop="10dp"android:background="@color/colorPrimary"android:gravity="center"android:onClick="@{() -> viewmodel.clearData()}"android:text="clear"android:textColor="@android:color/white" /></LinearLayout></layout>

通過上面的實現,當 EditText 中文字變化后,會自動修改 inputText 的值,觸發 inputText 監聽器,此時 ViewModel 將消息傳遞給 Model 進行處理,Model 數據處理完成后,通知 ViewModel 更新 handledText 的值,自動更新到界面上。

點擊清空按鈕時,自動調用綁定的點擊函數,通知 ViewModel 清空事件,ViewModel 將消息傳遞給 Model 進行數據清空,Model 數據處理完成后,通知 ViewModel 進行界面更新。

7.3 MVVM 架構模式的優缺點

優點:

  • 結構清晰,職責劃分清晰
  • 模塊間充分解耦
  • 在 MVP 的基礎上,MVVM 把 View 和 ViewModel 也進行了解耦

缺點:

  • Debug 困難,由于 View 和 ViewModel 解耦,導致 Debug 時難以一眼看出 View 的事件傳遞
  • 代碼復雜性增大

八、架構模式的運用

上面的文章中,我們介紹了 MVC,MVP,MVVM 三種架構模式,以及其簡單的實現。這里我們再回過頭思考一下,什么時候該使用架構模式呢?

架構模式可以使代碼模塊清晰,職責分工明確,容易擴展,帶來的副作用就是會引入大量的接口,導致代碼文件數量激增。

我們在最開始說過,架構模式是用來解決特定的問題的,如果特定的問題在目前階段不是問題,或者不是主要問題,那么我們可以先不考慮使用架構模式。比如一個功能非常簡單,代碼量少,而后續又沒有擴展的需求,那我們直接使用傳統方式進行開發,快速且清晰,完全沒有必要為了架構而架構。

對于在開始沒有考慮架構模式的代碼,后續慢慢去重構,也是一個好的選擇。

總結來說就是:架構雖好,可不要貪杯哦~

總結

關于我:

更多面試內容,面試專題,flutter視頻 全套,音視頻從0到高手開發。
關注GitHub:https://github.com/xiangjiana/Android-MS免費獲取面試PDF合集免費提供簡歷修改建議,獲取大廠面試PDF

https://u.wechat.com/ENywrVttLJsE4P0PTa0cnFs (二維碼自動識別)

總結

以上是生活随笔為你收集整理的mvvm模式和mvc的区别_Android 开发中的架构模式 -- MVC / MVP / MVVM的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。