Forms and Leaky Abstractions
The model on Windows for rich-client programming is event-driven. Your window waits for a message, which is dispatched to a handler method it has registered with the OS (the Window Procedure). Frameworks hide this complexity here: in Windows Forms you register a delegate to listen an event and the underlying framework calls that delegate for you when it receives the event you were listening for.
Web applications work by a request-response paradigm. The browser sends a message to the server, which spins up your application in response to the request. Your application processes the request and responds with a message that tells the browser what content to display now.
WebForms’ server side controls brought the familiar world of event-driven programming to the web, by the trick of parsing the request to determine what action had caused the request and then raising an appropriate event on the target page.
Windows applications are stateful. While we react to events, the state of the application is preserved across those events, for the lifetime of the application.
By contrast web applications are stateless. The server spins up a new instance of our application to service each request.
As well as giving the illusion of event-driven programming, WebForms’ also created an illusion of state-fullness. The state of our page was preserved between requests using hidden fields embedded within the HTML and restored when the request was parsed so that our page felt as though it was stateful.
This illusion of event-driven, stateful behavior provided a familiar model for forms developers to use when tackling web projects and enabled programmers with little web experience to transition to web development.
The question is whether this illusion hinders as much as it helps. ViewState, the mechanism used to provide the stateful illusion has resulted in heavy pages as developers fail to grasp how it works ‘under the hood’ and make mistakes in its usage; developers no longer understand what HTML elements like input controls and forms are for; mixing dynamic HTML client-side behavior i.e. Ajax with server-side WebForms controls becomes messy rapidly; the postback model for raising events results in pages that flicker and are unresponsive; the loading of control state on requests encourages developers to think they are interacting with controls, not that they are rendering HTML for display by the browser; the page lifecycle is sufficiently torturous that is has become a favorite interview question.
WebForms have become a leaky abstraction, hiding too much so that the underlying protocols have been obscured and many developers cannot understand how to resolve problems when they hit them.
So the divorce of frameworks like MonoRail from the server-side control model is deliberate. While WebForms developers may look on hesitantly, the truth is that a model that reflects how the web works is in many ways easier to understand.
People who encounter MVC frameworks for the first time often stumble upon how useful they seem to be to RESTian services. The reality, of course, is that ,REST, Monorail et al all seem to have an affinity, because they expose how the web works, instead of obscuring it under a borrowed, and ill-fitting paradigm.
One facet of good design is software that is amenable to change. When we think about the cost of software we need to consider the total cost of ownership, not just the cost to live. Sadly that often gets forgotten, because people don’t add the two costs together when thinking about software, leading to short-term approaches in build, in an effort to reduce cost, even if the overall cost then increases.
When we talk about cost of ownership, the big cost is how amenable is the software to change. As the business the software serves changes, so must the software. While I have been told many times, ‘we do not need to worry about good design, we will never need to change the software’ I have never seen that to be true. In fact, change usually happens long before the first release.
It turns out that Test Driven Development encourages the adoption of MVC frameworks because UIs tend to require hosting in a context (browser, windows message pump, and console) that vanilla testing frameworks can’t simulate. It’s much easier with TDD to use a Test Double and replace the view with something that you can test.
Of course you might want to replace the model too if it talks to the DB, but that’s a separate story. ‘
It’s worth repeating an earlier blog here. There is a danger that some xUnit testing frameworks try too hard to solve the problem of hard to test code. They introduce the risk that you are no longer encouraged by those ‘hard to test’ areas to adopt best practices. Testing frameworks need to be smart enough, but no smarter.
So, as other posters have mentioned the addition of an MVC framework enables people who want to work in a Test-First way. However it’s important to recognize that one facet of putting your code under test, is the emergence of good design, so designing for testability is also good design.