views:

464

answers:

7

Going through the mvc section at the chapter on compound pattern in the head first design pattern book, i came across the following thing that makes me uneasy. As per the description of mvc , model should have implementation of observer pattern and upon any change of its state it is supposed to notify all its observer of the event and as they have put it views are supposed to register themselves with the model to receive such notifications and take the necessary action .

Now model notifying view directly , does not this introduce the problem of tight coupling between each other that we are trying to solve in first place through mvc ?? My opinion here is that there should not be any direct interaction between models and views whatsover to the extent that they are oblivious of each other's existance , whatever state change events are to be raised either by model or view controller is the sole recipient of all such events and it only will route them appropriately. Is this approach correct ?? or do you see some flaw in this line of argument, please respond.

+1  A: 

If you read the book carefully, it says that for each new view you'll likely have to write a new controller as well. The decoupling is betwen the view/controller and the model such that the model isn't designed a certain way because of the user interface.

SnOrfus
yes , that exactly is my point . View and Model should not be aware/dependent on each other's existance, but if we are making view to receive model's events directly view has to have the knowledge of model to collect all necessary data . But if we make controller receive the event and do all data setting on view it serves our purpose and is better in terms of separation of concerns between view and controller. I understand that view and controllers are rather tightly coupled and specific to each other.
redzedi
no - it's not they should not be aware of each other, it's the model should not be aware of the view!
Tobias Langner
A: 

I guess it kind of depends on the kind of MVC you are working with, and the platform your environment executes on. In the case of MVC on a desktop application, the view does usually have a direct reference to, or at least direct access to, the model. That access generally includes observations on any events the model may fire. That is generally how MVC works. Web-based MVC implementations take on a different form, and while the view during generation time has a reference to the model, there is rarely any kind of eventing that occurs between the model and the view.

If you are interested in fully separating your views from everything, giving full control to some other central mediator, I recommend looking into MVP variants. MVP, or Model-View-Presenter, is an adaptation of the original MVC that solves a few problems for certain environments, and can often provide better separation of concerns when implemented properly.

Another option would be to use some kind of light weight messaging to provide a loose coupling between your model and view. Rather than implementing the observer pattern, have the controller or presenter create channels that allow the model to publish messages that one or more views may subscribe to. The channel infrastructure would be central to everything (model, view and controller/presenter), but would enable looser coupling between those things themselves.

The concept of lightweight messaging has been around for some time (it is fundamental to Erlang), and is a core, critical concept in Microsoft's research project "Singularity". It has been applied on a larger scale in the form of ESB's (Enterprise Service Bus), and other messaging servers such as MSMQ. However, the concept is not limited to large-scale distributed implementations, and can be very effective on much smaller scales to reduce coupling and improve separation of concerns.

jrista
In that case , is it reasonable to channelise all communication through controller i.e controller acts as BUS as u mentioned but in a smaller scale (say a desktop app or a presentation layer of web app ) PLUS controller has the intelligence to translate event to specific actions on view and model
redzedi
I guess it would depend. The controller is the central handler for all user activities, but generally, it does not mediate between the view and model. You could give the controller that responsibility, but then, you are adding concerns for the controller classes. That breaks Separation of Concerns. The idea with the channels is to maintain that separation, allowing the view, controller, and model to vary as independently as possible.
jrista
A: 

There is inevitably some coupling between model and view, in that the view needs to know something about the model (e.g to get instance properties for display), though not vice versa. For example, if the model implements observability using an interface, then views can implement that interface and register with the model to observe changes; the model knows nothing about the view implementations other than that they implement the interface. If the model implements an interface, the views need not know anything about the model other than that it implements that interface - i.e. they know nothing of the internal implementation of the model.

Vinay Sajip
A: 

There are many kinds of coupling. So let's get a little more specific, if two things are coupled then if one changes the other must change. By having the model notify the view what coupling have we introduced? What kinds of coupling are inevitable between M and V? What costs result?

The View can only do its job if it understands the Model. So if the model changes (eg. an attribute is removed, or we change an atribute measure in milliseconds field to one measured in seconds) then the view must be changed. That coupling is inherent in Model/View. Yes we'd might try to avoid the problem by making Model changes back-compatible, but that's just another way of saying that the coupling exists.

Now the Model is going to notify Views that it has channged. It could do two things:

  1. Hey view X, you're using my percentage attribute, it's gone up again!
  2. Hey everybody I've changed!

In the first case the Model knows the identify of who is listening and what attributes are interesting to each listener. This is very tight coupling. Every change in the View requires a change in the model.

In the second (recommended) case, we decouple by using an event registration scheme. Hence no code in the Model changes no matter how many Views there may be, and no matter which attributes are being used by any view.

One line summary: Coupling is not a symmetric relationship: The view depends on the model, the model is indifferent to the the view.

