Slightly confused about MVC pattern - model-view-controller

I have almost completely understood the MVC pattern, but there is one thing that still confuses me:
Let's say - for the purpose of this example - I have got a controller, a model and 5 views. Whenever the model changes, I would like to (optimally) change a (proper) subset of these 5 views as a result of changes in the model.
What would be the right way to do it ?
My understanding of MVC as of now is that the model should not know anything about either controller or view. Does that apply to the view as well ? I.e. does the view also not know about controller AND model ?
Based on the assumption above, the proposal for my MVC program with the given requirements would structurally look something like this:
Pseudocode:
OPTION 1
MODEL
//Random data, no references to either controller or view
notifyObserver(){
observer.modelChanged();
}
CONTROLLER
reference MODEL
reference VIEW
var model;
var view1;
var view2;
var view3;
var view4;
var view5;
createController(m,v1,...,v5){
model = m;
view1 = v1;
.
.
.
view5 = v5;
}
modelChanged(){
view1.updateView(model.someVariable);
view4.updateView(model.someVariable);
}
VIEW
//no references to either model or controller
//some visual elements
updateView(var someVariable){
myVisualElement.change(someVariable);
}
TESTCLASS
main(){
create view1;
create view2;
.
.
.
create view5;
create model;
create controller(model,view1,...view5);
model add observer(controller);
}
So what I am basically doing with this, is letting the controller know about everything, while both view and model act completely independently. In this case, the CONTROLLER is the only one who gets notified when something changes in the model. It will then go ahead and change its views accordingly.
OPTION 2
So the VIEW would basically have a property/variable called model, that I will pass in with the constructor like this:
TESTCLASS
main(){
create model;
create view1(model);
create view2(model);
.
.
.
create view5(model);
create controller(model);
model add observer(view1);
.
.
.
model add observer(view5);
}
This way, all the views have references to the model and are notified by the model as soon as something changes.
I am confused because I am not sure which is the right approach... I hope you can help me understand this once and for all.

That's hard to catch what's the best solution for you and what you are actually asking for.
Which technology do you use, as dependently on a platform, there might be some specific nuances on MVC?
MVC basically don't have anything like observer.modelChanged and if you do use it, that adds certain limitations/possiblities on the inplementation details.
For instance, if you use mobile applications, you would rather have that MVC transformed to MvvM (Model-View-ViewModel) (where ViewModel would act rather as a Controller) and in that case the "Controller" would know only about Model, and View would know only about Controller (representing its Model partially).
If you use web application ((ASP.NET) MVC), you would have a Controller, which passes Models to Views (without knowing how actually the View works). Views would also know Model and adapt itself to it, but also getting in touch with Controller. At the same time, Model would not know about anyone of mentioned.

Related

Need expert's voice for mvc beginner about Controller & Model

