views:

261

answers:

4

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

A: 

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%5Fbogard/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.

Pino
And here I thought coming from a ASP.NET background would mean you'd recommend the OP should move to stored procedures. :-)
cletus
Thanks much! I also think that a seperate ViewModel could make sense. However, I am afraid of doing all this extra work implementing additional "view types" to abstract the real business model just for the view. Partly, it's just looks like double-work to me. I am not sure if it is worthy to do. What do you thnik?
Michael
A: 

I will do all my view rendering in the controller bascially like below

  1. model only output dataset/objects (this should contain the most code)
  2. controller assign view and add necessary HTML and make use of models
  3. 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.

Dan
A: 

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.

See this similar question in Nabble

Gordon
+4  A: 

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.

Bill Karwin
+1. As long as your domain objects don't interact with the database or persist data in any way, I find it valuable to be able to execute business logic in my view. e.g. `$team->canAccept($user)` to decide whether to render a "join" button.
Richard Nguyen
Hey Bill - thanks for your feedback. I agree with you. The only thing that I worry about is that if the domain model changes. In fact it means that I have to change code in ALL layers incl. the views. Maybe this is as it is and cannot be avoided in genral. I am not sure. An alternative I had in mind is putting another (thin) layer between Controller and View, a ViewModel (see Pino's post also), that holds all view data in a structured, object oriented way instead of just having a "dictionary" as value storage which ZF offers by default. However, I am not sure if it is really worth the work.
Michael