Architecture pattern in Android Development — MVC / MVP / MVVM

Time:2020-5-31

Preparatory knowledge

Learn about Android basic development
How far can I reach after reading this article

Learn how to analyze an architecture pattern
Master MVC, MVP, MVVM architecture definition and Implementation

More interview content, interview topics, full set of flitter video, audio and video from 0 to expert development.
followGitHub:https://github.com/xiangjiana/Android-MS
Free access to interview PDF collection
Free resume modification suggestions, PDF and video tutorials for large factory interview

Article overview

Architecture pattern in Android Development -- MVC / MVP / MVVM

1、 What is architecture

In fact, the definition of architecture is different in many books and articles, so it is difficult to make a unified. Here are two definitions:

That’s how it’s defined in Wikipedia

Software architecture is a sketch of a system. The object described by software architecture is the abstract component that directly constitutes the system. The connection between components describes the communication between components in a clear and relatively detailed way. In the implementation phase, these abstract components are refined into actual components, such as a specific class or object.

In IEEE software engineering standard vocabulary, it is defined as follows:

Architecture is the basic organizational structure of a system with the content of components, the relationship between components, and the relationship between components and environment, as well as the principle guiding the design and evolution of the above content.

After reading the vast number of architecture definitions, I understand the architecture as follows:

1. To solve specific problems
2. Divide the whole system into modules / components / roles according to specific principles
3. Establish communication mechanism between modules / components / roles

To give a specific explanation, first of all, there should be specific problems. There is no problem talk structure, just like a castle in the air, which has no practical value. However, there will be different solutions for different problems.
Secondly, the division of modules should be based on specific principles. Without principles, there is no way to evaluate the quality of an architecture. Finally, the communication mechanism between modules makes the system a whole

last,Architecture mode, in fact, is more of an idea, a rule, often an architecture mode may have different ways of implementation, and between the ways of implementation, there is only the right or not, there is no right or wrong.

2、 How to analyze an architecture pattern

We have introduced the definition of architecture. According to this definition, we will analyze the architecture pattern from these three aspects later.

2.1. What problems does the architecture solve

Only when we know the problems to be solved by the architecture pattern, can we look at them pertinently and think about whether the solution is appropriate or not.

2.2. How does the architecture pattern divide roles

The most important thing in architecture is the role / module division. Only by understanding the role division in architecture mode, can we better understand its structure.

2.3. How roles communicate

Communication between roles is also important. The same role division and different communication methods often constitute different architecture patterns.

Role to role communication can be understood as the flow of data. In Android development, the data in communication can be understood as two kinds: one is the data structure, that is, the JavaBean used for communication such as network request and local storage; the other is the event, that is, the action generated by the control, including touch, click, slide, etc. In the process of communication, we also focus on these two kinds of data.

3、 What are the common architectural patterns

For Android developers, the common architecture modes are MVC, MVP and MVVM. These three modes are also common for GUI application development.

In addition, there are layered mode, client server mode (CS mode), master-slave mode, pipeline filter mode, event bus mode and so on.

This article also analyzes the three architecture modes of MVC, MVP and MVVM.

4、 How to develop app before not using architecture

After we understand the definition of architecture, we may think, why do we use these architecture patterns? Before we know about these patterns, it’s the same development. Similar to the design pattern, in fact, the purpose of the architecture pattern is not to develop the application software, but to make the structure clearer, the division of labor clearer, and the expansion more convenient.

Let’s take a look at how we developed without using architectural patterns.
For a simple chestnut, we haveEditTextTextViewButtonThe functions of the three controls are relatively simple:

1.EditTextAccept user input
2. Processing data input by users
3. Output data toTextViewin
4. ClickButtonClear user input

The interface is as follows:

Let’s take a look at how we develop without using architecture mode, which is our common development mode:

4.1. First, design the interface in 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">

      <TextView
          android:id="@+id/titleText"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:text="Normal" />

      <EditText
          android:id="@+id/edit"
          android:layout_width="match_parent"
          android:layout_height="50dp"
          android:textColor="@android:color/darker_gray" />

      <TextView
          android: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" />

      <TextView
          android: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. InActivity / FragmentGet fromView, conduct event monitoring
2. PassViewEvent processing after obtaining data
3. Set the processed data toView

The code is as follows:

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("")
          }
      }

      //Data processing may be network request, disk access, large amount of calculation logic, etc
      private fun handleData(data: String) {
          if (TextUtils.isEmpty(data)) {
              msgText.text = "default msg"
              return
          }
          msgText.text = "handle data ..."
          handler.removeCallbacksAndMessages(null)
          //Delay to simulate network or disk operations
          handler.postDelayed({
              msgText.text = "handled data: $data"
          }, 3000)
      }
  }

Disadvantages of the default development method:

Let’s analyze the above code. One obvious feature is that the processing logic is focused onActivity / FragmentNo matter it’s rightViewThe operation of, or the processing of data. The problem isActivity / FragmentIn the logic of bloated, follow-up expansion to lead a hair and move the whole body. Moreover, the unclear division of responsibilities also brings difficulties to the follow-up maintenance.

In that case, let’s see what it looks like after using the architectural pattern transformation.

5、 MVC architecture

5.1 model introduction

Actually aboutMVCArchitecture, in different frameworks, there will be some differences in implementation, which shows that architecture is a kind of idea. We choose a more mainstream implementation here.
Architecture pattern in Android Development -- MVC / MVP / MVVM

5.1.1. What problems to solve

We can see that the above does not use architecture for development, resulting in the problem of activity / fragment logic bloated, which is not conducive to expansion. So the problem MVC has to solve is:Control logic, data processing logic and interface interaction coupling.

Here is a digression. Actually, as a programmer, we should not only realize the requirements, but also make the code easy to read and expand. This often reflects the power, not that it is the God who uses all kinds of strange skills.

I don’t know if you have been exposed to Java Swing desktop application development. In Java swing, the setting of interface / control is also implemented by java code. If you don’t use architecture, the final result is that the control logic, data processing and page display code are all concentrated in one class. Readers can imagine that such code is difficult to maintain

5.1.2. How to divide roles

In order to solve the above problems,MVCIn the architecture, the processing of logic, data and interface is divided into three parts: model view controller. The functions of each part are as follows:

  • ModelModel, responsible for data loading and storage.
  • ViewView, responsible for the display of the interface.
  • ControllerController, responsible for logic control.
5.1.3. How to communicate (data flow direction)

Let’s see how the three communicate.

Before introducing communications, let’s explain what the data in communications is. In fact, in Android development, communication data can be understood as two types. One is data structure, which is used for communication such as network request and local storageJavaBean, the other is events, that is, actions generated by controls, including touch, click, slide, etc. In the process of communication, we also focus on these two kinds of data.

stayMVCIn the architecture,ViewGenerate event, notify toControllerControllerA series of logical processing is carried out in, and then it is notified toModelTo update the data,ModelAfter updating the data, inform the view of the data structure to update the interface.

This is a completeMVCData flow of

5.2 implementation in Android

I understandMVCPattern, let’s see its implementation.

In fact, in Android development, by default, it can be understood asMVCStructureViewPut it inxml Middle andJavaCode decouples, andActivity / Fragmentact asControllerLogic control, but Android itself doesn’tModelSo often we makeActivity / Fragmentact asModelandControllerTwo roles. And oftenxmlInViewThe operation is also inActivity / FragmentSometimesActivity / FragmentIt will also serve as someViewThe role of.

Therefore, in the specific implementation process, we should clearly divide the responsibilities. Here, we letFragmentact asViewThe role ofModelandControllerThe logical division is clear.

First, we define three interfaces as follows:

