3

I've been working with a friend on a project that we've taken over, and I've realized that we have a big problem implementing the model-view-controller design pattern due to the way that the project has been set up.

The project is currently split up into the following three sections (.proj files in Visual Studio):

  1. Model classes.
  2. Controller classes (business layer logic).
  3. View classes.

Visual Studio isn't letting me create cyclic references (quite understandbly) between two of these three sub-projects. This means that the controller classes can have a relationship with the view classes, but the view classes can't have a relationship with the controller classes! The result of this is that as soon as the controller displays a view, the rest of the controlling logic has to go in the view class!

So I've proposed that we merge all three sub-projects together (to avoid the cyclic references of visual studio). This means that we can create all the relationships between the three types of classes that the model-view-controller design paradigm requires. Ultimately, it will be we can place the controlling logic in the rightful place of the controllers, taking it out of the view classes.

The problem is I'm having a hard time convincing my friend about this. He thinks that having these separate boundaries between the sub-projects means that there's safety that we won't ever do things like put controlling or viewing code in the model (as the model sub-project is currently only ever referred to and doesn't refer to the controller or the view).

I was wondering if anyone could come up with some ways that I could really get my point across about how important this design pattern is, and how limiting it would be to go against it, and continue putting controller logic in the view classes?

Many thanks.

4
  • I don't quite understand in what scenario the view should need to reference the controller?
    – Domenic
    Apr 18, 2011 at 23:05
  • When the view want's to notify the controller than the user is interacting with it (clicking a button, dragging a slider, scrolling a page etc. etc.) In these events, the controller needs to decide on the action to take, perhaps calling on resources from the model to make decisions or pass information back to the view to be presented to the user. Apr 19, 2011 at 7:49
  • 6
    An event-publishing architecture should not have the code element firing the event dependent upon anything listening to it. I think your coworker is right; you are trying to create a circular reference out of misunderstanding of the MVC pattern.
    – Domenic
    Apr 19, 2011 at 14:34
  • Hi Domenic, your comment about the event driven system is correct. I think I misunderstood C#'s way of implementing MVC (I thought that the only way would be to use protocols and call methods between the view and the controller). Thanks for the help. May 9, 2011 at 14:20

3 Answers 3

4

The controller really shouldn't hold business logic, you should try to put as much business logic as you possibly can into your models, not the controller.

The view should only talk to the model, not the controller.

The controller sets up the model (or a specialized ViewModel, EditModel) and passes this to the view.

The controller's main concern is handling the presentation logic, what screen comes after what etc. The controller just wires stuff up, connects screen to each other etc.

The inability to reference your controller from your views seems healthy to me. The model should have everything the view could ever need. The controller can play a role in helping the model get there.

3
  • I think the buisness logic should be split across the model and controller, but that's not the key issue here. What happens when the user clicks a button in the view...? The view has to let the controller know so as it can figure out how to present the next thing. Apr 19, 2011 at 7:54
  • 1
    the controller method invoking the view could either receive some kind of return value or object. Or it could register a callback while invoking the view.
    – Joppe
    Apr 20, 2011 at 23:46
  • The return value option would be that the controller would only be able to respond to the view being closed, which isn't enough functionality. I think registering a series of callbacks is the alternative here. The only issue I have with this is that the code could get a little messy because it can be hard to see where the callbacks have been assigned (as opposed to, say, being able to go to the code that's called when a button is clicked). Apr 21, 2011 at 7:56
2

My suggestion would be to consider creating interfaces that the view class implements yet the controller class can use that interface as a way of knowing what the view does hold. This is what I've seen where I work that at times works pretty well. The interfaces are a separate project with no dependencies as they are just stubs of the calls rather than an actual implementation.

As for a suggestion to your friend, consider where would you like to put tests and how should they be structured so that a UI change isn't suddenly breaking a bunch of unit tests if it a change purely for the sake of appearance?

Another idea would be to consider taking a small portion of the entire system to put into an MVC structure and see how well or not so well it goes in terms of actually using it as this is where the big learning will happen.

1

The best argument I find is from the testing perspective.

If you have a controller class that handles all the logic, you can easily test it with basic unit tests. Since the view classes will then only contain the creation of graphics and user interface, there won't be any need to test those classes.

The other option is that the view and controller functionality are in the same classes, that will mean your tests will be relying on user interface events for the tests.

Once you start to think from the perspective of making testing easy, good code design often comes automatically.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.