{{{
People usually make me feel slightly embarassed when they ask things like *”How does Cells handle MVP?”* or, even better, *”Is there any MVP _implementation_ in Cells?”*.
Frankly, *I don’t have a fucking clue about the _real_ differences between MVP and MVC*. In the past I usually deflected people’s attention by buying beers instead or whatever. I hope to find some answers in the comments section, soon.
After actually reading a bit about “MVP, Presenters and Rails” I came to the following conclusions:
* There simply is *_no_ difference between MVP and MVC* (imho)
* Rails *_Presenters_ don’t implement the MVP/MVC pattern* completely (imho)
* And, *if Rails would be real MVC we wouldn’t need _Presenters_*. (imho)
As always, these theses are subject to discussion.
h3. The confusion about MVC and Rails
So the first problem “I already discussed in one of my recent posts”:http://nicksda.apotomo.de/2010/11/rails-misapprehensions-cells-dont-break-mvc/ is that *Rails encourages a very monolithic controller architecture* having one controller being responsible for a complete page.
As Rails is an opinionated framework, *their MVC-definition is absolutely ok for me*. However, this is not the _MVC_ known from GUIs – *usually you’d have multiple controller-view couples in your page UI*, each pair implementing complex elements like forms, menus or pageable lists.
But we already talked about that, I just wanted to point out that *this is the root of the mysterious MVP misapprehension in Rails*.
h3. MVP, where art thou?
Anybody *being seriously interested in GUI design patterns* read “Martin Fowler’s paper describing MVC, MVP, Presentation model and friends”:http://martinfowler.com/eaaDev/uiArchs.html.
To be honest, *I still did not understand the difference.* Luckily, Martin himself seemed to realize that it is “tremendously difficult to discern between the two patterns”:http://martinfowler.com/eaaDev/ModelViewPresenter.html, and *split _MVP_ into _Supervising Controller_ and _Passive View_* (“some people alleged that I’m a fan of the latter”:http://nicksda.apotomo.de/2010/10/why-rails-controllers-need-a-double-render/#comment-677, which I’m not!).
What I basically get from these excellent writings is that
“Presenters are a loose form of MVC controller. As a result a lot of designs will follow the MVP style but use ‘controller’ as a synonym for presenter.”
which I for myself cut down to *”MVP == MVC”* – at least in a Rails-like web development environment.
It just simplifies things.
h3. Presenters in Rails
In the past years a couple of *_Presenter_ implementations emerged and several clever writings* about that pattern popped up. I was happy to read “Dmytro Shteflyuk’s blog post about his presenter project”:http://kpumuk.info/ruby-on-rails/simplifying-your-ruby-on-rails-code/, although I disagree in some points (I’m an asshole).
The word _Presenter_ obviously refers to the _P_ in MVP, and in Rails they roughly work like this.
class ShowPresenter def top_videos @top_videos ||= Video.top.all(:limit => 10) end
After *defining the data aggregating code* you can use the presenter in your rendering layer.
@presenter.top_videos %>
So, we _retrieve_ data in the presenter and then pass it to the partial, right? This approach is of course a thousand times *better than collecting data for presentation in the view itself*.
h3. Help me! What’s a Presenter?
However, in my understanding of the “Supervising Controller pattern”:http://martinfowler.com/eaaDev/SupervisingPresenter.html (which seems to supersede MVP), we need two crucial parts in order to _be_ a Supervising Controller at all:
* a view to *display, well, data*
* a controller to *handle input response and complex view logic*
Please don’t get me wrong and correct me, I appreciate any approach different from Rails’ traditional VC-stack.
However, to me it seems that *presenters in Rails only handle the “complex view logic part”* (“collecting the videos to display”), whereas the monolithic @ActionController@ still renders the view and handles input responses.
Am I wrong here? *_Is_ the @ActionController@ _itself_ the Supervising Controller* which calls a presenter and then renders a view? I’m confused.
h3. Cells is truly MVC, but is it different from Presenters?
After all this confusion and hyperlinking I’d like to stand up for my own solution for this dilemma. Let’s comment Dmytro’s (maybe outdated) blog post where he *ponders the benefits of Presenter vs. Cells* telling us to use presenters whenever you
* have *too much logic* in views
* get into *trouble with already cached data* within views
* can’t *test an action* anymore because of its complexity
and to use Cells only when
* you need a *reuseable partial* with initialization code
Well, *I don’t agree* here. Cells do all the stuff presenters do, and more. That doesn’t mean you should use Cells everywhere in place of partials and Presenters, but nevertheless *comparing Cells and Presenters is discerningly*.
*Presenters are data aggregators*, whereas *Cells are autonomous MVC stacks* as claimed by the true MVC pattern. This is a bit like comparing controllers with ActiveRecord’s finder.
h3. Presenter gets Cell
Let’s see how the former example would look with a cell.
class ShowCell 10) render end cache :top_videos end
The cell would also contain a separate view in its namespace.
Note how simple the actual cell rendering in the controller is since *we handle cell caching _within_ the cell itself!*
Here, my top porns:
Can you see the difference?
* *Cells can aggregate and prepare data* just like presenters in their methods.
* They *keep their views separated*, taking away complexity from the monolithic controller
* Handling *caching within a cell* drastically reduces controller’s duties and is easier testable, too
* Both *data preparation _and_ rendering is testable* in a fine-grained cell scope
* Cells can also *inherit views from parent cells* which wouldn’t work with a controller+presenter approach!
By no means do I discourage usage of presenters! Use it, *as long as rendering the presented data in the controller scope is clear*. If it gets too complex (or if you need any other advantages cells have), use “Cells”:https://github.com/apotonick/cells.
h3. MVC, done right
One of my intentions was to show that *you don’t need _presenters_ if you have a true MVC framework with multiple controllers/views* – you can simply wrap data retrieval, rendering and optimization code (like caching) in a separate controller.
*That is how GUIs used to work for decades and how web based frameworks _should_ evolve.*
}}}
Plain old controllers, ESI and/or JavaScript may do widgets well enough.
LikeLike
@Nolan: How do you use ESI with plain old controllers? How’d you dispatch calls to ESI urls in the controller to a view component (complex view logic + partial rendering)? Can you make an example?
@Niko: Interesting, thanks! The Representers look as if they exactly do what they are supposed to do: Aggregating data with more or less complex decisions or logic. However, the more I think about MVP I think that the term “Presenter” is wrong here.
LikeLike
On our last Rails project we where happily using Floeres presenters (“representer”: https://github.com/floere/representer).
As far as my understanding of Fowlers presenter patterns go, they are different. They just provide an object oriented approach to cope with view logic: Representer instances usually derive from model instances and implement view logic as plain methods. So you can use @article.teaser in you view and depending on wether the Article instance is an instance of the CDReview subclass or the ConcertReview subclass it decides on what the teaser contains.
Representer don’t process incoming data (form posts, …) in any way.
If you’re spotting a lot of case/when statements in your view helpers: Give Representers a try and solve the flow control how it was meant by the OO gods – by using polymorphism.
LikeLike
I fully agree that there is some confusion with the presenter pattern in the Rails community.
I even wrote a blog post, which coincides with some of your thoughts: http://novembermeeting.blogspot.com/2010/03/miscomprehension-of-presenter-pattern.html
LikeLike
This article made me to spend 2 hours reading about MVP, and wtf is MVP…turns out the miscomprehensions are true π I found the same question on stackoverflow and a nice explaining answer also http://stackoverflow.com/questions/2056/what-are-mvp-and-mvc-and-what-is-the-difference
The presenter doesent handle server-calls – It’s the glue between the model and the view. I guess now I’ve learned at least something about MVP hehehe.
Nick, keep writing about advanced stuff – you are good at it π
LikeLike
MVC has a controller which fetches data, and passes it to the view. MVP has a presenter that a view delegates to to get its information. The (main) difference is that with MVC the entry point is the controller, with MVP the entry point is the view.
At the end of the day, just because a pattern exists doesn’t mean it is good, or fits your requirements. It does lend a bit more respectability to your designs, but that is about it. You shouldn’t be trying to defend yourself against people who say you are breaking mvc, you should be defending yourself against the people who say the complexity of this solution is worse then the problem (imo of course π )
LikeLike
@Matt, you are so damn right… Can you imagine how hard it is to stand up for a fucking cool gem that 100% improves Rails as it simply removes the paucity of reusable components, while you permanently get comments like “Plain old controllers, ESI and/or JavaScript may do widgets well enough.“?
LikeLike
i hate you…
LikeLike
Another approach to the whole discussion is this:
Often you’d like to show a list of items that are not the model. Or use a unified interface for model objects, like have a list_item method which renders a list item for the model object.
More often than not, something like this ends up in the model (violating MVC), or in a helper, as “if this then render this view, else that, render that view.” (not using Polymorphism).
That’s when you need a thin Proxy on the model objects: view models.
The explanation:
http://floere.github.com/view_models/
The github repo:
https://github.com/floere/view_models
Not that this is used for displaying and rendering things, and to make view methods on models as easily testable as on models.
All the best.
LikeLike