Saturday, January 10, 2015

Pudgy controllers? Try the Route diet!

Nestled between user and controller, the routing layer is a perfect home for common filtering and access-control oriented code. But you have to know your framework's routing capabilities to exploit this location. In this article, I share a users' group presentation on the supple Laravel 4 Route facade.


"Fat model, skinny controller" guides developers to push excess controller code down into the model. But there is another choice: up into the routing layer. A framework's routing layer mediates data flow between user and controller logic. Quality frameworks offer a supple routing layer, one that is both thin (for fast processing) and flexible (for extending to meet an application's need).

Routing in Laravel 4

Of the frameworks I've used, Laravel's routing layer is the best. If you have never used Laravel or are a Laravel developer who doesn't make much use of Route, I encourage you to try it, then mine it for all its riches.

To kick-start your exploration, here is a user group presentation on Route.

Open the presentation "Routing in Laravel"

Soapbox: "Fat model, skinny controller" considered harmful

In his blog, Jon Cairns advocates for "skinny everything":
No class should be fat. Ever. There is no need for your controllers, models or views to be fat; this shows laziness, as there's been no thought given to the application's design outside of deciding to use a particular framework.
I agree. Resting glibly on "fat model" guideline, junior and senior coders alike generate not just fat, but obese models. Rather than coding into the framework, spreading the logic into appropriate framework service layers, they literally push everything not a view into a model.

Keep controllers lithe by focusing their logic on wiring, only. Controllers assemble delegates together and get them talking, and that's it.

Likewise, keep models lithe by focusing them on data validation and relationships. Models show what the business data can be and how it relates to other data, period. An example of a lithe model.



If you're wondering, I've used Zend Framework, Fuel, CodeIgniter, and Laravel in production applications.

2 comments:

  1. Taylor describes an altogether better design pattern in Apprentice to Artisan by abstracting the functions away from models, views, controllers, routes, etc. Jeffrey Way has great videos describing the practical application of these ideas.

    So, say I want a validator.

    My validation is handled in a validation class and called in my controller.

    app/
    - Acme/
    - - Validation/
    - - - ValidationHandler.php { accepts the input and returns formatted errors or null
    - controllers/
    - - UserController.php { addUser() method calls Acme/Validation/ValidationHandler::validateInput(Input::all())
    - models/
    - - User.php
    route.php { use resourceful controllers or maybe Route::post('user', ['uses' => 'UserController@addUser'];

    ReplyDelete
    Replies
    1. Absolutely! We developers should aim for lithe classes, delegating work to classes that have one specific function. "Do one thing, and do it well" applies at every level: function, class, module, etc.

      For me, I tend to think of a large service layer having definite and dedicated sub layers like validation, form building, third-party communication (eg LDAP). That helps to keep the MVC structure small. Heck, maybe that's what we should be aiming for: MVCS -- Models, Views, Controllers, and Services.

      Thanks for the example!

      Delete

Share your thoughts!