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

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.

Related

Is there a downside to validating data through a static method of the Model in an MVP setting?

I was recently reading about MVP, and at the end of the post the author starts to talk about Validation of Data. He mentions
I favour a single isValid() routine in the view.
...
An alternative approach, which is more in-line with the pattern, is to include this method in the interface and for the presenter to call this method (view.isValid()) before attempting to make changes to the model.
I don't think the validation should be handled in the View because it exposes more about the Model than the View should know, especially since we're trying to keep the View and the Model as separate as possible. Plus that method becomes redundant when you have multiple views referencing the same Model (e.g. a quick summary view vs. a more detailed view).
The Presenter has the most opportunity to validate the data, seeing as it is the bridge between the Model and View. I do like the "alternative approach", but I still don't like how it's using view.isValid. Plus I'm still not entirely sure if one presenter controls one view, or multiple view (a question for another time).
But one idea that did occur to me is to use a static isValid() method from the Model. You would call it in the Presenter, and the Presenter would pass all the relevant information from the View to the method. The method returns some form of valid or not-valid, maybe even specific enough to say which pieces of information aren't valid. To me this keeps all information relevant to the Model, within the Model, and accessible to Presenter, while keeping the View blissfully unaware of the Model.
Are there any shortcomings to this idea that other Validation practices solve, or is there any glaring downside to this method of Validation?

What is the advantage of Model-View-Controller (MVC) over Model-View?

Could anyone give an example of why it would be advantageous to use MVC instead of a simpler Model and a View only.
Note: whether it's called MVC or MVP (Model-View-Presenter), I'm talking about the one where the View receives input, then the Controller will respond to the input event by interpreting the input into some action to be done by the Model. When the model changes, the View will update itself by responding to events from the model.
What is disadvantageous of simply letting the Model respond to events in the View and vice versa?
In MVC, if I changed the model in a way that affects the controller then I'll have to do changes in the controller. In Model-View, if I change the Model, I'll have to update the view.
So, it seems like we are introducing complexity by adding the "controller" part?
In MVC, the Model is blind to its environment, the view can be too - passing off (blindly) its events to the controller, which knows more about the view and model. So when all is said and done, the controller is the 'non-reusable' disposable part of the system, since it is the most context aware component.
if I changed the model in a way that affects the controller...
The the model should expose simple CRUD methods in such a way that those using the methods do not have to know anything about the passed update object, nor what really happens inside the model.
This means that the view, IMO, has to do a bit of work by creating the passed record, since Controllers are supposed to be stateless and the view is more persistent. Controllers get triggered and 'kick-in' do their work with a passed object and do not have a state.
The passed data is created by some sort of generic convention.
Let me go even further. Suppose you have a view, a tablegrid, and a control whose enabled property is dependent on item is selected in the grid -- you COULD create a view that handles both those controls and this logic internally, and that would probably be the way to go in such a simplified example.
But the more atomic your views are, the more reusable they become, so you create a view for every, yes every, control. Now you are looking at a situation where views have to know about each other in order to register themselves for the right notification...
This is where the controller steps in, since we want to stick all these dependencies onto him, the long term disposable one. So the controller manages this type of view-to-view notification scheme.
Now your views are ignorant as they can be and independent, thus reusable.
You can code a view without having to know about the system, or the 'business logic' as they like to call it. You can code a model without having to know too much about your goals (though it does help to tweak the model to enable it to return the datasets you have in mind).... but controllers, they are last and you have to have the previous two firmed up before you can wire things together.
Here is another thing to think about -- just as the Model is supposed to abstract-away and provide a generic interface to the underlying implementation of the data it is managing (the client does not know if the data comes from a DB, a file, a program setting, etc) -- the view should also abstract away the control it is using.
So, ultimately this means a view should not (caveat below) have functions/properties that look like this:
public property BackgroundColor{get;set}
Nor
public function ScrollBy(x,y){}
But instead:
public SetProp(string name, object val){}
And
public DoCmd(string name, object val){}
This is a bit contrived, and remember I said ultimately... and you ask why is this a good idea?
With reusability in mind, consider that you may one day want to port things from WinForms to, say, Flex, or simple want to use a new-fangled control library that may not expose the same abilities.
I say 'port' here, but that is really not the goal, we are not concerned with porting THIS particular app, but having the underlying MVC elements generic enough to be carried across to a new flavor -- internally, leaving a consistent and ability-independent external interface intact.
If you didn't do this, then when your new flavor comes along, all your hard references to view properties in the (potentially reusable/refactorable/extendable) controllers have to be mucked with.
This is not to mean that such generic setters and cmds have to be the interface for all your views abilities, but rather they should handle 'edge case' properties as well as the normal props/cmds you can expose in the traditional hard-link way. Think of it as an 'extended properties' handler.
That way, (contrived again), suppose you are building on a framework where your buttons no longer have buttonIcon property. Thats cool because you had the foresight to create a button view interface where buttonIcon is an extended property, and inside the view your conditional code does a no-op now when it receives the set/get.
In summary, I am trying to say that the coding goals of MVC should be to give the Model and View generic interfaces to their underlying components, so when you are coding a Controller you don't have to think to hard about who you are controlling. And while the Controllers are being (seemingly unfairly) set up to be the sacrificial lamb in the long run of re-usability -- this does not mean ALL your controllers are destined for death.
They are hopefully small, since a lot of their 'thinking' has been shoved off into semi-intelligent Models and Views and other controllers (ex: Controller to Sort a Grid or Manipulate a TreeView) -- so being small they can be easily looked at and qualified for reuse in your next project -- or cloned and tweaked to become suitable.
It actually reduces complexity by separating the workflow logic from the domain logic. It also makes it easier to write unit tests and makes your application easier to maintain and extend.
Imagine if you wanted to add a new data type. With the approach above, you would probably duplicate a lot of the workflow logic in the new class as it would be likely to be tightly coupled to the domain logic.
The discipline involved in separating the workflow logic into the controller makes it more likely that you will have fewer dependencies between workflow and domain logic. Adding a new data type would then be more simple, you create the new domain object and see how much of the controller you can reuse, e.g. by inherited from a controller super class.
It would also make it easier to change frameworks in future - the model would probably not change too much and so would be more portable.
Having said that, you might want to look into MVVM depending on what you are using as your presentation layer: Benefits of MVVM over MVC
Advantages of MVC/P (I am talking about Supervising Controller here) over MV include:
You can handle complex data binding code in the controller, if required.
You can test that complex presentation logic without a UI testing framework.
You can also have a graphic designer make your views, and not see your code, and not mess up your code when they fix your views.

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?

Zend Framework / MVC: What type of objects to push to the View?

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.

Is The Web's version of MVC different than traditional MVC?

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.

Resources