This week I had planned to start on a new feature for my pet project – the personal financial management application. A way to add and record account balances. Up until now I had not implemented any form of unit testing, or utilizing any form of test-driven development. I was quite excited to get started, even managed to write a few tests – but soon I was distracted. My user-interface class was starting to balloon, I was add too many components and responsibilities to this “god class” that was doing everything that was UI related. It was time to break it up into smaller pieces.
Almost as soon as I started I began running into problems. Everything was interconnected, it was a like untangling spaghetti. Soon it became pretty obvious that I would struggle to refactor the code without breaking the functionality. I decided to break that rule and rebuild and restructure the code by writing new classes copying the constructs to the new class but without implementing functionality. I ended up with a nice set of “view” classes that didn’t do anything except add low-level components to panels, and these classes would then assemble each panel and wait for another class to request it. It was nice, it was clean, it was modular, but functionally it didn’t work.
It looked that same, everything was in the proper places, but I had yet to wire up any of the views to the underlying model. This is when I discovered something interesting about the way MVC should be implemented. In short, it appeared that there was no single agreed way of implementing MVC. The key question was – should the view communicate with the model directly(via request for object state) or should everything be handled through the controller? It took awhile for me to figure this out. I was under the impression that the view should be able to request information from the model directly, but other developers would disagree.
In the end, I had to ask myself, what is best for my project? and what is best for me as a growing developer. I had to ask why would you want to completely decouple the UI from the model?
The reason for the MVC pattern is to decouple the model from the view. In other words, the model wouldn’t know how the information is going to be displayed – it could be a printout to a console, or a beautiful GUI, the model wouldn’t (or shouldn’t) know or care. Similarly the view shouldn’t know too much about the underlying model. This decoupling promotes component re-use and better maintainability and flexibility. Clearly some people have decided that actually, reuse and flexibility is more important for the model than it is with the UI. After all, how often are you going to reuse parts from the UI in another project – when the UI framework provides easy ways to construct UI components anyway?
However, allowing direct access to the model seemed like a cop-out. Anybody could do that. Simply store all your data in the objects fields and allow the UI public access to the object’s getters and voila. You’re done. Too easy. Some people have gone as far as to use interfaces to further decouple this route, but I don’t see much benefit in adding an additional layer of indirection at this point.
A harder and more interesting approach is to completely decouple the the UI from the model, making all the data exchanges through a controller class. So I have begun adding functionality via controller classes to help “wire” the model and the view together.
Of course I have also run into problems here, such as creating a controller “god-class” that performs all things controller related. I have begun adding classes for each feature that should act as a mediator between the model and view, but I can’t help but feel that some of my controller classes are a little messy. I often find myself asking – should a controller class really have this many references to so many view objects and model objects? I have found myself passing references of half the classes I have written so far into the controller class via constructor-injection or setter-injection. Suffice to say, this many references to so many objects makes me feel that while the model and view are nicely decoupled, the controller classes feel like they are doing too much and know too much about the other classes.
So far, the controller, model, and view classes are smaller than 150 lines, and are fairly manageable. It is yet to be seen if this implementation of the MVC is going to help me or hurt me. Hopefully, I have a nice separation of concerns which should make the project more flexible in the long run. Although I still have this nagging feeling about some of the wiring. In the mean time I will forge ahead in this direction and wait until some new inspiration hits me, or until someone shows me a better way to implement the MVC pattern.