Huh? I guess... I guess it makes sense! I used to do that a lot; I would create the main application controller and all the other ones would have a pointer to it in case they wanted to tell the software that something had happened or in case they wanted to know who was the currently logged on user. It had never occurred to me that this was wrong until I had views within views within views and controllers within controllers within controllers. I was getting very confused and lost within my own code. Design patterns are supposed to help me, not make things more complicated!
The MVC design pattern (image taken from wikipedia)
The tiny little programmer that lives under my software developer hat (reference to Ratatouille, here) started instructing me to use events instead of calling parent controller methods. Events! I had completely forgotten about them! This is what web programming does to you, by the way: you forget how to build a desktop application properly. And then last week, I realized I could've simply used a singleton class to hold information such as the currently logged on user instead of calling properties from parent controllers. Now why didn't I think of that before?
(Note to self: read this blog post before you design your next program!)
But there is something else I've come to realize. Whenever I use the MVC (Model-View-Controller) design pattern, I don't use it in quite the same way. Depending on the situation or task at hand, I'll code it differently. Sometimes I'll have each view create their own controller, through which they modify and get information from the models. Some other times, the controllers give the model objects to the views and tell them to display them however they want to display them. The controller doesn't care what the view does and kinda trusts it not to mess with the model object being passed.
I'm unfortunately pretty chaotic when I program and this blog will help me put things in perspective. I need to go back over previous designs and decide what went wrong and what went right and writing about that will force me to think about the issue much more clearly that just giving it a though while I'm falling asleep at night. Believe me, that doesn't work... "I guess I could use this control.... ZZzzzzzz." Yeah... um, no.
My way (or you might wanna choose the highway)
Anyway, so how am I supposed to use this design pattern? I see it everywhere, from Ruby on Rails to Cocoa applications. Even ASP.Net now has its own implementation as a new built in feature. Yet everything I code seems to be more complicated than the usual little MVC diagrams that I find everywhere on the Internet, like the one above. Alright, let's see...
First of all, I will never again access information about a model directly from the controller. Instead, the controller will always give me access to the model object. It is logical after all: the view knows how to display the model and the controller shouldn't get in the way.
Secondly, we need to make sure that the model is completely isolated from the rest of the application. This means that if the information contained in the model object needs to be transformed in any way, the controller will be in charge of doing that. The controller also knows about the models in general and can make decisions concerning passing information back to the models.
This is getting complicated. It looks like models are well isolated, like views require models and controllers, and it looks like controllers require models. Does a controller need to know about a view? No. Views know what kind of controller they need and simply ask for it. The controller, in turn, will give the view the models it wants. Phew! I got it out of my system! Finally something I can base myself on when I design my applications! It's worth repeating:
- Views know what kind of controller they need and simply ask for it.
- Controllers give the views the model objects that they want and act as a conduit for information going to and from (sometimes) the models.
Now, how can we prevent the views from updating the models? It depends. If I'm the only programmer on a project and I know for sure that there will never be more than one or two developers working on it, and that the project will never be used as a library or incorporated in another project, then I don't really have to prevent the views from updating the models. Just knowing that I shouldn't do it is enough.
In other cases, however, it would be best for the controllers to provide the views with an interface to a model object instead of the model object itself. The interface would only give access to methods that can be used to get data out of the model. Then only the controllers and the models themselves would know how to update a specific model.
What if I ever feel like coding controllers that have child controllers again? How do I prevent myself from doing such an insanity again? This usually happens when I have multiple views embedded within each other, all interacting with the same model object, but in different way. I enjoy the way I can choose different views on the fly for different reasons and each view might require their own controllers because of varying business logic. Well I can simply allow all my views to have access to the same controller, eliminating the need for more than one. This is not always the best scenario, however, since I do not relish the thought of having one giant, massive controller.
Another way is create a helper class that will hold the data that can be needed by multiple controllers. A singleton would be perfect for that sort of thing. And finally, the same model object can be shared by multiple controllers. You believe in sharing, don't you?
Reusable code
In the end, it seems that following what I just preached about will yield code that is better designed, with better defined interactions and that is more reusable. Models will be isolated and will definitely be reusable with the aid of pre-made controllers; it's just a matter of snapping different views on top of them. This way, a desktop application can become a web application or service and vice-versa without to much trouble. This is actually what is going to happen with my project and I know that all my design flaws will jump in at my face when I get started on that.
If nothing else, the time I spend designing a good MVC architecture for my applications will help me structure my ideas much more clearly and that is a good thing. I don't think I'll be perfect anytime soon but its at least something that I'll have gained. And I'm all about improving myself!

0 comments:
Post a Comment