My application is following the MVC design pattern. The problem I keep running into is needing to call methods inside a Controller class from outside that Controller class (ex. A View class wants to call a Controller method, or a Manager class wants to call a Controller method). Is calling Controller methods in this way allowed in MVC? If it's allowed, what's the proper way to do it?
According to the version of MVC that I am following (there seems to be so many different versions out there), the View knows of the Model, and the Controller knows of the View. Doing it this way, I can't access the controller. Here's the best site I've found and the one describing the version of MVC I'm following: http://leepoint.net/notes-java/GUI/structure/40mvc.html. The Main Program code block really shows how this works.
Thanks for any answers.
Take a closer look at this paragraph from the article you linked to:
View
This View doesn't know about the Controller, except that it provides methods for registering a Controller's listeners. Other organizations are possible (eg, the Controller's listeners are non-private variables that can be referenced by the View, the View calls the Controller to get listeners, the View calls methods in the Controller to process actions, ...).
You have the observer pattern here between the View and the Controller. MVC is not a single pattern per se but at least two combined.
One way to get your head around managing the View/Controller communication is to use events. The View fires events on certain user actions (without knowing necessarily who might handle them.) The Controller processes these events and acts accordingly.
Related
Please enlighten me: If I'm implementing a simple application using MVC pattern, should controllers always be bound to objects existing in the application?
For example, if I'm implementing a Holiday Reservation Application and I specify such classes like: User, HolidayRequest, Holiday, etc, should the controllers be: UserController, HolidayRequestController and HolidayController?
Thank you for your help.
Your controller receives the input of your application and controls what happens with this input (i.e. which data is passed to the model, which actions the model should execute on it, and perhaps if the view needs to update itself).
The inputs I can see in your example are a HolidayRequest, and a HolidayReservation. Those would be separate actions on your controller, so I would create a HolidayController that implements those actions.
In general, I would recommend going for a keep it simple approach, if your application is not too complex, your architecture should be simple, too. Don't go implementing N controllers when all you need is one single class ;-)
I've learned that you should set up the controller-class in a MVC-OOD as a use case, from top to bottom in only one method that run the MVC-classes.
Is it OK to use different methods in one controller to get more control and better overview?
Let's say you wanna run a controller that will display a login form (getting the html etc from the View). And the same controller will also display a log-out button IF the user is NOT logged in.
This could be done with a single method in the controller, but using two methods seems better. One method to call if you want the login form, and one to call if you want to log-out button.
(just an example)
So, what does the pros say. Should each controller contain one "use case" method only, or could it be several?
TL;DR -- you have misunderstood the MVC design pattern and are doing it wrong.
Controllers are not responsible for rendering the interface, nor for presentation logic. Controllers do not display anything. Instead, each controller's method deals with different user's request. It extracts the data from said request and passes it to model layer and the associated view.
Decisions about what and how to display are in purview of views. Views contain the presentation logic in MVC pattern. In the context of web applications, views create the response. They can compose a from from multiple templates or just send a single HTTP header.
Controllers can signal the associated view by passing some specific values of the request to that view, but most of the decisions in the view are based on information that the view requested from different services in the model layer.
A Controller's methods are based on what type of requests a user can send. For example in a authentication form it might be: GET /login and/or POST /login.
Its important to remember two things with MVC, firstly, its an Object-Oriented Architecture, and secondly, It should be used for separating concerns.
Separation of Concerns is related to Abstraction, It is to aid us in understanding the section of code at hand. The Model and View are both collections/domains of related objects. Each object is fully complete and relevant to its domain.
You will find objects with types such as Buttons, Images, Text Inputs etc inside your View, and you will find business related objects (User, Account, Profile etc) within your Model.
The collection of objects inside your Model don't tend to do much, They require logic to wire the objects together. (Or simply delegate simple single object requests to the correct object)
The Controller provides the interface into your Model, and contains the business logic related to the Model and the interactions between the Model objects. You will have a single Controller for your Model, and the Controller will have multiple methods which will align with your use-cases.
I find myself needing to have a View expose its Model and Controller references. Is this the smell of bad design? Or is this considered "safe" practice?
For example: I have a list (composed of a ListView, ListController, and ListModel) and many list items (composed of a ItemView, ItemController, and ItemModel).
When I create the ItemModel, ItemView, and ItemController for each list item, I pass the ItemView instance off to the ListView. But, at some later point, my ListController needs a reference to the corresponding ItemController instance.
So, would it be more proper to pass both the ItemView and the ItemController in to ListView::addItem(), or just pass in ItemView and expose an instance method such as ItemView::getController()?
Or doesn't it matter? Is each approach equally viable? If followed to their logical conclusion, does either tactic result in an anti-pattern?
But, at some later point, my ListController needs a reference to the corresponding ItemController instance
Why? If you're decoupling your classes properly, you shouldn't need this.
Controllers almost always address a functional domain. An example of such a domain might be "Sales" or "Admin." In addition, MVC also supports the use of "Areas," which provides an additional hierarchical level of organization.
Adding references to controllers from other controllers is at cross-purposes with this organizational structure. If you need to combine functionality to make your code more DRY, ordinary refactoring will accomplish that. You can also inherit controllers from a base class containing common functionality.
In the mvc pattern the users request shall be routed to a controller, say invoicecontroller, that has actions.
Lets say the default action, Index, returns a list of invoices; the controller then creates a model with a list of invoice objects, instantiates the correct view and injects the model into the view.
Now it is the views turn to do its magic. It renders the best view it can with the data it has, which may include routes to one or more controllers.
In NO instance should the view (or model) do business logic themselves.
That said, I totally agree with Jakub. Hope that helps.
Considering you are not actually showing any code at all.
In my opinion, you should change your design. A controller is not supposed to communicate with another controller (directly), MVC dictates it: reference.
If you need to invoke a controller action from another controller, consider using delegates or composition. Instead of directly invoking the controller action.
In my world, the model notifies only the controllers subscribed to the model's event. Then the controller tells the view what to do, for example adding a new row to a list.
The same with the view: the view notifies the controller subscribed to the view's event. Then the controller modifies the model as needed, for example setting the name of a person, and call the Save() method on the model.
Okay, I know I'm wrong, I don't think every article about MVC is wrong because I'm thinking in another way. The point in MVC is to seperate the UI from the data model. How does this come true when the view and the model reach each other? Why should they do so?
Thanks for Your answer!
Model-View-Controller is seen different ways by many people, but I like to think of it as a combination of several other patterns rather than as a single pattern. This may come originally from this note
The connection of the view to the model is an Observer Pattern, with the model notifying the view when it has changed. There's no need for the controller to be involved in this.
I completely agree with you on this one.
For every project i work on, i try to enforce this:
View --> Controller --> Model
So that every action or event in the view call a specific controller method. This controller method will do his job (validate, call other service, etc) then if persistence is needed, it will the call the associated ModelService to persist the data.
in my world, a view component should never call a ModelService without going thru a controller.
But that's just me ;-) (and almost 100% of the good architect and designers i worked with)
I like to think of the model as a transparent thing, adhering to some sort of scheme. Very easy to "read" by a view. I never make my views programmatic, in the sense that you can call all sorts of methods on it. Usually my view is HTML, my model has methods but is also capable of presenting itself as a plain data structure, and there is an intermediate: in the form of a template engine.
But, there are lots of variants for MVC. I don't think there are 2 developers who would exactly, exactly, agree on what MVC actually is. MVC is -in my view - a pattern to help you. It is not a law that is trying to hold your creativity back by exactly defining up to the last bit what you have to do.
I have two controllers that each do a separate action, retrieving data for my page. Can I chain them together and pass the data from the first to the second?
Looks like you have given a lot of responsibilities to your controllers. After all, a controller should delegate responsibility of building model (data) to others and should mainly focus on matching model with view. It should not even be aware of how model is built and how a view would be rendered. I think some refactoring is needed so that instead of requiring some chaining, you could use the same model builder in both controllers.
Having said that, of course, you can pass data from one controller to other and most popular way is to use redirect or forward. Please also see Programmatically call #Controller.