Thursday, November 17, 2011

SVP - Service View Presenter

Introduction
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

The Model
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

These are objects of static,stateless nature, that operate solely on the input data and returnresponse. Their code lives in the same execution environment (OS process, HTML page, JVM ...) This makes the libraries easy to test,because they don't depend on the environment.

Side note: Another nice effects is that they scale well (because they are stateless aka functional)

This means that:

  1. Libraries are supposed to have unit tests of their own
  2. 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.

Most of the the code of a service object lives outside of the execution environment of the presenter and is accessible through some protocol, such as HTTP, RMI, CORBA etc. There is a small part of the service code living in the same environment that is used to make the actual call
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
Libraries and data holders (DTO) still exist, but we don't care much about them, because they do not interfere with our testing process. Want to use a library inside your presenter? That's fine. As long as the test passes and the presenter code is covered 100% you can use whatever library you want. Here is the essence:
  • 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

This pattern is just slightly different than MVP in that it refines the Model into a Service and specifies the Libraries and data holders. I hope it will be useful, especially to the young software developers trying to find their way around MVC/MVP

No comments:

Post a Comment