views:

259

answers:

5

Lately I've been trying to improve upon/move away from the standard MVC setup for web development, and I thought it was about time to throw my ideas at StackOverflow.

The general flow is the same in that a bootstrapper creates the initial objects. The difference is that these are then kept in a ServiceManager.

Then, instead of dispatching a controller, it loads the view.

The view then calls Commands and Queries. Commands represent functionality that is generally form-related (updating database rows, generally), and Queries are what normally would be ModelPeers. When these are created (via the ServiceManager) they have the ServiceManager passed to them, which gets rid of the need for a lot of potentially complicated dependency injection.

The models themselves would just do create/update/delete on a single row.

So a view would look like:

ListUsers.php

<?php $users = $this->ServiceManager->get('Query\User')->getNewestUsers(10); ?>

<?php foreach($users as $user): ?>
....
<?php endforeach; ?>

UpdateUser.php

<?php $this->ServiceManager->get('Command\User')->update(); ?>

<form>...</form>

I know that there's some tier violation, but it seems a lot cleaner than having a bunch of controllers that act more like ViewVariableSetters than anything.

It also makes everything much more testable since all functionality is encapsulated into Commands and Queries and away from large controllers. Technically, I could have a controller or ViewVariableSetter, but it seems like it would add a lot more code with very little benefit.

Any feedback would be appreciated, and please let me know if I can clarify anything.

+3  A: 

You will feel that little benefit once you add another developer to your project and when your project goes bigger and bigger. You'll be thankful you separated the view from the controller and from the model.

Randell
Commands/Queries are already separated. The only thing in the view is the calls to them.
whichdan
@whichdanYou might have what's known as a "Passive View" MVC if your previous comment was any indication:http://martinfowler.com/eaaDev/PassiveScreen.html
Nolte Burke
A: 

How will you adjust the view to accomodate to different formats? Eg html response, json response etc.

koen
I could just print JSON or XML and set the header content type.
whichdan
There needs to be an object that takes the request and decides with 'view'/response you will be sending.
koen
The router can take care of that.
whichdan
You're going to mix responsabilities.
koen
+3  A: 

If you don't like MVC, you could look at its siblings MVP (Model-View-Presenter), PM (Presentation Model) and MVVM (Model-View-ViewModel).

In fact, what you describe may be PM, I'm not sure.

R. Bemrose
M-V-PM does sound very close to what I'm doing. I'm concerned about having too many classes though, because especially with smaller web apps, you could end up having to change 3-4 files for something relatively simple.
whichdan
Dan, do you anticipate this being a general approach, or is this a single site you're thinking about?
Paul Nathan
General approach. I'm going to be applying this to multiple web apps with different size/scope.
whichdan
well, that's the engineering tradeoff: a "full" approach with a small webapp is going to result in a heavy relative overhead for changes.
Paul Nathan
That's true, but when we have Commands, Queries, Views, Controllers, Models, Validators, Facades for the validators, and a few other classes sprinkled here or there, setting up something as simple as a form could take 5-10 classes/files alone. Since I'm usually the primary developer, with maybe one or two other people working on the code, I'd like to avoid too much code bloat.
whichdan
Welll.....that's your tradeoff. :) Personally, I'd be thinking about a parsimony approach: "what is the minimum effort needed to achieve your goals". If you can do it all in one small file - why not? (there are good reasons not to, for many situations. But ask yourself Why Not for each project. :)) http://www.philosophyprofessor.com/philosophies/parsimony-principle.php
Paul Nathan
Most of my projects share common functionality (user system, auth, routing, etc) so it's much easier to find a common ground for everything!
whichdan
+1  A: 

One good start here: making reusable / modular code to be called from a controller, rather than the giganto monolithic controller.

My opinion: perhaps the problem is not so much "MVC", as current dogma about the "V" (view). Current dogma seems to be that the view must be a (HTML) template, in which code has to be woven into an "object d' art". One could argue that for many applications, this is just make-work.

Perhaps we need better / alternate "view" technology: when setting up a CRUD edit task, as opposed to a marketing kiosk (which should be a work of art), we make an API to generate forms and other UI elements using a "DOM" model like javascript in the browser (or like java AWT)? Just a thought.


In response to comment:

"... I want to avoid having a class that just passes stuff to a view ..."

First off, it should be doable to make this a minimum amount of code when it is a minimum amount of work. For instance, I like how "Rails" automatically routes requests within a certain "region" of the application into a class, mapping requests to individual functions/handlers. I've emulated this behaviour in java code, to keep responses more concise.

Second, this "passing info to a view" is just a specific instance of "calculate and store, passing data along a pipeline of simple steps". It makes code easier to understand and maintain. I'm not a hardcore "functional programming" fan, but there is something to be said for being able to (easily) comprehend the data flow in a piece of code. As a side benefit, it often (unintuitively, it seems) makes code actually run a bit faster as well. I've ranted about "locality" before, so I won't repeat it here.

Roboprog
I was thinking of using commands/queries from inside the controller, but again, I want to avoid having a class that just passes stuff to a view, which is what it inevitably ends up being in a lot of cases.Code generation could work but it seems like a lot of overhead when generally the HTML/JSON/XML really isn't all that complicated.
whichdan
A: 

MVC is a bit of a curious design for the web. Most of the time, you don't really need the separation between view and controller. On the other hand, because url's act as application state, you need some level of interoperability between the two. This leads to one of two scenarios; Either you only get a partial separation, or you get a lot of complexity. Neither is very beneficial.

I'd say that most frameworks choose a relaxed separation. Rails and its php clones generally follow this strategy. Personally I don't really see the point of that. A two-layered (eg. model/presentation) design can work well for the majority of applications.

There is something to be said though for using an industry standard - however wrong - simply because it's a standard. If you cook your own architecture up, other developers will have a harder time figuring it out. You shouldn't underestimate how much work there goes into getting something like that just right.

troelskn