When applying the MVC pattern to a design with multiple classes do I need to create a model, view and controller for each of the relevant classes?
For example, for a design with a domain with UserAccount class, a MultimediaContent class, etc, would I need to design a UserAccountModel, UserAccountView, UserAccountController, and a MultimediaContentModel, MultimediaContentView, MultimediaContentController, etc?
I've looked for examples online but they all use a single class.
In the he original MVC as decribed by its inventor a:
an application should have one controller
a controller can provide input and commands to several views,
an applications can manage multiple models.
This is is a very high level description because each of these main "components" could be made of multiple classes. So it is fully up to you to decide of the best mapping.
Other principles, such as the separation of concerns, would suggest to have different views for different model objects. So a UserAccount, and a UserAccountView is in general a sound approach. But you could still have combo views that refer to serveral different model objects at once.
You will find many more flavors of MVC regarding the controller. The single controller monopolizing the user input and controlling all the views and commanding the domains, is no longer a reality, since many windowing system attach the controller to a window. So you'd probably have a swarm of controller, with an AppController and an additional controller for each view, e.g. UserAccountViewController, rather than a controller per domain object.
Of course, in a very simple application, with a few relatively independent domain object, each having a single view, you could find the objects as you describe them.
Related
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.
This question really has larger architectural implications and I welcome any input or suggestions on this:
I'm more of the Martin Fowler school of thought when it comes to OOP. I believe you should be able to directly render domain entities in the UI. If I have a Car entity, I should be able to render it to a webpage. The domain model is a crosscutting concern and not a layer. Treating the domain model as a layer leads to an anemic domain model. I don't believe in DTOs in an OOP architecture.
A view model for me is a way of composing the domain entities required in your view. It's not a DTO. I don't understand what the reasoning behind using a view model like DTO is though it seems like a common thing to do using automapper?
So using the metadata approach I put data annotations on my domain model to give any UI implementation hints on how to render and validate the entities. I like to have a richER domain model.
In MVC3 how can you accomplish this (specifically using the Display data annotation) with a resource file that resides in the UI layer? Is there a native implementation for this or do I need to get creative myself? Or have I gone wrong somewhere in my approach?
I disagree.
For one thing, some of the attributes you will use to specify how an entity property should be displayed on a web page come from the System.Web namespace, not the System.ComponentModel.DataAnnotations namespace. By putting these attributes on properties in your domain model, your domain model is taking a dependency on System.Web. For example, there is the [HiddenInput] attribute that tells MVC3 to render a field as input type="hidden". This is not in System.CompoenentModel.DataAnnotations.
Secondly, I don't believe you need data annotation attributes on your entity properties to have a rich domain model. A rich domain model comes from classes that wrap knowledge in a context. The client application should not need to know anything about the domain in order to use it. You achieve a rich domain model with classes, methods, and properties that describe knowledge using the ubiquitous language. DataAnnotations attributes don't lend themselves well to the ubiquitous language imo. And, your domain is more than just your entities. There are factories, services, and other patterns that you can use to build a rich domain model. A domain with only entities and metadata sounds anemic to me.
Thirdly, you may have an entity that should be rendered in different ways on your web site. When someone searches for a car, you may want to display just the make, model, year, and thumbnail photo. When someone clicks on the search result, you may want to display multiple photos, reviews, etc. If you were to use the UIHint attribute on an entity to tell the web ui how to render the car, you wouldn't be able to have different strategies for rendering the Car in different contexts.
Finally, yes, automapper is really great for DTOing your entities into viewmodels. It essentially lets you populate copies of the entity, disconnected from the domain, targeted for specific UI concerns. Here it is safe to use HiddenInput and UIHint attributes to tell MVC3 how to render data.
Response to comment 1
As far as UIHint, I mentioned it here because it has a special meaning with MVC3 EditorTemplates. In cases where a partial view involves receiving input, what is the composition of the view? Text fields, drop-down lists, and input elements that often correspond to entities and their properties in some aggregate root. You will therefore need some representation of the entities to encapsulate the data. Your DTO can be an aggregate root as well, with depth. You can have a root DTO with scalar properties (text/date/bool), navigation properties (drop-down list) and collection properties (ul/ol/table).
We create a corresponding viewmodels for many entities in an aggregate root, and implement them as views using EditorTemplates. If we ever want to switch to a different EditorTemplate, we can apply UIHint to a viewmodel property. Thus we can tell it to "render a location dto as a google map". Automapper can map navigational and collection properties to corresponding viewmodels, forming as complex a representation of your domain entities as you need for the user.
Forgive me if I misunderstand what you mean by flat dto.
Response to comment 2
A viewmodel dto can flatten out / denormalize some properties (using automapper), if your requirements call for it. For example, consider a University entity. It may have many names in many languages (translations), hinting at a UniversityName entity in the aggregate, with University having a collection of Names (1..n). Of those names, 1 may represent the OfficialName / NativeName, and another may represent the TranslatedName to the user's CurrentUICulture. Other entities in the collection may represent TranslatedNames that the user does not understand, and need not be bothered with.
If you have a view that is only interested in these 2 Names in the collection, you can promote them to first-class properties on the viewmodel:
public class UniversityViewModel
{
public string OfficialName { get; set; }
public string TranslatedName { get; set; }
// ...other properties
}
This is a case where denormalizing part of the entity when converting to a viewmodel dto can make sense. Notice how the viewmodel is anemic -- a bare container for data transfer from a controller to a view. This is perfectly fine, and in fact, encouraged.
Answer to original question
To answer your original question, it helps if you think of your domain model & entities as a layer -- more specifically, a bottom layer. Layered software is easier to understand if you think about the various concerns in an application as having dependencies on other concerns. MVC3 is a presentation / UI layer, and will have dependencies on the layers beneath it -- one of those being your domain layer.
If you want to access a resource file in the UI from the domain layer, you are going in the opposite direction. You would be making a low layer depend on a higher layer. If your domain lib depends on the UI lib for a resource, and the UI lib depends on the domain for entities, you end up with a circular dependency. I think you could probably accomplish it using reflection if you needed to, but in that case, you would be fighting against the framework. MVC and .NET in general may not be the best choice for you if that is the case.
I actually think of resource files as a cross-cutting concern. Our application has i18n sprinkled throughout, and often we find we need the same language text resources in both the domain and the UI.
There is nothing wrong with putting a Display attribute on an entity. But if you want to use resources for it, then either put that resource in the domain layer, or if you feel it doesn't belong there, in a lower layer. That way it can be accessed by both the domain and the UI.
So I ended up putting a resourse file in the domain model and added a custom HiddenFieldAttribute so that I don't have to reference the MVC assembly in the domain model.
I still fundamentally dissagree that a view model is really a DTO and that the domain model should be constructed as a layer. I feel that architecting the application in this way creates abstractions that really have no value. If the domain model was truly a layer then we would build a set of logical interfaces from which to access it, and this we don't do. It's a cross cutting concern.
Thanks to olivehour for an interesting discussion and suggesting that it's okay to place resource file(s) in to domain model assembly.
I have a question concerning the structure of an MVC application. Suppose we have to realize a web-based application composed by several modules, such as shopping cart, store browser(end-user), store manager(admin) and so on.
It is of course possible to create one controller and use the routing to submit the requests to a specific controller's action method. However this would make the code quite messy and hinder the practice to vertically structure the application, namely to identify and distinguish which views, models and controllers are involved to fulfill a specific requirement (an example is given by Phil Haack).
Another approach is to use one controller for each application section, for instance one controller made available for end-user operations, another for the store administrator, another one for queries made by the shipping department and so on. The drawback to this approach is to have too many controllers that mess up your code, too dedicated for specific tasks and so difficult to reuse.
According to this two extreme situation, what is the best way to organize your controllers and routing policies? Do you use a structured approach or it depends on the type of application you are developing?
Thanks
Francesco
It is of course possible to create one controller and use the routing to submit the requests to a specific controller's action method. [...]
Another approach is to use one controller for each application section, [...]
You're overlooking a third alternative, which is the most common one. In general you should have one controller per resource. A resource is a model that is publicly exposed. In your specific storefront application, the resources would be things like Products, Orders, Customers, etc.
This is typically the proper level of abstraction, because controllers usually don't need to know about models other than the resources they touch. A controller that touches more than one resource should be viewed with some skepticism, since it's violating the single-responsibility principle.
You should try to follow REST as much as possible
Basically - that means controller for each 'collection' (Your entity).
If Your controllers will be RESTful, other parts (routing, views) will fit themselves accordingly.
Hey guys - here's a question on Zend Framework or better on MVC in general:
I am asking myself for a quiet a long time now, if it is a good idea to push business objects (User, Team, etc.) to my views or if it would be better just to push dump data containers such as arrays to the view for rendering.
When pushing business objects to my view I have a much tighter coupling between the views and my domain model, however, the view could easily do things like foreach($this->team->getUsers() as $user) { ... } which I personally find very handy.
Providing domain model data in dumb arrays to me looks more robust and flexbile but with the costs of that the view cannot operate on real objects and therefore cannot access related data using object's method.
How do you guys handle that?
Thanks much,
Michael
It's better to make your View access a Domain Model object in an object-oriented manner, instead of using the Controller to convert Model data into plain scalars and arrays.
This helps to keep the Controller from growing too fat. See the Anemic Domain Model anti-pattern. The Controller only needs to know what Model to instantiate, passes the request inputs to that Model, and then injects the Model into the View script and renders. Keep in mind that a Domain Model is not a data-access class.
You can also write View Helpers to encapsulate a generic rendering of a Domain Model object, so you can re-use it in multiple View scripts.
Your View should accesses the Domain Model only in a read-only manner. View scripts should not try to effect changes to the Domain Model.
You can also design your Domain Model to implement ArrayObject or other SPL type(s), as needed to make OO usage easy in the View script.
It's true, a large driving motivation of MVC and OO design in general is decoupling. We want to allow each layer to remain unchanged as the other layer(s) are modified. Only through their public APIs do the layers interact.
The ViewModel is one solution to abstract the Model so that the View doesn't need to change. The one I tend to use is Domain Model, which abstracts the details of table design, etc. and supplies an API that is more focused on the business rather than the data access. So if your underlying tables change, the View doesn't have to know about it.
I would expect that if there's a change to the Domain Model, for instance it needs to supply a new type of attribute, then it's likely that your View is changing anyway, to show that new attribute in the UI.
Which technique you choose to decouple one layer from the others depends on what types of changes you expect to be most frequent, and whether these changes will be truly independent changes, or if they will require changes to multiple layers anyway.
The "standard" approach would be to completely prepare the model in the controller (e.g. fetch all teams, including users) and then send that to the View for presentation, but you are not bound by that. The data structures can be whatever you want it to be: Array, ArrayObject or custom Classes - anything you deem appropriate.
I dont use Zend framework, so this is in repsonse to the general MVC Have a look at the ViewModel pattern.
http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/29/how-we-do-mvc-view-models.aspx
I'm comming from a .Net MVC point of view but I believe the concepts will the same.
I will do all my view rendering in the controller bascially like below
model only output dataset/objects (this should contain the most code)
controller assign view and add necessary HTML and make use of models
view only contains placeholder and other presentation stuff and maybe ajax call
So my team can work on each part without interrupting each other, this also add some information security to the project i.e no one can retrieve all the working code they only communicate by variables/object spec.
I've done a fair amount of work on MVC on the web, and we're learning about it in my OOP class. I'm seeing some differences, and I can't tell whether that's because the Web's version of the MVC pattern is different than the traditional one, or whether I misunderstood it.
From my understanding, The model (your flat files, RDBMS', etc) is a generic data-housing object. The View (Browser, HTML, etc) is what the user interacts with, and the controller mediates between the users actions and the data. The controller is the most domain-specific part, and it manages the views, tells the model what it needs, and tells the views what to display.
In class, we have the Views matching what I just described, the Model contains a list of the views so that it can update them when the data changes, and the controller simply maps the user's actions to calls to the model and to specific objects (which may themselves, ask the model to update the views). What ends up happening is that most of the business logic is in the model, and it's tied very heavily to the simulation or application that is being written, while the Controller is reduced to a mapping tool between commands and methods.
What are your thoughts on this?
In a non-web interface the controller handles the inputs from things like the keyboard and mouse, choosing which views to render and what changes to make in the model based on those inputs. The view and model can be more closely related because the view can register callbacks directly with the model entities to be notified of changes and thus be updated based on changes to the model directly instead of being updated by the controller.
In the web world, views are necessarily more decoupled from the model. It must act through the controller actions because it has no direct access (after being rendered and delivered to the browser) to the model. The controller takes a larger role in this environment even though the only "input" it has to deal with are browser requests. In a sense, the coupling that used to occur with the view in non-web MVC is transferred to the controller acting on its behalf. Since there are no callbacks from the model to respond to (let's forget about "push" technologies for now), more business code is incorporated into the controller since it's the natural place to model business processes, though perhaps not validation.
In my understanding controllers in the web MVC pattern are just bridges between Models and Views, they simply grab the data from the Model and pass it on to the View. The Model and the View and independent and never talk to each other.