-
Notifications
You must be signed in to change notification settings - Fork 104
MVVM in more detail
The idea of MVVM is to separate the state and behavior from the appearance and structure of the UI. To do this MVVM defines components with clear responsibilities as well as the relationship between those components.
The View defines how the UI looks like, what controls are used and what layout the UI has. The View doesn't contain any logic. For example, the View only knows that there is a button but not under which conditions this button is enabled or disabled or what happens when the button is pressed.
The ViewModel represents the state of the View. It has instance variables to hold values for the controls of the View and other values that define the state of the UI.
For example, when the View has a button that is enabled or disabled under some condition the ViewModel has a boolean property that indicates whether the button is enabled or disabled.
However, the ViewModel does not know about any specific controls. It doesn't know if there is a button in the View nor does it know about any other action controls. It only defines their state, in this case: when an action control is enabled or disabled.
The ViewModel contains all UI logic that is needed to define the current state of the UI. Additionally, the ViewModel has the responsibility to mediate between the View and the Model.
What the Model looks like depends on the application you are building. You can think of it as "the rest of the application". The MVVM Pattern doesn't specify the Model in detail. Typically, the Model will contain the business logic and the data persistence of your application. The only thing that is important is that the Model not be UI-specific.
The visibility between the components is clearly defined:
- The View knows the ViewModel but not the Model.
- The ViewModel knows the Model but not the View.
- The Model knows neither.
The ViewModel contains the state of the UI. This is implemented with so-called "Properties" that support Data Binding. The View knows the ViewModel and can bind itself to the state defined in the ViewModel. This way the View is updated automatically when the state in the ViewModel changes.
The View can call methods on the ViewModel for example when a button is pressed. The ViewModel decides what should happen when the method is called. For example, the ViewModel might do some validation. In the end the ViewModel will call some action on the Model. The Model could be some kind of Business Facade that encapsulates the business logic from the outside.
The biggest benefit of MVVM is that all the UI logic is encapsulated in a class (the ViewModel) that doesn't have UI specific dependencies. This means that you can write simple Unit Tests for the ViewModel without the need of bootstrapping the Application/UI.
This shouldn't be underestimated: Testing the UI is typically a hard task because you will need integration tests in a classical development scenario. To verify that some actions in the UI are only possible under specific conditions in your test you will have to startup the application and use some sort of robot to click through the UI to reproduce the desired state and to trigger the actions that should be verified. To write this sort of test is time consuming and error prone. In addition, most of the time it isn't easy to run this sort of test in an automated way because it takes a lot more time for the test execution and it needs a graphical environment installed. This can be a problem on build servers.