What Is the Hmvc Pattern

What is the HMVC pattern?

Sam de Freyssinet (one of the Kohana developers) wrote a rather in-depth article about HMVC, what it is, and how it can be used.

Link is dead: New Link - https://web.archive.org/web/20160214073806/http://techportal.inviqa.com/2010/02/22/scaling-web-applications-with-hmvc/

MVC vs HMVC for web application development

The Hierarchical-Model-View-Controller (HMVC) pattern is a direct
extension to the MVC pattern that manages to solve many of the
scalability issues already mentioned. HMVC was first described in a
blog post entitled HMVC: The layered pattern for developing strong
client tiers on the JavaWorld web site in July 2000. Much of the
article concentrates on the benefits of using HMVC with graphical user
interfaces. There has been some suggestion that the authors where
actually re-interpreting another pattern called
Presentation-Abstraction-Control (PAC) described in 1987. The article
in JavaWorld provides a detailed explanation of how HMVC can aid in
the design of desktop applications with GUIs. The focus of this
article is to demonstrate how HMVC can be used to create scalable web
applications.

HMVC is a collection of traditional MVC triads operating as one
application. Each triad is completely independent and can execute
without the presence of any other. All requests made to triads must
use the controller interface, never loading models or libraries
outside of their own domain. The triads physical location within the
hosting environment is not important, as long as it is accessible from
all other parts of the system. The distinct features of HMVC
encourages the reuse of existing code, simplifies testing of disparate
parts of the system and ensures that the application is easily
enhanced or extended.

From Scaling Web Applications with HMVC
by Sam de Freyssinet

HMVC pattern - how do all the triads M-V-C share the same view template/css/etc.?

You really don't want modules to share the same views. Typically what you want is a common view, the outer view. In HMVC the controller is the middle man between the view and the model. All requests will be routed to a controller action. Your initial request could be to a controller that instantiates a view (outer view), then within that same controller you make a request to a module controller which gives a view as a response. The initial controller takes the module controllers view response and sets it to a section of the outer view.

Class Controller_Page extends Controller {
/**
*Initial controller
*/
public function action_index() {
//get the outer controller view
$outerView = View::factory('outermost');
//request to a module called widget
$widgetView = Request::factory('widget');
//add the widget to the body of the outer view
$outerView->body = $widgetView;
$this->response->body($outerView);
}
}

Class Controller_Widget extents Controller {
/**
*Module Controller
*/
public function action_index() {
$view = View::factory('widget');
//set the widget view as the response
$this->response->body($view);
}
}

//contents of "outermost" view
<html>
<body>
<!--The $body property was binded to the view by the contoller ("$outerView->body") -->
<!-- Binding of properties to views is how data is passed to the view -->
<?php echo $body; ?>
</body>
</html>

//contents of "widget" view
<p>
I'm a widget
</p>

//the final result will be
<html>
<body>
<p>I'm a widget</p>
</body>
</html>

Also note that in HMVC there is a Model, View, and Controller but it's not the "MVC architecture" you hear talked about. It more follows the Presentation Abstraction Control (PAC) architecture. In the MVC architecture the model notifies the view of changes, this is not the case with PAC.

HMVC Design Pattern in PHP

First of all. There are two kinds of HMVC.

1 Kohana style. Where you can access other controllers within you application

Possible implementation:

  • All request data (URL, POST, GET ...) are stored in Request variable. In this case none of controllers can access POST, GET or other request variables directly. All data should be taken from Request variable.

  • When controller1 executes method to access controller2, new (fake) Request instance is being created and transferred to controller2. Controller2 does not know that he is executed not via real request, but fake one and process data as usual.

2 Real HTTP request over the internet. In this case you can access other online services within your controller. Unfortunately I don't know real world examples.

Possible implementation: using CURL

What Can I Use the HMVC Architecture for?

It is a bit like ajax, just purely server-side.

That's a good analogy.

HMVC is nice for adding widgets to pages - modular bits of content that you'll reuse on few pages. For example, a shopping cart widget. You could do the same thing in different ways:

  1. A library. We're accustomed to moving reusable code from a controller into a library. Then, from the controller, you could load the results of a call to that library into a view variable.
  2. A view. You could load a view (partial) from within the main view. That view partial could pull in content from models. Calling models from views isn't always popular but it isn't necessarily wrong.

However, Kohana HMVC has a few advantages:

  1. Consistency - HMVC requests are treated the same as external http requests.
  2. Power - HMVC requests have the same Kohana resources as http requests including routes.
  3. Pluggability - When called from a view, an HMVC request doesn't have a coupling between the controller (which assigns the library results to a view) and a view placeholder. You only touch one file as opposed to two.

I'm starting to appreciate the case for HMVC and scalability with http requests as linked by Kiall. The same thing could be done with CURL. However, it might be more natural to design with Kohana HMVC than CURL from the start.

Accurate use / consumption of the HMVC pattern?

After reading different resources of HMVC, I believe ASP.NET MVC does have HMVC since v2.0 in the form of Areas.

Couple that with T4MVC and calling Action.PartialX() methods and you've got yourself the next buzz-word HMVC.

HMVC pros and cons when compared to MVC in PHP

Basically, the HMVC pattern is just an extension of MVC. An HMVC application includes one or more MVC sub-applications. So anything MVC can do, HMVC can do too. Now, it depends on whether you need the flexibility and scalability that HMVC offers.

In terms of performance, there's no difference between HMVC and MVC (as long as it's properly implemented). Sam de Freyssinet, one of the developers of Kohana (an HMVC framework), explains that very well - http://techportal.inviqa.com/2010/02/22/scaling-web-applications-with-hmvc/

How do I avoid HMVC design pattern in Laravel?

I came up with a neat way to do it, and it seems to have helped me speed up my workflow...

I think this alternative I made can replace HMVC, as well as the conventional way of using controllers... as now controllers are but somehwere where our -what I called- 'motors' are injected.

Check out my article at coderwall where I went through the whole thing.

Read through it, and hopefully it will provide a better way of doing things, starting from the models to and finishing at controllers.

However if you wish to proceed your own way, make sure what was required to be shared between two controllters hiarchecly gets shared in a more neater way, as taylor suggested, shared through injection.

For instance, you are in AdminsController and you feel the need to call an action from UsersController, just make that action and its siblings into a third class, and in your AdminsController

//AdminsController

use ThirdClass;

public function __construct(ThirdClass $mything)
{
$this->myThirdClass = $mything;
}

public function mySharedAction()
{
$this->myThirdClass->mySharedActionFromUsersController();
}

And like so.

Update

If you have gone through my article at coderwall, the one I have mentioned above, I have made a little package that generates all of the mentioned components in there.

Check it out at github



Related Topics



Leave a reply



Submit