During my first encounter with
the Model View Controller and later with the Model View Presenter pattern I had some hard time understanding what's behind the Model. Having practiced test driven development for years I will now summarize my experience and will describe a new pattern called Service View Presenter or SVP.
Why MVP/MVC?
The MVC pattern has emerged long ago in an attempt to make user interface code modular and
better structured. Then the MVP pattern came as a refinement in an attempt to make MVC more testable. In its very essense MVP does not allow the View to interact with the model directly. Hence the view becomes a purely declarative piece of code (i.e. no if/else/switch statements and only foreach loops). Thus all logic resides in the Presenter and the view is being mocked out during unit testing. Let me now go into some more details about the roles of each of these elements.
The View
In MVP, the view is concerned with
- Declaring how the UI should look
- Capturing user interaction
- Modifying the view on request from the Presenter
The Presenter
The presenter then has the responsibilities of
- Handling user interactions
- Manipulating the view in response
- Interacting with other objects to perform calculations or
data access
Having asked several people the question "What is the model?" I usually receive different
responses, like:
- This is a pure data structure/holder class (e.g. a DTO)
- It's a data holder with embedded logic for e.g. consistency checks, serialization etc (which must have their own tests)
These sound reasonable, but IMO misses an important point. Why care so much about the model if it is either a pure data holder? So, for the time being, let's define the Model like this
The model in MVP is a set of objects that the Presenter interacts with in order to perform calculations and move data from/to the view.
We can then divide these objects into two categories
Libraries
Side note: Another nice effects is that they scale well (because they are stateless aka functional)
- Libraries are supposed to have unit tests of their own
- We don't need to mock them
Services
The majority of these are objects that let the presenter interact with external data stores. For example:
- Query a database table to get the user's preferences
- Call a REST service to post a new photo in an image gallery
- There could be services that are stateless, much like libraries. For example a Weather service.
through the respective protocol. For example:
$.ajax({ ... })
There could be also services that have been introduced in order to isolate the components in a large piece of software. For example in multi-view screens the different view often communicate through a message bus. Then the message bus is also a service, even though it does not communicated with remote hosts. By definition, services shall not be called during a unit test, because unit tests shall be independent from the environment. That is why in a test case they are mocked out and usually also stubbed, to simulate different responses.
SVP - Service View Presenter
Therefore, we come to a pattern called SVP, in which we aim to structure our code around:
- Services - as described above
- View - as in MVP
- Presenter - as in MVP
- Only presenter is subject to unit testing
- Presenter is injected with the view and the services (e.g.
through a constructor or a DI library). - View and services are mocked and stubbed in order to simulate
the test scenarios - Data holders and Libraries remain untouched, but as a side
effect are covered by the test as well
