My current project has Windows Forms as it’s UI technology. We started off with an MVP approach, and this has worked well, but I experimented recently with a Presentation Model pattern for a data entry grid. It seems to work nicely, and I am reasonably happy with the code, so this series of posts is going to cover how we can implement this pattern with Windows Forms.
Why should I care?
I suspect many (the majority?) of developers put all their code in the View of a screen (Transaction Script). It is very easy to do this, partly because Microsoft doesn’t build anything into the framework to guide UI design, so it is the path of least resistance to add code in the event handlers to talk to the database, perform any business logic, and finally bind to the controls. This is arguably fine for demo code, but leads to a nightmare for maintainability.
The code-behind of the View is not a good place to put application logic. It is difficult (impossible) to write tests against. Important business logic is hidden alongside infrastructure and UI code, and most likely duplicated throughout the application(s). Changes to requirements are difficult to implement as there is no adherence to Single Responsibility Principle.
What is Presentation Model?
Martin Fowler has an extensive article on the Presentation Model.
To quote “The essence of a Presentation Model is of a fully self-contained class that represents all the data and behavior of the UI window, but without any of the controls used to render that UI on the screen. A view then simply projects the state of the presentation model onto the glass.”
For me, it is about separating UI logic from application logic.
UI Logic – User interface logic should be kept minimal as possible, and directly related to interacting with UI controls in a particular view. For example, flagging a customer row with a different background colour if they meet a certain condition.
Application Logic – This is what happens when a user interacts with a screen. A button is clicked, an event is raised, actions happen based upon that. The nice thing about having this as a separate object, is that it can be used without the full application being fired up. This saves time, and leads to an improved feedback cycle.
The preliminary plan is to have posts covering the following:
- View and Data-binding in Winforms
- End to end example
Comments and suggestions welcome.