djna
that's good point , but what i am saying here is if controllers listen to all such event notifications instead of views directly then we can simplify the stuff that's to happen on view after model change event has been notified.
redzedi
Maybe I miss the point here, as far as I can see you're advocating that the controller should know what model events are interesting to which view. In which case you are introducing coupling between the views and controller. I don't see that as a win. Having the View say to the Model "tell me when you change" is enough.
djna
"... Having the View say to the Model "tell me when you change" is enough." - in that case view should also know about the model i.e when view receives an event notification , it should know also say how it should collect the relevant data from model to update itself
redzedi
I'm missing the point, the view knows about the model? Well yes, how else can it possibly work? The whole point of a view is that it's a representation of the data obtained from the model
djna
Thanks - on StackOverflow it's quite OK to fix such typos when you spot them. In future feel free to just edit the answer and fix it!
djna
Would if I could but 2000 rep is needed to edit :-/
danio
Ah yes. Forgot that.
djna
A: 

I think you got this wrong. The model is "observable" for changes (implementing the observer pattern). The views are designed to present/show/visualize a model, so they must know the model. They normally have a direct reference of the model to query the information. This is tight coupled (static at compiletime).

The model does not have such a reference. The view registers itself as an observer for the model at runtime. Now it gets notified on changes. The model itself does not know the type of the observers or who observes it. This is lose coupling since you can add different views, multiple views - whatever you want - without changing the model. Once the model is programmed, there's no need to change it.

The same logic applies to the controller. It needs to control the model. It's specifically designed for that model, so it can have a direct reference.


The Problem with generic controllers

There are generic controllers (buttons, listboxes, etc) that can represent a lot of different models. That's where Microsofts MVVC comes in handy. There's only an additional abstraction layer for the generic controler integrated as far as I know (but correct me if I am wrong).

In Short

  • Model: lose coupling to controller and view
  • Controller: tight coupling to model
  • View: tight coupling to model
  • View and Controller can be one (example: Checkbox representing a boolean, visualizing and controlling it).

Any questions about my answer?


Answers to the comments:

  1. The controller modifies the model, the view shows the model, the model represents the data and the logic.
  2. No - that's not his responsibility. Most of the time in modern guis, view and controller are the same. Example: If you have a chart showing some data, the chart is the view, the data is the model. The spreadsheet modifying the data is controller and view in one. If you change the values in the spreadsheet, the data gets modified and the chart gets updated. In this case, there are 2 views (chart, spreadsheet) both showing different aspects of the model (the data). The spreadsheet allows the manipulation of the data, so it's a controller as well. Another example: an sql-browser. You have some "command-line" to enter sql-commands. This is the controller. And you have a view on the result. This is the view. The result (which changes each time you enter a different command and execute it) is the model in this case.

In your case PrefView() is the view and the controller. It has buttons to manipulate the model. No need to seperate it. The case of the delete-button: direct method call for deleteModel(). Inside deleteModel, there has to be some kind of notification for observers (because the data changed). This callback is then used to update the view.

Tobias Langner
Hi Tobias, Many thanks for that answer. Please go through my responses above to various comments to get a sense of my dilemma , additionally i have following questions on ur response :-1> what is actual responsibility of controller - is it controlling model or controlling view ??2> Can controller act as a central mediator for both model and view ?? i.e is it reasonable to channelise all communication through controller
redzedi
If you give me a specific problem, I might identify the different parts for you. But to understand MVC you must first understand the observer pattern.
Tobias Langner
Hi Tobias , Thanks again . Let us consider a typical datagrid scenario which displays search criterias , show/delete buttons and data display area we will call this PrefView. We have a corresponding model for this called PrefModel that defines the data structurally and encapsulates the logic for data loading and associated business logic and i was planning to have a controller class PrefController between these 2.SCenario :-on click of delete button model's deleteModel() is to be called . On successfull deletion view is supposed to update various data fields and display appropriate msg
redzedi
+2  A: 

Patterns are names for common practical solutions, nothing more. MVC is a pattern, describing those particular relationships between layers - it doesn't say that they are theoretically clear and optimal, it just names them. Arguing about it is like arguing with dictionary that some word should have different meaning.

It might well be beneficial to design for more (or less) separation than MVC calls for, following different pattern or no well-known pattern at all.

ima
A: 

Here is my take on the situation:

  1. The model must never know about the view. Knowing about observers is OK.
  2. The view can know about a specific model class, unless the view can be used with different model classes (e.g. a table view).

The point is that the model can know about observers even if they are view objects, but it should not know that observers are views. For example, you shouldn't put a redraw method on the observer interface. If the model can access view functionality like redrawing, then it "knows about" the view.

I've written about MVC here if you want a more detailed explanation.

Tom Dalling