Tuesday, June 28, 2011

Model-View-Controller

I have read all about this pattern for doing UI work, but I have never seen a great need to adopt the pattern. Both Builder and Visual Studio invite you to place all of your response code directly into the UI element class, and I have gladly taken the invitation. To be honest, I had never seen a good reason to do any differently. Oh, I would wrap some concepts into external (or even internal) classes, but the basic approach has worked fine for me.

The last couple of days I have been working on the configuration assistant for the accounting system at mypeoplematter. This is an ASP Wizard control with (as of now) 11 pages, some of which feature expanding windows that allow the user to configure things like bank accounts. Very quickly the number of buttons and their callbacks became unmanageable. So I built a controller class that provided a framework for each page. Then each "page" in the wizard got its own Controller-derived class to actually handle the work. My form class was left with just a little code to abstract out navigation events, and 4 general-purpose button events that it forwards to the controllers.

The Controller class has an interface with 7 methods:
virtual public void OnEnter(secure_accounting_ConfigAssistant page);
virtual public void OnExit(secure_accounting_ConfigAssistant page);
virtual public bool SkipMe(secure_accounting_ConfigAssistant page);
virtual public void OnSelect(secure_accounting_ConfigAssistant page, object sender);
virtual public void OnShowEditor(secure_accounting_ConfigAssistant page);
virtual public void OnSaveEditor(secure_accounting_ConfigAssistant page);
virtual public void OnCancelEditor(secure_accounting_ConfigAssistant page);

It provides (empty) default implementations so that derived classes need only override the methods they need. I built a small caching mechanism to keep track of controllers throughout postbacks.

The resulting code is so clean that I will use it in every Wizard I build from here one, and probably for multi-tab pages as well. I can find the implementation of a given event handler by going to the appropriate controller and looking through at most 7 methods, rather than the over 60 that I would have needed without the controller abstraction.

Having said all that, I still do not see how MVC (or MVVC) would simplify my pages that perform a single function. Now, I have done some abstracting - most of my data entry pages have FillPage() and Gather() methods that handle the populating and retrieval from these pages. But since the pages themselves perform only a single function, I do not see the benefit to be gained from adding a controller class.

Any thoughts?

No comments: