How should the MVC pattern work? - model-view-controller

I have searched and searched but got no answers: How should the MVC pattern work?
So long I got two examples out of many similar ones: one of them suggests that the view should be updated by the controller, but the model is directly updated by the view, and another one suggests that the model should be updated by the controller, but the view should be updated by the model.
I have learned that the view should display content from the model fetched by the controller, and the model content would be altered by the view and updated by the controller.

It's been a year, and I got no answers. Maybe because the question is kinda opinion-based, or maybe because it didn't get much attention.
But ever since then I searched and studied more and more about best practices and design patterns, and now I feel confident enough to answer my own question.
Q: So, how should the MVC pattern work?
A: It should work the way you design it.
The MVC pattern defines three vital types of components: the Model, the View and the Controller:
The Model is what holds and manipulates the data you're working with: it handles persistence methods (writing/reading or CRUD) and has all the properties that your file/database table has;
The View is what displays the Model in a human readable way: it binds his visual components' values to properties of the Model;
Finally, the Controller is what notifies the View of changes on the Model, or notifies the Model of changes on the View: basically it's a sort of messenger, notifying two parts of each others' actions.
Now, how's the usual data flow of a MVC application?
The user changes a component value on the view;
The View queries the Controller about the value that the user passed;
The Controller then notifies the Model that it wants data about the value that the View passed;
The Model interacts with the database and gets the corresponding values (if they exist). After that, it notifies the Controller that it finished whatever it was doing;
The Controller notifies the View that the Model has been updated;
The View updates its' components accordingly, changing whatever values that may have changed.
That was only the reading flow, the writing flow is similar but a bit different:
The user changes values on the View;
The View sends those values to the Controller, saying that data changed and it should be persisted;
The Controller notifies the Model about the data changes, and passes the message along;
The Model then updates the database with the new/updated data, and notifies the Controller;
The Controller notifies the View that the Model has been updated;
The View displays a message to the user, saying that the operation was sucessful.
Now, when I first asked this question, I was with a Java-heavy mindset, so I wanted to know how would I go about implementing this in Java:
DAOs and Java Beans. You write the views and the controllers, but the models are split between data objects (Beans) and persistence objects (DAOs);
Java Beans with embedded persistence methods. You write the views, the controllers and the models. The models are Java Beans that have whichever persistence methods you need (the most basic ones being insert, select, list, update and delete).
So, my final answer is: There's a lot of correct ways of implementing the MVC pattern. But there's a series of guidelines you should follow if you want your implementation to be correct.

Related

Spring best practice to separate model from view in controller and jsp?

Is it a good practice to use Spring Controller class(with #ModelAttribute) and the jsp to prepare model at the same time or the model has to be prepared only by Spring and the view from the jsp?
The idea comes from this topic . I have a Controller class:
#RequestMapping(value = {"", "/"}, method = RequestMethod.GET, params = "mode=create")
public ModelAndView showCreatePage(#ModelAttribute("createForm") ApplicationCreateForm form)
{
return customMethod("some string");
}
and in my jsp I have:
<jsp:useBean id="createForm" scope="request" class="com.example.ApplicationCreateForm"/>
I do not need to populate the form with the information to be present to the user all fields are empty.
So from what I uderstand I have been declared ApplicationCreateForm bean twice, with the same scope - request.
Is it a good design practice to use both at the same time? Is there a reason for that? Does the second declaration(in jsp) give me more power, for example to override the model or it is complete unnecessary? Does the second declaration overrides the first one when both are present?
There are many things wrong with this implementation.
Is it MVC?
If JSP know about Model, why do we need controller. Lets remove the routing engine and use JSP directly to consume Model. But then the application will be monolithic. I believe you do not want that. We have two major flavours of MVC. In both, controller is the front facing object. It receives the command, interprets it, works with data layer and gets Model. If required the Model gets converted into a viewModel and then this object is passed to the view.
Why viewModel?
Say we are implementing paging on screen. We are showing list of persons. Person is your model here but your view also need to know page number, page size etc. Your model thus may not fit directly in this case.
Say we need data from multiple tables to shown on screen. This data is related in some way. Now will you pass separate model objects to view and let it do all the business logic? Ideally no.
Should not the design support DTO or ViewModel or Commands and Queries?
We want our application to be designed properly. As stated above we need to send data to view or clients (REST) after processing. Processed data may not map to you domain until unless we are just creating a CRUD stuff. What if you want to implement CQS or CQRS?
Where is separation, where is SOLID?
If my view is performing business logic then where is 'S'? If view knows about model and need to be changed in slightest of changes in model then where is 'O'?What if I want to separate queries from command (CQS) and scale the two things separately?
To conclude I would say, yes you can do this but it is not good if you are developing a decent size application or you think it will eventually be one. I have seen people using model entities starting from ORM, to controller to view. It will work but the question is do you want a monolithic and tightly coupled application. As per my experience the presentation logic (view) has very different logic and need of data in comparison of controller and same goes for your data access layer.
I think you should prepare your model fully in spring controller. Then view should be as passive as possible, ie. only showing model attributes received from controller while having no further knowledge about application logic. This approach gives you clean separation of concerns and you view is as independent as possible and can be easily switched for different view technology - eg. thymeleaf or freemarker templates. The whole idea of MVC is to separate presentation layer and by leaking business logic to view you create unnecessary dependencies.
Your view should be as simple as possible, as the logic leaked to view makes it very hard to test and reuse. On the other hand, if your logic is nicely separated, you can test it easily and reuse it easily. Ideally, business logic should be completly independent on web environment.
By defining you are creating tight coupling between your view and class com.example.ApplicationCreateForm, using spring mvc you achive loose coupling between your controllers, view and model it might happen that you change you model name but you still have same properties in it which might be enough for view, in above case you will need to update your view but it won't be required in case you are using Spring MVC.
Since spring comes with the concept of making things loosely coupled to make your code more testable, you should always keep in mind that separation of concern is your priority. So it is always the best practice to prepare your model fully in Controller, not in views.
Keep thing simple , make your controller responsible for preparing your model, and keep your views to display the model only.
So, a big NO to your question. The second declaration isn't going to make you powerful, rather help you to be tied up.

On MVC, clarification on object responsibility needed

Suppose, as part of an iphone application, I need to show user a list of some of some objects.
The model
Represents actual objects to be shown
Brainless data, collection of getters and setters
The view
Displays the list, passes received actions to a controller
Presentation layer
The Controller
Interprets actions received from the view and takes actions on data
Sits between the view and data
In this picture, would be be controller's responsibility to persist model to disk, or, should it be a part of Model's logic? Request to do this will come from a controller, but, should the controller know how to save data to disk, or should data know how to save itself to disk?
This is wrong.
Model is responsible for all the business logic. Additionally model is not directly aware of database or any other data storage medium. When model is initialized it receives factory for creating DAOs or DataMappers which are the ones responsible for storing and retrieving the informations.
Controller interprets the received information from view , and changes the state of model and view.
View either receives information from a persistent model via observer pattern ( classical MVC ) or request data from models ( Model2 MVC ).
I can see this going both ways. I would think that this logic goes into the model this way the controller is a little cleaner. Also, if you're using this functionality across models and it's mostly consistent e.g $person->saveData(), $user->saveData() then you could possible extend the base model so it would be inherited by other models and save you from duplicate code.
If this logic is incorporated into the model it would probably be a good idea to make it flexible enough so that the controller can override the persisting of data. So maybe, pass an argument into the model function $person->save( false ) This false would prevent the model from persisting the data but on default would be true.

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.

MVC: Are Models and Entity objects separate concepts?

I asked here a while ago for some help in understanding MVC, since I'm very new to the topic. I thought I had a decent understanding of it, and this is documented in a blog post I wrote recently on the subject. My understanding basically boils down to this:
Controller: Determines what needs to be done to fulfill a request, and utilizes whatever models it needs to collect/modify as needed. It's basically a manager for a given process.
Views: Presentation only. Once a controller collects what it needs, it creates a specific type of view, hands it the information, and says "show this to the user however you do it."
Models: Behavior of the application. When the controller asks it to extract or modify something, it knows how to do it. It also knows to trigger other models to do related tasks (in my understanding, when a model tries to "vote for something" on StackOverflow, that model knows to ask if a badge should also be granted because of it. The controller doesn't need to care about that).
My question, assuming all of that is more or less accurate, is where do entity objects come in? Are models and entities the same thing, with each object knowing how to persist its own data, or are entities a separate concept that exist on their own and are used throughout the application?
My money is on the latter, since this would allow models to act independently, while all three layers (model, view and controller) could utilize the entities to pass data around as needed. Also, objects and database persistence seem like concerns that should be separated.
To be honest, the more I read about MVC the more confused I get. I'm about ready to just take the core concept (separate presentation from logic) and run with it in whatever way feels right, and not worry too much about the "MVC" label.
Yes!
My money is on the latter, since this would allow models to act independently
You don't want to bind your view to an Entity, because if the view also needs some other piece of data, you would have to it to your Entity. The model is entirely supportive of the view, and is concerned with supporting that view and nothing else.
For example, you show a list of your entities, what other data might you need? Current page number? Total number of pages? A custom message to be displayed?
This is why you should bind to a model, which you can freely add data items to as you need to.
Update
Here is an explanation of MVC in action...
The controller gets all of the data required for the request and puts it into the model. It then passes the model to the view.
The view then deals with the layout of the data in the model.
Each Model can be one entity that contains some methods to control and use its data.
Is it enough?

Can any processing be done on the model? [MVC]

I've decided to make a big push towards MVC for all new sites I make. I have a question about whether or not you can have any processing on the model level.
The case that brought up this question is a video site. I have a Video class (model) and one of the things I need to do when a user views the video I need the view to be logged in the database. I'm not sure if I need to add a query in the controller or if I can add a addView method in the Video class.
The basic underlying question for me is what kind of methods am I limited to in the models? Can it be anything or does it have to be only accessor (a.k.a getValue/setValue) methods?
Ruby on Rails has the motto skinny controller, fat model. This doesn't apply to just Rails and should be practiced with any mvc framework.
I think your model is exactly the place to handle this. Now, your model is necessarily composed of just your entity classes. Your model, in my opinion, would include your entities as well as any business logic that you need to implement. Your controller should just be handling I/O for the view, invoking model methods to accomplish the actions invoked by the user via the user interface (view).
Here how I would do this. It should be valid in pretty much any language.
The View would initiate a method call to the controller's OnView() method, then display whatever the controller spits back to it (in a controlled way, of course... I'm thinking your view is going to contain a video player component, so you're going to get a video of some kind back from the controller)
In your controller, have a method OnView() that does 3 things: instantiate the Video object (i.e. uses your data layer to get a model object), call the updateViewCount() method on the Video object, and display the video (by returning the Video object to the View, presumably).
The Video model object contains data representing your video and any houskeeping stuff you need, which includes updateViewCount(). The justification for this is that a Video has a view count (aggregation). If "view count" needs to be a complex object instead of just an integer, so be it. Your data layer that creates Video objects from their primitive representation on disk (database?) will also be responsible for loading and creating the corresponding view count object as part of the creation of the Video.
So, that's my $0.02. You can see that I've created a 4th thing (the first three being Model, View, and Controller) that is the data layer. I don't like Model objects loading and saving themselves because then they have to know about your database. I don't like Controllers doing the loading and saving directly because it will result in duplicated code across Controllers. Thus, a separate data layer that should only be directly accessed by Controllers.
As a final note, here's how I look at views: everything the user does, and everything the user sees, should go through the view. If there's a button on the screen that says "play", it shouldn't directly call a controller method (in many languages, there's no danger of doing this, but some, such as PHP, could potentially allow this). Now, the view's "play" method would just turn around and call the appropriate method on the controller (which in the example is OnView), and do nothing else, but that layer is conceptually important even though it's functionally irrelevant. Likewise, in most situations I'd expect your view to play a video stream, so the data returned by the controller to the view would be a stream in the format the view wants, which might not necessarily be your exact Model object (and adding that extra layer of decoupling may be advisable even if you can use the Video object directly). This means that I might actually make my OnView method take a parameter indicating what video format I want to get back, or perhaps create separate view methods on the controller for each format, etc.
Long winded enough for ya? :D I anticipate a few flames from the Ruby developers, who seem to have a slightly different (though not incompatible) idea of MVC.
Since you can use whatever model code you want with MVC (not just limited to LINQ) the short answer is yes. What should be done in the model is perhaps a better question. To my taste, I would add a ViewCount property (which probably maps to a column in the Video table, unless you are tracking per user in which case it would be in the UserVideo table). Then from the controller you can increment the value of this property.
With MVC, people seem to be struggling with fitting four layers into three.
The MVC paradigm does not properly address the data storage. And that's the "fourth layer". The Model has the the processing; but since it also addresses the data, programmers put SQL in there, too. Wrong. Make a data abstraction layer which is the only place that should talk to back-end storage. MVC should be DMVC.
Keep in mind, there are many variations on MVC and no real "right way" to do things. Ultimately, how you design your classes comes down to personal preference. However, since you asked for design advice, here are my two cents:
Business logic belongs in the controller. Keep it out of the model and view.
Out of the many variations on the MVC pattern, the passive view style seems to be the easiest to test. In the passive view, your classes are designed as follows:
Your controller is "smart: it makes changes to the database, updates the model, and syncronizes the view with the model. Apart from a reference to the model and view, the controller should hold as little stateful information as possible.
The model is "stupid", meaning it only holds the state of the view and no additional business logic. Models should not hold a reference to either the view or controller.
The view is "stupid", meaning it only copies information from the model to the UI, and it invokes event handlers which are handled by the controller. The view should contain no additional business logic. Views should not hold a reference to the controller or model.
If you're an MVC purist, then it would not make sense for the model to update itself or the database since those responsibilities belong to the controller, so it would not be appropriate to create an addView method to your Video class.

Resources