I was taught (hopefully rightly) that a class contains data relevant to it and methods which act on that data. For example, a class representing a Monkey might have attributes like date of birth, male/female, number of children, and a reference to the zoo where it lives. Methods might be getYearsOld() to work out how many days old it is, haveSex(List<Monkey> partners) [aren't chimps well known for group sex?], addChild(Monkey kid), setZoo(Zoo newHome).
Equally a complex graphical user interface component like a tree or a table might contain a matrix or hierarchy of cells and methods for setting the cells attributes (data, size, borders, rendering information, etc). It would typically have renderers for painting the cells as well as perhaps editors for editing the data in the cells. In fact, Swing has a rather nice implementation of Tables, Trees and even Tree-Tables. Eclipse JFace is fast catching up.
So if you do find yourself building something like this, say in Java Script, look at the nearest thing you can find that already exists, analyse how object oriented it is, then implement something similar (even sub-class it).
What you want to avoid is creating a load of helper methods which just build the GUI in a totally pre-object-oriented manner - Builder Classes as I call them.
I have seen this done several times by programmers that learned to program in the object oriented age. It might be expected from an older programmer who learned to program pre-object orientation, or one that has never used an object oriented language. But its odd when its done by programmers selling themselves as knowing object orientation. Very odd indeed.
Here is a quick challenge:
Go to Google and search for "MVC".
Check each of the first ten search results.
What do you notice? Each description of MVC is different. Perhaps not in terms of the Model, the View and the Controller, but in terms of the details of how they interact with each other. In some descriptions the controller sits between the View and the Model. In others they all talk to each other. I have even seen implementations where an update in the GUI sends an event to the Controller which updates the Model which sends an event back to the Controller which updates the View, with the same data which it just changed, resulting in a very active user interface!
Now it starts to makes a lot more sense, that both Java Swing and Eclipse SWT / JFace do not implement true MCV but rather a light weight version referred to often as separable model architecture. Here, the Model is seperate from a "delegate" which is a combination of the Controller and View. It makes a lot of sense and reduces complexity and confusion a great deal.
One case where I would advocate a separate Controller is where the View is very complex and there are also a lot of business rules dictating how the data is validated before being set in the model. Then it is useful to implement a Controller. In such cases I suggest the following rules for your three MVC components:
- The View listens to model changes, but only through an independent interface to ensure no dependencies on the model
- The Controller has methods that take all the necessary data in order to update the model, so that they have no dependency on the View (e.g. they don't query the View to get the selected radio button in a group. It is important that the Controller is independent of the View and the View can be (ex)changed at any time.
- The controller responds to UI events and updates the model based on these. To reduce the amount of model change events which are fired after the model is updated, the Controller can contain coarse grained methods and fire model change events itself, for example at the end of a coarse grained / facade method.
- The model contains data as well as a list of listeners (who implement an independent interface - see rule 1), who would like to be notified in the event of model changes. The model itself does not however fire events when it is updated. This is left to the Controller who knows if its appropriate to do so (consider performance here).
- Model updates/changes should only be done through the Controller in order to guarantee that both business logic is adhered to and that model change events are fired.
I believe that models who fire their own events are the result of frameworks like Java Swing and Eclipse SWT / JFace who have done away with the Controller. This works fine in such environments, but when the Controller is re-introduced it is significant NOT to send an event with each attribute change in the model - because it results in cases where a UI component is updated for example 20 times resulting in very poor UI performance. The UI can also unnecessarily hog System resources in cases like this because Java will not necessarily release them until the JVM is ready to do so.
This proposal is based on experience of different implementations as well as a project where we implemented exactly this pattern where it worked very well.