//Data model interface, which defines the operation of data model
  interface IModel {
      fun setView(view: IView)
      //Data model processes input data
      fun handleData(data: String)
      //Clear data
      fun clearData()
  }

  //View interface, defining the operation of the view
  interface IView {
      fun setController(controller: IController)
      //Status in data processing
      fun dataHanding()
      //Data processing completed, update interface
      fun onDataHandled(data: String)
  }

  //Controller interface, defining the logic of the controller
  interface IController {
      fun setModel(model: IModel)
      //EditText data changes, notify controller
      fun onDataChanged(data: String)
      //Clear button click event
      fun clearData()
  }

The above three interfaces are defined respectivelyModel,View,Controller Operation of. One thing to note is that according toMVCCommunication process,ViewNeed to holdControllerControllerNeed to holdModelModelNeed to holdView, so you need to expose the corresponding interface.

Let’s take a look at the specific implementation:

  • Model implementation

The processing of data in the model is to add"handled data: "Prefix, with a 3-second delay

class HandleModel : IModel {
      private var view: IView? = null
      private val handler: Handler = Handler(Looper.getMainLooper())

      override fun setView(view: IView) {
          this.view = view
      }

      //After receiving the data, process it. A delay of 3 seconds is set here to simulate the operation of network request processing data
      override fun handleData(data: String) {
          if (TextUtils.isEmpty(data)) {
              return
          }
          view?.dataHanding()
          handler.removeCallbacksAndMessages(null)
          //Delay to simulate network or disk operations
          handler.postDelayed({
              //When data processing is completed, notify view to update the interface
              view?.onDataHandled("handled data: $data")
          }, 3000)
      }

      //Clear data directly after receiving the event to clear data
      override fun clearData() {
          handler.removeCallbacksAndMessages(null)
          //After the data is cleared, notify the view to update the interface
          view?.onDataHandled("")
      }
  }
  • Implementation of controller

ControllerThe implementation of is relatively simple, and the operation is directly forwarded toModel, in fact, for complex business scenarios, there are a lot of business logic to deal with here.

  class HandleController : IController {
      private var model: IModel? = null

      override fun onDataChanged(data: String) {
          model?.handleData(data)
      }

      override fun clearData() {
          model?.clearData()
      }

      override fun setModel(model: IModel) {
      }
  }
  • Implementation of view

hereFragmentActing asViewThe role ofViewEvents passed toController, and receivedModelTo update the interface.

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?) {
                  //Inform controller of changes in data input
                  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 {
              //Notify controller to clear data event
              controller?.clearData()
          }
      }

      //Model data changes and interface updates
      override fun onDataHandled(data: String) {
          if (TextUtils.isEmpty(data)) {
              edit.setText("")
              msgText.text = "default msg"
          } else {
              msgText.text = data
          }
      }

      //Model data changes and interface updates
      override fun dataHanding() {
          msgText.text = "handle data ..."
      }

      override fun setController(controller: IController) {
          this.controller = controller
      }
  }

So we have a simpleMVCStructure.

5.3 advantages and disadvantages of MVC architecture mode
advantage:
  • Clear structure and responsibility division
  • Reduce coupling
  • Facilitate component reuse
Disadvantages:
  • In fact, our above example has been optimizedMVCStructure, in general,Activity / FragmentWill undertakeViewandControllerTwo roles will lead toActivity / FragmentMore codes in
  • Model direct operationViewViewModification of will result inControllerandModelAll changed
  • Increased complexity of code structure

6、 MVP architecture

6.1 model introduction

Architecture pattern in Android Development -- MVC / MVP / MVVM

6.1.1. What problems to solve

Problems to be solved by MVP andMVCThe same: control logic, data processing logic and interface interaction coupling, whileMVCInViewandModelDecoupling.

6.1.2. How to divide roles

In MVP architecture, the processing of logic, data and interface is divided into three parts: model view controller. The functions of each part are as follows:

  • ModelModel, responsible for data loading and storage.
  • ViewView, responsible for the display of the interface.
  • PresenterController, responsible for logic control