I am quite new to MVC. I am having the following questions, please help me clarify those questions, thanks a lot.
Q1. Where should I populate my view model? e.g. My view model is very big, and contains a lot of the dropdown listbox, multi select list and the other few complex objects. I am currently populate them inside the view model self, by passing the model through the constructor, and load all the object data within the constructor. I also see my college populate the viewmodel inside controller. so I am confusing now, coz lots of people suggest to keep the controller small and skinny.
Q2. We are using the linq2sql as data access layer, should I use the table entity in my viewmodel instead of creating separate model class? Expert said it's bad, but if create seperate model class, I basically repeat them and I also need to copy those value to linq 2sql entity every time when I want to persist data, it's not that fun, too much work.
lots of people suggest to keep the controller small and skinny.
Yes. What people mean is that the controller should not contain any logic, except for model <-> view mapping. With model I mean the "M" in MVC.
Q2. We are using the linq2sql as data access layer, should I use the table entity in my viewmodel instead of creating separate model class? Expert said it's bad, but if create seperate model class, I basically repeat them and I also need to copy those value to linq 2sql entity every time when I want to persist data, it's not that fun, too much work.
No. You should not. Read my answer here: ASP.NET MVC Where to put custom validation attributes
Use a mapping framework for the model -> viewmodel conversion.
Update:
From what I understand, you suggest to assembly the viewmodel inside the controller (I mean call the business layer or repository to get my data) and use controller to call the business logic dealing with the data, am I right?
yes. The controller is really a glue between your business layer / repositories and your views. The views (and view models) should know nothing about them and the business layer / repositories should know nothing about the controller/view.
The controller was created for just that purpose. To create an abstraction between the user interface layer and the lower layers. Hence the only code that should exist in the controller is to make that possible (and therefore following the Single Responsibility Principle)
If you start adding that logic into your view models you start to add coupling between the lower layers and the user interface layer. Doing any changes in the lower layers will therefore also affect all your view models (instead of just the controller
your viewmodel should be a poco, and should most certainly not be handling the mapping of the model. if you don't want to map your model to your viewmodel in the controller i would suggest you look at something like automapper. it makes it easy.
once you've mapped from your model to your viewmodel, any extra properties that need to be set such as your lists should be set in the controller.
as i stated previously, definitely don't tie your viewmodel to your current orm or table structure. you never know what might need to be refactored, and if you can handle it via an automapper mapping instead of changing your view and viewmodel then you've saved yourself a significant amount of time.

ASP.NET MVC: Where do you assemble the view model for a view?

From inside to outside, these are our MVC app layers:
MS SQL / Tables / Views / Stored Procs
Entity Framework 4.1 (ORM) with POCO generation
Repository
Service (retrieve) and Control Functions (Save)
Routing -> Controller -> Razor View
(client) JQuery Ajax with Knockout.js (MVVM)
Everything is fine until I need to create a single ViewModel for step 5 to feed both the Razor view as well as the JSON/Knockout ViewModel:
Header that includes all Drop down list options and choices for the fields below
Items - an array of whatever we send to the client that becomes the ViewModel
Since the Controller won't have access to the Repository directly, does this mean I create a service for each and every view that allows editing content? I'll need to get the POCO from the repository plus all options for each field type as needed.
It just seems redundant to create separate services for each view. For example, a viewModel to edit an address and a separate viewModel to edit a real estate property that also has an address. We could have a dozen forms that edit the same address POCO.
To make this question easier to answer, is allowing the Controller direct access to the repositories a leaky abstraction?
Well, so are your controllers going to have code that translates POCOs from Entity Framework into separate view model objects?
If so, then you should move that code to a separate class, and follow the single-responsibility principle. Whether that class is in the "service layer" or not is up to you. And whether you use AutoMapper or not is up to you. But these kind of data mappers should not be part of the controller logic; controllers should be as dumb as possible.
OK, now let's ignore the data mapping problem, and pretend you could always use your POCOs directly as view models. Then you would still want a service layer, because it would translate between
userService.GetByUserName("bob")
in your dumb controller, and implement that in a specific manner by returning
userRepository.Users.Single(u => u.UserName == "bob")
Putting these together, your UserController ends up taking in IUserService and IUserDataMapper dependencies, and the code is super-dumb, as desired:
public ActionResult ShowUserPage(string userName)
{
var user = userService.GetByUserName(userName);
var viewModel = userDataMapper.MakeViewModel(user);
return View(viewModel);
}
You can now test the controller with stubs for both dependencies, or stub out IUserDataMapper while you mock IUserService, or vice-versa. Your controller has very little logic, and has only one axis of change. The same can be said for the user data-mapper class and the user service class.
I was reading an article this morning that you might find somewhat illuminating on these architectural matters. It is, somewhat condescendingly, titled "Software Development Fundamentals, Part 2: Layered Architecture." You probably won't be able to switch from a database application model to the persistent-ignorant model the article describes and suggests. But it might point you in the right direction.
i personally always inject the repository/repositories into the controller. i'm not sure why you would want to have a service layer between the repository and the controller. if anything you would use specifications.
once you've done that, check out automapper. its a mapper that, once properly configured, can map your domain model to your viewmodel, and back again.

Would you create a View Model if it was the same as other pages?

Thanks to previous answers, I have now written View Models and really like this concept, however, there are points in the application where the View Model will be the exact same as the (Not sure on the term..) real model.
Now in this situation, I understand that a View Model is best as one day, I may change the application logic, and it makes the application more robust.
However, a situation I have now is where I have a multiple pages that are very closely linked to each other and all need the exact same Model. In this situation, would you use the same View Model or just create a separate identical one for each page?
Are they exactly the same? In my opinion, if they are exactly the same you should reuse the ViewModel. Why create the same ViewModels twice whose functionality is basically the same. However, you should be careful that there are no service calls being in ViewModel constructor because, you may not need the exact same service calls for all views. In that case your calls are wasted even though you do not require it. In such a case make a public method in ViewModel like :
public void DoServiceCallsForViewA()
{
ModelObj.FooA();
}
public void DoServiceCallsForViewB()
{
//your calls for view B
ModelObj.FooB();
}
Then in your viewA you can typecast the DataContext,
((YourViewModelName)DataContext).DoServiceCallsForViewA();
and in your viewB you can write :
((YourViewModelName)DataContext).DoServiceCallsForViewB();
ViewModels should be simple data vehicles between views and controller actions (just a list of properties). If they are simple lists of properties in your app you can use Automapper to make your eventual decision on this fine detail less important.
...not to evade the question, I would stick with one ViewModel definition while the views are demanding exactly the same data shuttle and be ready to create a new ViewModel when one of those views needs something ever so slightly different.
There is no need to duplicate except to make your view:action mappings obvious, but weighing the obvious mapping against violation of the DRY principle seems like a straightforward decision...
The way I see it, your Model instances should each have an associated ViewModel. That is to say, you should have a 1:1 relationship betweel Models and ViewModels. You are however free to bind multiple Views to the same ViewModel.
Say, for example, you have a Person object, and a PersonViewModel, and then two different Views relating to that Person, say a PersonEditView and a PersonDetailsView. You should put all the neccessary properties for both PersonEditView and PersonDetailsView into PersonViewModel. Then use a DataTemplateSelector to choose which View should be displayed for the ViewModel at which times.
The each ViewModel instance should be a representative for a single Model instance, and it should be the only representative for that Model instance.

Where does Zend_Form fit in the Model View Controller paradigma

The Zend Framework is mainly meant for MVC use. One of the very usefull components is Zend_Form.
I have a bit trouble finding the place of Zend_Form. Is it part of the view, model, or controller and which responsibilities should I give it.
The thing is, Zend_Form does two things: decorate and render the form and validate it. The first is a real view task, the second a real model task.
Now the most common use seems to be to have the forms interact with the controller only, effectively putting both tasks (rendering and validating) to the view/controller.
Another option given by Matthew Weier O'Phinney is to attach the form to your model, and adding the later view options in the controller.
So, I'm doubting. Where in the MVC pattern should I place Zend_Form and how should I use it?
Edit Good answers so far, thanks! I will be awarding the bounty an hour or two before it expires, so please give an answer if you have some more thoughts!
Zend_Form can be viewed at different points. It can't be considered at all as part of just one layer of MVC pattern.
First of all Zend_Form use decorators and view helpers to render the form, at this point it is part of view layer.
Then, Zend_Form does part of the model job filtering and validating the content.
We know that Controller layer render input from the view and pass it to the model. Actually, the controller layer decide which resource to load from model layer and then perform the corrects calls.
When you call Zend_Form from controller layer, you can consider that you are calling one model resource to perform valitations and filtering actions and decide whether or not this is a valid input. For example:
public function newAction()
{
$form = $this->getForm();
if($this->getRequest()->isPost())
{
$formData = $this->_request->getPost();
if($form->isValid($formData))
{
$Model = $this->getModel();
$id = $Model->insert($form->getValues());
}
}
$this->view->form = $form;
}
Tie Forms to the model can be considered a good pratice because when you are performing filtering and validation actions you are on model layer. So, as Matthew proposed:
class Model_DbTable_Users extends Zend_Db_Table
{
protected $_name = 'users';
protected $_form;
public function getForm()
{
if(!$this->_form)
$this->_form = new Form_User();
return $this->_form;
}
public function add($data)
{
$form = $this->getForm();
if(!$form->isValid($data)) return false;
if($form->getValue('id'))
{
$id = (int) $form->getValue('id');
$this->update($form->getValues(), 'id =' . $id);
}
else
{
$id = $this->insert($form->getValues());
}
return $id;
}
}
From the standard directory structure we can see that Forms aren't in the model folder nor in the view folder because Zend_Form is a specific class that tie many resources and layers together. If you check the Matthews post you will realize that this is exactly what is being said when the action url is set on the view script and the form is tied to the model.
Finally, you can analyze your context and pick up one of these two approachs.
Currently, my choice is to tie forms to models. Looks nice! And make a lot of sense to me.
IMO, Zend_Form is designed to wear multiple hats. It is, in fact, a bridge between the view and model with a giant support beam from the controller.
Instead of assigning a Form to a Model, consider assigning Model(s) to a form.
In the Model layer, you can have a a getFormInputs method that could return the Elements needed to input data. The model doesn't care what form is going to use it, it just makes it available to any from that wants them.
Now in your form layer, make a setupInputs method that will loop thru an array of models to grab all the inputs. If there was only one model, add the inputs to the form. If there was more then one model, make sub forms.
Your controller will initiate the form and pass the values back to model (see Keyne's newAction method)
Zend_Form does often feel like the odd man out. I think everyone's mileage varies.
Lately, most of my administrative interfaces have been very drag + drop AJAX-y, and they require a good deal of html and javascript - actual form elements are sparse. So I chose to eschew a lot of the features of Zend_Form and use it as a fancy view helper with filtering. All my validation is done on a separate layer in the model.
I think O'Phinney's idea makes a lot of sense as well. Here, he's choosing to think of the form almost as a component of the domain object - where he can add business logic. This sounds just fine, as long as you're careful to keep all the view logic for the form separated. As he notes, it's about making semantic sense. There isn't necessarily a hard and fast rule.

MVC: pass model / model data to a view from a controller?

If a view needs to acces data from a model, do you think the controller should:
a) pass the model to the view
b) pass the data of the model to the view
c) neither; it shouldn't be the controllers concern. Let the view access the model directly to retrieve the data. Only let the controller give some parameters the view needs to filter the data from the model.
d) it depends on the situation.
e) none of the above, but [...]
Thanks
After some debate in the comments to an answer that was deleted by the user, maybe this needs clarification. My view of the MVC architecture is biased towards that of the Zend Framework (php) in which an action in a controller by default has a default view assigned to it. So it's not so much the model that dictates which view is approporiate, but rather the controller. Do you feel the model should dictate what view is appropriate? The only way I see fit to let the view be build based on a model, is by letting the controller pass the model to the view. Are there other techniques to let a view access a model without the controller being involved? Or is it perfectly fine to let a controller pass the model to a view, so that the view can be build based on the models attributes?
e) None of the above; pass in a view-optimised "ViewModel".
Example in ASP.NET MVC:-
public ActionResult Details(int id)
{
Product p = ProductService.GetProductById(id);
if(p == null) { return RedirectToAction("Index"); }
ProductViewModel model = new ProductViewModel(p);
return View(model);
}
both a) and b) "will do" subject to d). Never ever c).
Typically, the ViewModel just encapsulates the Model (if nothing complicated is going on, your view could access the model directly via ProductViewModel.Product). If the view needs to do anything complicated with the Model however, it's the ViewModel's responsibility to do that, rather than the responsibility of the Controller, or the View.
This keeps your concerns nice and segregated. Your Controller doesn't care exactly what specific data your View needs (beyond the fact that it's rendering some Details of a Product), or especially what format your View needs that data in. Your View doesn't depend on the implementation details of your Model. Your Model doesn't have to concern itself with how it's being Viewed. If you have two Views rendering Products (e.g. Create, Edit, Summary, MoreDetails etc), those Views can have different ViewModels to expose only the data that each specific View needs, so your Views aren't depending on eachother. Lovely :)
Some further reading from various viewpoints:-
http://www.thoughtclusters.com/2007/12/datamodel-and-viewmodel/
http://stephenwalther.com/blog/archive/2009/04/13/asp.net-mvc-tip-50-ndash-create-view-models.aspx
http://www.nikhilk.net/Silverlight-ViewModel-MVC.aspx
I think ViewModels are a particularly .NET thing, but I see no reason at all why the pattern can't be used in PHP.
Hope this helps.
Ideally, it should "pass the data of the model to the view" so the view doesn't need to know any explicit structure of the model and thus be more reusable and designer-friendly.
But practically, "pass the model to the view" works as just fine. Most of the time you will need a new view anyway because clients never share favorite colors (if you know what I mean :-) so views re-usability doesn't justify having a lot of tedious code required to copy data from the model to the view.
What you should concern more about is the modularity of the controller itself, since many websites do share common functionalities (controllers) such as web forums or a news listing but not looks (views)
This is late I know, but I'm having this issue on a project I am working on. I started with a) - for simplicity - and now running into road blocks.
I am coming around to this method:
e) None of the above; pass in a view-optimised "ViewModel".
because it avoid bloating both your model classes (instances of which are "transaction objects") and your views. For example, you may need to render a number with a specific number of decimal places (this is the problem I am having now).
With an intermediate "ViewModel" this is easy - you just write the relevant ViewModel "getXXX" method to return the number formatted how you wish.
If you just pass the model directly into the view, you will need to specify it in the view every time you use this figure (going against DRY - don't repeat yourself), or alternately, add a rendering method to your model classes (which goes against a class being for one purpose only).
Cheers
a) pass the model to the view
Otherwise the controller is manipulating the view via screening the model. This is what would happen in "b) pass the data of the model to the view". The b) option doesn't really even make sense in the pure MVC pattern. After all, the model IS the data. If the model is changed for consumption, a view has been applied, whether you choose to do it in the controller and pass it off as a controller function. What happens when you have a different view? Does the controller screen its data differently? You soon have two views for model, the controller sub-view and the view itself.
For me that's e).
As already mentioned here, ideally the view and the model are decoupled. The way I prefer to implement this is to have a viewHelper for a model. This has the API the view can use to get the data. Now views are not affected by changes in the model and the view doesn't need to 'get' the internals of the model. These are hidden away by the viewHelper.
example:
class Post {
public function export(ViewHelper $helper) {} // I try to avoid getters when I can
}
class PostViewHelper {
public function getTitle($parameters) {} // title of current post in the loop
}
class PostView {
private $helpers = array();
public function loadTemplate($path) {}
public function addHelper(ViewHelper $helper, $name) {}
public function __get($key) {} // if exists $this->helper[$key] etc
}
in a template
<h1><?php $this->post->getTitle(); ?></h1>
You may want to implement this differently. But my point is in how the view and the model are decoupled, introducing an intermediate viewHelper wich creates the view/template API.
I don't think it's that complicated. a or b.
The controller's job is to manage the relationship. It finds the model and view and provides the view all the model data it needs to do its job. That's it. MVC doesn't dictate the exact form the data takes.
(a) Start simple. It's pretty natural to pass the model objects directly to the view. If you have a page about a Foo, just pass the Foo.
(b) But at times-- and only at times-- you create a value object / DTO to get the data to the view (called a ViewModel above). Do this when there's a mismatch between the view and the native model, such as summary views. If the view is presenting a summary of 1,000,000 objects, you don't want to hand the view the model objects; you want to hand the view a summary of the 1,000,000 objects.
And the exact implementation really depends on the language and framework you are using. But I think these guidelines are a good start.
uhh b.
i dont really see the difference between a and b other then some technicallity of how you will be passing data.
usually you pass a map of data to the view with some data from the model

Resources