6.1.3. How to communicate (data flow direction)

As we can see, the roles in MVP are divided, andMVCBasically similar, so what’s the difference? The difference is in role communication.

MVPandMVCThe biggest difference isViewandModelDo not hold each other, all passPresenterTransfer.ViewGenerate event, notify toPresenterPresenter After logical processing, notifyModelUpdate data,ModelAfter updating the data, inform the data structure toPresenterPresenterNotice againViewUpdate the interface.

This is the data flow of a complete MVP.

6.2 implementation in Android

I understandMVPAfter that, let’s take a look at its implementation.

First, we define three interfaces:

//Model interface, which defines the operation of data model
  interface IModel {
      fun setPresenter(presenter: IPresenter)
      //Combing data
      fun handleData(data: String)
      //Clear data
      fun clearData()
  }

   //View interface, which defines the operation of the view
  interface IView {
      fun setPresenter(presenter: IPresenter)
      //View in data processing
      fun loading()
      //Data display
      fun showData(data: String)
  }

  //Controller, logical operation defined
  interface IPresenter {
      fun setView(view: IView)
      fun setModel(model: IModel)
      //Model processing complete data notification presenter
      fun dataHandled(data: String)
      //Notify presenter when model clears data
      fun dataCleared()
      //Notify presenter when EditText text changes in view
      fun onTextChanged(text: String)
      //Click button in view to notify presenter of event
      fun onClearBtnClicked()
  }

Defined aboveView,Model,PresenterThree interfaces, of whichViewandModelWill holdPresenterPresenterholdView andModel

Next, let’s look at the implementation of the interface:

  • Model implementation
class HandleModel : IModel {
    private var presenter: IPresenter? = null
    private var handler = Handler(Looper.getMainLooper())

    override fun handleData(data: String) {
        if (TextUtils.isEmpty(data)) {
            return
        }
        handler.removeCallbacksAndMessages(null)
        //Delay to simulate network or disk operations
        handler.postDelayed({
            //Notify presenter when data processing is completed
            presenter?.dataHandled("handled data: $data")
        }, 3000)
    }

    override fun clearData() {
        handler.removeCallbacksAndMessages(null)
        //Notify presenter when data cleaning is completed
        presenter?.dataCleared()
    }

    override fun setPresenter(presenter: IPresenter) {
        this.presenter = presenter
    }

 }

ModelImplementation and frontMVCThe implementation is basically the same inMVCinModelDirect operationViewThe view is displayed in theMVPLi, noticePresenterTo transfer.

  • Implementation of view

It’s still hereFragmentActing asViewThe role ofViewEvents passed toPresenter, and receivedPresenterTo update the interface.

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? = null

    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 = "MVP"

        edit.addTextChangedListener(object : TextWatcher {
            override fun afterTextChanged(s: Editable?) {
                //Pass text modification event to presenter
                mpresenter?.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 {
            //Pass button click event to presenter
            mpresenter?.onClearBtnClicked()
        }
    }

    override fun setPresenter(presenter: IPresenter) {
        this.mpresenter = presenter
    }

    //Show views in data processing
    override fun loading() {
        msgText.text = "handling data ..."
    }

    //Display the processed data
    override fun showData(data: String) {
        msgText.text = data
    }
 }
  • The implementation of presenter

herePresenterThe implementation of is relatively simple, and there is not much business logic. In practical application, the business logic will be processed here.

  class Presenter : IPresenter {
      private var model: IModel? = null
      private var view: IView? = null

      override 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 advantages and disadvantages of MVP architecture mode

advantage:
  • Clear structure and responsibility division
  • Module to module charging and disassembling coupling
  • Facilitate reuse of components
Disadvantages:
  • A large number of interfaces will be introduced, resulting in a sharp increase in the number of project files
  • Increase code structure complexity

7、 MVVM architecture

7.1 model introduction

Architecture pattern in Android Development -- MVC / MVP / MVVM

7.1.1. What problems to solve

MVVMProblems to be solved andMVCMVPThe same: control logic, data processing logic and interface interaction coupling, and at the same time canMVCInViewandModelDecouple, andMVPinPresenterandViewAlso decoupled.

7.1.2. How to divide roles

MVVMIn the architecture, the processing of logic, data and interface is divided into three parts: model view logic. The functions of each part are as follows:

  • ModelModel, responsible for data loading and storage.
  • ViewView, responsible for the display of the interface.
  • ViewModelController, responsible for logic control.
7.1.3. How to communicate (data flow direction)

As we can see,MVPThe roles in, andMVCMVPBasically similar, the difference is also in the role of communication.

We said above, inMVPMiddle isViewandModelDo not hold each other, all passPresenterTransfer. This enablesViewandModelDecoupling.

And inMVVMThe decoupling is more thorough,ViewModelAnd will not holdView。 amongViewModelChanges in will be automatically fed back toViewInterface update, andView Events in will also be automatically fed back toViewModel

In order to achieve this effect, of course, we need to use some tools to assist. The most common one isdatabinding

In MVVM, the flow of data is like this

ViewGenerate event, automatically notify toViewModeViewModelAfter logical processing, notifyModelUpdate data,ModelAfter updating the data, inform the data structure toViewModelViewModelAutomatic notificationViewUpdate the interface.

This is a completeMVVMData flow direction of.

7.2 implementation in Android

MVVMThe implementation of is a little more complicated. Let’s look at the definition of the interface first:

//ViewModel interface, which defines logical operations
  interface IViewModel {
      fun setModel(model: IModel)
      fun handleText(text: String?)
      fun clearData()
      fun dataHandled(data: String?)
      fun dataCleared()
  }

  //Model interface, defining data operations
  interface IModel {
      fun setViewModel(viewModel: IViewModel)
      fun handleData(data: String?)
      fun clearData()
  }

MVVMInterface in only definedViewModelandModel, noViewInterface, becauseViewYesdatabindandViewModelOf.

Let’s look at the implementation:

  • Model implementation

ModelThe implementation of is basically the same as the above, that is, the processing of data and notification after processingViewModel

class HandleModel : IModel {
      private var viewModel: IViewModel? = null
      private var handler = Handler(Looper.getMainLooper())

      override fun handleData(data: String?) {
          if (TextUtils.isEmpty(data)) {
              return
          }
          handler.removeCallbacksAndMessages(null)
          //Delay to simulate network or disk operations
          handler.postDelayed({
              //Data processing completion notification ViewModel
              viewModel?.dataHandled("handled data: $data")
          }, 3000)
      }

      override fun clearData() {
          handler.removeCallbacksAndMessages(null)
          //Data cleanup completion notification ViewModel
          viewModel?.dataCleared()
      }

      override fun setViewModel(viewModel: IViewModel) {
          this.viewModel = viewModel
      }
  }
  • ViewModel implementation

ViewModelThere are some differences in the implementation ofdatabindconductViewModelandViewBinding for.

Two variables are defined,inputTextYes andEditTextData bound in two directions,handledTextYes andTextViewData bound in both directions.

WhenEditTextIf the data entered in changes, you will be notifiedinputTextRegistered listeners, andhandledTextThe change of value will be automatically displayed on the interface.

class ViewModel : IViewModel {
      private var model: IModel? = null
      //View bound data, inputtext and handledtext will automatically notify view to update the interface after updating
      var inputText: MutableLiveData<String> = MutableLiveData()
      var handledText: MutableLiveData<String> = MutableLiveData()

      init {
          //Register data monitoring and inform model to process data after data change
          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)
      }
  
      //Clear button click event binding
      override fun clearData() {
          model?.clearData()
      }

      override fun setModel(model: IModel) {
          this.model = model
          model.setViewModel(this)
      }

      //After the model data processing is completed, set the handledtext value and update it to the interface automatically
      override fun dataHandled(data: String?) {
          handledText.value = data
      }

      //After the model data processing is completed, set the inputtext value and update it to the interface automatically
      override fun dataCleared() {
          inputText.value = ""
      }
  }
  • View implementation

to glance atViewData binding in.

class MVVMFragment : Fragment() {
      companion object {
          fun newInstance(): Fragment {
              return MVVMFragment()
          }
      }
 
      override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
          //Using databind for data binding
          var binding: ArchitectureBindingBinding = DataBindingUtil.inflate(inflater, R.layout.architecture_binding, container, false)
          binding.lifecycleOwner = this
          val viewModel = ViewModel()
          viewModel.setModel(HandleModel())
          binding.viewmodel = viewModel
          return 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">

      <! -- define data bound in view -- >
      <data>
          <variable
              name="viewmodel"
              type="com.zy.architecture.mvvm.ViewModel" />
      </data>

      <LinearLayout
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical"
          android:padding="10dp"
          tools:context=".MainActivity">

          <TextView
              android:id="@+id/titleText"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:text="MVVM" />

          <! -- two way binding inputtext to EditText -- >
          <EditText
              android:id="@+id/edit"
              android:layout_width="match_parent"
              android:layout_height="50dp"
              android:text="@={viewmodel.inputText}" 
              android:textColor="@android:color/darker_gray" />

          <! -- bind handledtext to textview -- >
          <TextView
              android: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" />

          <! -- bind the click event of empty data to textview -- >
          <TextView
              android: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>

Through the above implementation, whenEditTextAfter the Chinese text changes, it will be automatically modifiedinputTextValue of, triggerinputTextMonitor, nowViewModelDeliver messages toModelProcessing,ModelNotify after data processingViewModelto updatehandledTextAutomatically update to the interface.

When clicking the clear button, the bound click function will be automatically called to notifyViewModelClear event,ViewModelDeliver messages toModelClear the data,ModelNotify after data processingViewModelUpdate the interface.

7.3 advantages and disadvantages of MVVM architecture mode

advantage:

  • Clear structure and responsibility division
  • Module to module charging and disassembling coupling
  • stayMVPOn the basis of,MVVMholdViewandViewModelAlso understand the coupling

Disadvantages:

  • Debug is difficult becauseViewandViewModelDecoupling makes it difficult to see at a glance when debuggingViewEvent delivery for
  • Increased code complexity

8、 Application of architecture mode

In the above article, we introducedMVC,MVP,MVVMThree architecture patterns and their simple implementation. Let’s go back and think about when to use architecture pattern?

The architecture mode can make the code modules clear, the division of responsibilities clear, and easy to expand. The side effect is that a large number of interfaces will be introduced, resulting in a sharp increase in the number of code files.

We said at the beginning that architecture pattern is used to solve specific problems. If a specific problem is not a problem at the current stage, or is not a major problem, then we can not consider using architecture pattern first. For example, if a function is very simple, with a small amount of code, and there is no need for expansion in the future, we can directly use the traditional way for development, which is fast and clear, and there is no need for architecture.

It is also a good choice for the code that does not consider the architecture pattern at the beginning, and to refactor slowly afterwards.

In conclusion, although the architecture is good, don’t be greedy~

summary

Architecture pattern in Android Development -- MVC / MVP / MVVM

About me:

More interview content, interview topics, full set of flitter video, audio and video from 0 to expert development.
followGitHub:https://github.com/xiangjiana/Android-MS
Free access to interview PDF collection
Provide free resume modification suggestions and get interview PDF of large factory

Architecture pattern in Android Development -- MVC / MVP / MVVM

Recommended Today

The way of nonlinear optimization

Mathematical knowledge 1、 Nonlinear functionLinear function is another name of a function of first degree, then nonlinear function means that the function image is not a function of a straight line.Nonlinear functions include exponential function, power function, logarithmic function, polynomial function and so on. 2、 Taylor expansion1. Taylor formula:Taylor’s formula is to add a_ The […]