A Factory Should Create, Not Retain

In a recent Reddit conversation, some of us went off on a tangent about factories. I maintained then, and do now, that a “factory” always-and-only returns a new instance. If you have a “factory” that returns anything other than a new instance, it’s not a factory alone. In the case of factory methods, it is a factory + accessor; in the case of factory objects, it is a factory + registry.

A “factory” (whether a factory method or factory object) is one way to separate object creation from object use.

Let’s say we need to create an object to do some work in a class method:

class Example
{
    public function __construct($db)
    {
        $this->db = $db;
    }

    public function doSomething($itemId)
    {
        $data = $this->db->fetchOne(
            "SELECT * FROM items WHERE id = :id",
            ['id' => $itemId]
        );
        $item = new Item($data);

        // do some other work with the item,
        // the return the results of that work.
        return $results;
    }
}

The item creation is mixed in with the use of the item. What we want to do is separate the creation from the usage. One way to do that is to use a factory method, or a factory object, to handle object creation for us. Here’s an example of a factory method:

class Example
{
    public function __construct($db)
    {
        $this->db = $db;
    }

    public function doSomething($itemId)
    {
        $data = $this->db->fetchOne(
            "SELECT * FROM items WHERE id = ?",
            ['id' => $id]
        );
        $item = $this->item($itemId);

        // do some other work with the item,
        // the return the results of that work.
        return $results;
    }

    public function item($data) // factory method
    {
        return new Item($data);
    }
}

Here’s an example of an injected factory object:

class Example
{
    public function __construct($db, $factory)
    {
        $this->db = $db;
        $this->factory = $factory;
    }

    public function doSomethingWithItem($id)
    {
        $data = $this->db->fetchOne(
            "SELECT * FROM items WHERE id = ?",
            ['id' => $id]
        );
        $item = $this->factory->item($data);

        // do some other work with the item,
        // the return the results of that work.
        return $results;
    }
}

class Factory // factory object
{
    public function item($data) // factory method
    {
        return new Item($data);
    }
}

There were some folks in the Reddit thread that believe a factory may additionally retain the created instance for reuse. For example, let’s say we create and the reuse a collaborator object of some sort:

class Example
{
    public function doSomething()
    {
        $collab = $this->collab();
        // do stuff, then:
        return $result;
    }

    protected function collab() // factory method?
    {
        if (! $this->collab) {
            $this->collab = new Collab();
        }
        return $this->collab;
    }
}

As far as I can tell, that’s not just a factory. There are three things going on there: initializing a property, creating an object, and accessing a property. To split the concerns, one would need two methods:

class Example
{
    public function doSomething()
    {
        $collab = $this->getCollab();
        // do stuff, then:
        return $result;
    }

    protected function getCollab() // initialize + access
    {
        if (! $this->collab) {
            $this->collab = $this->newCollab();
        }
        return $this->collab;
    }

    protected function newCollab() // factory
    {
        return new Collab();
    }
}

Now the concern of creating the object is represented by newCollab() method, and the concerns of initializing and accessing the property are represented by the getCollab() method. Indeed, splitting out a factory method in this kind of situation is the exact recommendation in the GOF Design Patterns book on page 113; this is the book that defined the term “factory method” in the first place, so it seems authoritative on this point.

What happens when you add retention to what would otherwise be a factory object? For example, is the following only a factory object, or does it do more than just create and return new instances?

class WhatIsThatThing
{
    public function getService()
    {
        if (! $this->service) {
            $this->service = $this->newService();
        }
        return $this->service;
    }

    public function newService()
    {
        return new Service();
    }
}

It both creates objects, and retains the created objects. That makes it more than just a factory; it looks more like a container at this point.

Finally, regarding method names, it seems like it’s best to indicate what to expect as a return result. I default to newInstance() in factory objects that deal with only a single class, and new<Type>() when the factory object creates many different classes. Using get<Type>() indicates that a pre-existing instance (probably memoized in a property) is being returned.

Radar: A PSR-7 Action-Domain-Responder Framework

Radar is a PSR-7 compliant Action-Domain-Responder (ADR) system. While it may look like a micro-framework, it is more like a wrapper around the real core of your application domain. Its architecture makes it an excellent complement to Domain Driven Design.


Radar is superficially similar to a micro-framework. It has a routing system to point URLs to actions, a filter-style middleware system to modify the incoming HTTP request and outgoing HTTP response, and a dependency injection container and configuration system to wire everything together.

However, with Radar, you don’t specify “controllers” or “closures” for your routes. Instead, you specify up to three callables per route, all of which are optional:

  1. A Domain callable to be invoked with the user input. (If you don’t specify a Domain callable, the Responder will be invoked directly; this is unusual but sometimes convenient.)

  2. An Input callable to extract user input from the incoming HTTP ServerRequest. The default Radar Input callable will naively merge the route path attributes (path-info parameters), the query parameters ($_GET), the parsed body parameters ($_POST), and the uploaded files array ($_FILES) into a single associative array of user input.

  3. A Responder callable to convert the Domain output to an HTTP response. The default Radar Responder expects a Payload object from the Domain; it delivers JSON output and sets proper HTTP status codes for a wide range of scenarios.

These three callables are invoked within a standardized ActionHandler. As a result, the Action logic in Radar is always the same for every route. The only variations are in how input is collected, how output is presented, and of course in how your core application domain operates.

So, don’t think of Radar as a micro-framework. Think of it more like a wrapper around the core of your real application domain. Its only purpose is to guide input from the user into the domain, and to present output from the domain back to the user.

You can read the documentation for it here.

MVC and ADR are User-Interface Patterns, Not Application Architectures

N.b.: I am the author of the Action-Domain-Responder paper referenced in this article.

In his post on MVC alternatives (including Action-Domain-Responder), Anthony Ferrara makes a claim that is central to his discussion. While I agree with much he says in that and related articles, I believe that one claim is in error, and while it does not discredit the essay as a whole, replacing the erroneous claim with a more accurate one gives the essay a different flavor.

The central mistake I think Anthony makes is near the end of this post, where he states (in talking about MVC, ADR, et al.) that “All Pretend To Be Application Architectures.” That assertion strikes me as incorrect.

While it may be that developers using MVC may mistakenly think of MVC as an application architecture, the pattern description itself makes no such claim. Indeed, Fowler categorizes MVC as a “Web Presentation Pattern” and not as an “Application Architecture” per se.

Sure, MVC is described in book called “Patterns of Enterprise Application Architecture”, but MVC itself is a presentation pattern within an application architecture. Here’s another example of the distinction: we would not call “Table Data Gateway” an application architecture, even though it too appears in the same book. It is a data source pattern within an application architecture.

Fowler’s categorization and description of MVC define it pretty clearly as a user interface pattern. ADR, as a refinement of MVC, is likewise a user interface pattern. Neither is an application architecture in and of itself, although they are the outermost part of an application architecture. So when Anthony’s article states elsewhere that ADR’s “coupling to HTTP that it becomes difficult to make a non-HTTP interface” my response is “Well, obviously – it’s a user interface pattern centered around HTTP.”

Anthony then goes on to say:

And that’s the biggest reason all of these “patterns”, “architectures” and “concepts” are a bad joke. They solve the easy problem, and throw the hard problem over the fence.

MVC, ADR, et al., solve a user-interface problem. That may be an easy problem for Anthony to solve, but to say that user-interface patterns “throw the hard problem over the fence” strikes me as starting from the wrong set of expectations. MVC and ADR, as user-interface patterns, aren’t supposed to be dealing with core business logic in the first place.

It might be better to say that the underlying application that is presented through the user interface is not really the user interface’s problem in the first place. The user interface code probably should not care too much about the internal operation of the underlying application code. If it does, then the application code is bubbling up too far into the user interface.

In summary, I think the assertion that “All Pretend To Be Application Architectures” is just not an accurate categorization. It would more correct to say that “All Are User Interface Patterns, Not Entire Application Architectures” – or, even better, that “Developers Frequently Misunderstand Them To Be Application Architectures”.

What’s The Difference Between A “Pivot Table” And An “Association Table”?

An “association table” is a table that joins other tables in a many-to-many relationship. For example, if an Article can have more than one Tag, and each Tag can be placed on one or more Articles, then they are in a many-to-many relationship. To associate them to each other, we need a third table through which we can join them.

-- one end of a many-to-many relationship
CREATE TABLE article (
    article_id INT,
    title VARCHAR(255),
    body TEXT
);

-- the other end of a many-to-many relationship
CREATE TABLE tag (
    tag_id INT,
    name VARCHAR(255)
);

-- an association table mapping articles and tags to each other
CREATE TABLE article_tag (
    article_tag_id INT,
    article_id INT,
    tag_id INT
);

In ORM terms, we might say each Article “has many” Tags “through” the ArticleTag association, that each Tag also “has many” Articles “through” the ArticleTag, and finally that each ArticleTag “belongs to” an Article and that it “belongs to” a Tag.

When writing SQL to find the Tags for an Article, or to find all the Articles that use a specific Tag, we join the ArticlesTags table to get the associated entity IDs. The SQL looks something like the following:

-- select all the tags for an article
SELECT tag.*
FROM tag
JOIN article_tag ON article_tag.tag_id = tag.tag_id
WHERE article_tag.article_id = ?

-- select all the articles that use a tag
SELECT article.*
FROM article
JOIN article_tag ON article_tag.article_id = article.article_id
WHERE article_tag.tag_id = ?

This pattern is called an association table mapping.

On the other hand, a “pivot table” is a cross-tabulation query, frequently used in spreadsheets. You can see more about pivot tables through Google. In short, the idea is to build a query, and convert the rows into columns by grouping the rows in a particular way. These kinds of queries generally involve some conditionals and calculations to group the query results; you can see some examples here.

In summary: if you are joining tables to each other in a many-to-many relationship, the table that maps the relationship is an association table. If you are doing a cross-tabulation to convert rows into columns, you are working with pivot table.

What’s The Difference Between Tightly-, Loosely-, and De-Coupled ?

In a tweetstorm that spun up late last week, Taylor Otwell produced the following commentary:

look guys I’m “decoupled” because this package doesn’t have composer dependencies!!! HAHAHAHA LOL

how many composer packages a given package has does NOT affect YOUR code’s decoupling.

that is a matter of programming to an interface, etc.

you people seriously do not understand decoupling. at all.

if you type hint AuraAnything that is a HARD, CONCRETE dependency. THAT is coupling.

IlluminateContracts are all interfaces. abstractions. not concretions. THAT’s decoupling.

IlluminateContractsViewFactory could be a Laravel view factory, could be an Aura one. That’s decoupling.

how many composer pkgs the IMPLEMENTOR needs is an implementation detail my consuming code need not care about

consuming code ONLY cares about programming to an interface for decoupling.

you [@philsturgeon] and brandon [savage] and paul [jones] don’t understand basic programming concepts like coupling

and think somehow coupling is tied to composer

Aura ships hard concretions = you are tightly coupled to Aura.

which should my consuming code give a shit if Aura is decoupled AMONGST ITSELF. Nobody gives a shit.

i only care if MY code is coupled to Aura.

and since Aura makes you depends on hard concretions, it promotes hard couplings.

I’m saying if you type-hint a class dependency, you are coupled to that implementation (cont)

regardless of that package’s internal dependencies

While some of Taylor’s rant is correct for as far as it goes, much of it glosses over important distinctions in subtle misdirection, and the remainder displays some misunderstandings. He is also flat wrong in his assertions of other peoples’ understanding of “basic programming terminology.” As such, I think his words demand a careful response for future reference.

First, I’m glad to see Taylor paying attention to the proper use of terminology in a software context. This is something he’s not always been great at in the past, and I encourage him here.

But I can’t quite tell if Taylor thinks the developers who use Aura believe their code is decoupled by virtue of using Aura. Or maybe it’s that the Aura marketing phrase “fully decoupled libraries” is the target of his ire. I infer allusions to both from his tweets, so I’ll attempt to address both possibilities. (Perhaps there is some other interpretation I have missed.)

It should be so obvious as to not require stating, but for the sake of explicitness: If your code has a dependency on classes in a particular thrid-party package, your code is tightly coupled to the code in that package. This is true for any classes in any library, framework, or other package code. So, if you believe that depending on an Aura library in your code makes your code “decoupled” then you are mistaken. As far as I know, I have never attempted to state or imply otherwise. I don’t think any Aura users have this misperception, but if so, consider this a corrective.

The fact that your code could be tightly coupled to another package does not mean that the other package is coupled to anything else. That is to say, the other package might have no couplings of any sort to any other code outside itself. The other package in that case is de-coupled.

The Aura library packages are designed with that kind of decoupling in mind. That is, no Aura library package depends on anything at all in any other Aura package. Each of the Aura libraries is thus fully decoupled from the others, and incidentally from any framework that is composed of them. (Note that the *_Kernel and *_Project packages are coupled to other packages; the decoupling principle applies only to the Aura library packages.)

But why would you care if a particular library package is itself decoupled from other packages? I assert that one reason (of many) you want libraries that are themselves decoupled is so that, if you have to swap one out in your own code, you only have to worry about the one library, not about all the dependent libraries that it is coupled to (and all the dependent libraries they are coupled to). Swapping out is still tedious: you will need to work through your code, change all the typehints from that library’s classes to those in another, and change all the injections that specify classes from the library. But at least it’s only the one library; the fact that the library is itself decoupled reduces the swapping-out work.

Taylor points out another level of coupling called “loose” coupling. This means that, instead of your code depending on a particular class, you instead depend on an interface. This couples you to the interface, but not to any particular implementation. If your code depends on interfaces, your code is loosely coupled to the implementations of those interfaces (although I don’t think this means you are de-coupled – there’s still some knowledge necessary for interactions).

Being loosely coupled is a good situation to be in compared to being tightly coupled. If you need to swap out an implementation of an interface, you won’t need to change your typehints (unless you swap to another set of interfaces). However, you will still need to change all your injections to the new implementation. Overall, being loosely coupled makes for less work when swapping out libraries.

How can you tell if a package is coupled to another package? Provided that composer.json is not lying, it’s easy enough to examine the “require” element to see if there are other packages listed there. If there are, then it seems likely that the package is coupled to whatever is required. You need to exercise a little judgment, though. If the required package contains only interfaces, then the coupling is “loose”. Otherwise, it is “tight”. If there are no other required packages at all, then the package has no coupling of any sort; it is fully decoupled from anything outside of it.

However, that’s only if you assume composer.json is not lying. To really discover the coupling of a particular package, you would need to examine its code. Any uses of interfaces defined outside the package indicates loose coupling, uses of classes defined outside the package indicates tight coupling, and no uses of interfaces or classes outside the package indicates full decoupling.

(Note that this discussion is of inter-package coupling. Even if the classes inside a package may still be coupled to each other, the package as a whole may still be decoupled from any other package.)

Having said all this, Taylor is trying out a “contracts” package that exposes the Laravel interfaces independently of the implementations. I think this is a neat idea. It’s the only truly new thing I’ve seen introduced to the PHP community by the Laravel codebase, and I think it is worthy of emulation.

Even so, if the “contracts” include anything besides interfaces, I think coupling to them might be defined as “tight”. I am thinking specifically of the Exception classes included in the “contracts” package. Although it may be fair to think that Exceptions are exempt from coupling rules, perhaps they would be better provided as interfaces to Exceptions, instead of classes proper. I will reserve my judgment on that for a later time.

Action-Domain-Responder and the “Domain Payload” Pattern

tl;dr: Instead of inspecting a Domain result to determine how to present it, consider using a Domain Payload Object to wrap the results of Domain interaction and simulataneously indicate the status of the attempted interaction. The Domain already knows what the results mean; let it provide that information explicitly instead of attempting to re-discover it at presentation time.

In Action-Domain-Responder the Action passes input to the Domain layer, which then returns some data for the Action to pass to the Responder. In simple scenarios, it might be enough for the Responder to inspect the data to determine how it should present that data. In more complex scenarios, though, it would make more sense for the Domain to pass back the data in a way that indicates the status of the data. Instead of the Responder inspecting the Domain results, the Domain should tell us what kind of results they are.

For example, let’s look at an example of some older code to update a Blog post. This is MVC-ish code, not ADR code; we’ll refactor along the way.

<?php
class BlogController
{
    // POST /blog/{id}
    public function update($id)
    {
        $blog = $this->model->fetch($id);
        if (! $blog) {
            // 404 Not Found
            // (no blog entry with that ID)
            $this->response->status->set(404);
            $this->view->setData(array('id' => $id));
            $content = $this->view->render('not-found');
            $this->response->body->setContent($content);
            return;
        }

        $data = $this->request->post->get('blog');
        if (! $blog->update($data)) {
            // update failure, but why?
            if (! $blog->isValid()) {
                // 422 Unprocessable Entity
                // (not valid)
                $this->response->status->set(422);
                $this->view->setData(array('blog' => $blog));
                $content = $this->view->render('update');
                $this->response->body->setContent($content);
                return;
            } else {
                // 500 Server Error
                // (i.e., valid data, but update failed for some other reason)
                $this->response->status->set(500);
                return;
            }
        }

        // 200 OK
        // (i.e., the update worked)
        $this->response->status->set(200);
        $this->view->setData(array('blog' => $blog));
        $content = $this->view->render('update');
        $this->response->body->setContent($content);
    }
}
?>

We can see that there is some amount of model work going on here (look for a blog post, attempt to update it if it exists, check for error conditions on the update attempt). There is also some amount of presentation work going on; remember, the view is not the template – the view is the response. So, even though the view templates are separated, the HTTP status codes are also part of the presentation, meaning that there is an insuffcient level of separation of concerns.

In converting this to Action-Domain-Responder, we can pretty easily extract the model work to a Domain, and the presentation work to a Responder, resulting in something like the following. (Note that the Domain layer now adds values to the returned $blog entity to indicate different failure states.)

<?php
class BlogUpdateAction
{
    // POST /blog/{id}
    public function __invoke($id)
    {
        $data = $this->request->post->get('blog');
        $blog = $this->domain->update($id, $data);
        $this->responder->setData('id' => $id, 'blog' => $blog);
        $this->responder->__invoke();
    }
}

class BlogUpdateResponder
{
    public function __invoke()
    {
        if (! $this->data->blog) {
            // 404 Not Found
            // (no blog entry with that ID)
            $this->response->setStatus(404);
            $this->view->setData($this->data);
            $content = $this->view->render('not-found');
            $this->response->body->setContent($content);
            return;
        }

        if ($this->data->blog->updateFailed()) {
            // 500 Server Error
            // (i.e., valid data, but update failed for some other reason)
            $this->response->status->set(500);
            return;
        }

        if (! $this->data->blog->isValid()) {
            // 422 Unprocessable Entity
            // (invalid data submitted)
            $this->response->setStatus(422);
            $this->view->setData($this->data);
            $content = $this->view->render('update');
            $this->response->body->setContent($content);
            return;
        }

        // 200 OK
        // (i.e., the update worked)
        $this->view->setData($this->data);
        $content = $this->view->render('update');
        $this->response->body->setContent($content);
    }
}
?>

But at this point we’re still inspecting the Domain result to see how we should present it. This strikes me as a lot of work to determine something the Domain already knows.

Instead of re-discovering the Domain status in the Responder, we should let the Domain tell us not only the data, but also what to think about that data. The Domain should give us an indication as to what it tried to do, and whether it succeeded or not. Then we can completely skip the inspection of the Domain results and present those results without lots of additional work.

The key to doing this is something called a Domain Payload Object. (Initially I called this a “Domain Result” but my recent reading of Vernon’s Implementing Domain Driven Design revealed the term to me. I love finding the right word for a concept!)

With a Domain Payload, we wrap the Domain results in an object that carries those results for us. We can then extend the semantics of the Domain Payload to tell us what kind of payload it carries. Something as simple as the class name of the Domain Payload can give us that information.

In the ADR example code we will find a series of Domain Payload objects. While these map closely to HTTP response codes for simplicity’s sake, other Domains are very likely to have different kinds of payload statuses. The point is that each Payload object explicitly tells us what the results indicate: entity not found, invalid data in the entity, database error, successful update, and so on.

The BlogUpdateAction remains straightforward. However, the example BlogService‘s update() method now does all the update work, and it wraps all returned results in a Domain Payload that indicates the result status.

Finally, the BlogUpdateResponder, which itself extends an AbstractResponder, can match a Domain Payload class name to a method that presents the payload results.

Voila: no more inspection of the results to figure out presentation. We let the Domain tell us what it tried to do and whether it worked or not (and what the cause of the failure was, if any). At the presentation layer, our Responder can honor (or ignore) that information at its convenience.

Action-Domain-Responder, Content Negotiation, and Routers

While talking about Action-Domain-Responder on the Crafting Code Tour, one of the common questions I got was: “Where does content negotiation happen?” My response was always: “Where does it happen in Model-View-Controller?” That opened up a discussion on how content negotiation is a tricky bit that can go in different places, depending on how you want the concerns separated, and is not a problem specific to ADR.

However, I’ve not really been satisfied with that outcome. I enjoyed the question and the discussion, but it never seemed to resolve itself. We were left with this tension between resource conservation and proper separation of concerns. Should negotiation happen in the the Action (Controller), the Domain (Model), or the Responder (View)?

At first it seems like this is clearly a (re)presentation issue, and as such ought to go in the Responder or View. But if the Responder cannot present an acceptable content type for the request, that means we have done a lot of work in the Domain to build objects that will be discarded in favor of a “406 Not Acceptable” response. This is not a good use of our limited resources.

Perhaps the Domain is the place for negotiation? I think we can dismiss this outright. The Domain should not be in charge of returning different presentations of its data.

Finally, we might try negotiation in the Action (Controller). Here we examine the request, and query the Responder to see what content types it can present in responses. (Alternatively, we embed the available content types in both the Action and Responder, duplicating that information somewhat.) If the negotiation fails in the Action, we skip the Domain work and instruct the Responder to return a “406 Not Acceptable”. But that means the Action is now responsible for at least a little bit of the response-building logic. It’s not horrible, but it does not seem as clean as it could be.

After thinking about this for a while, I am beginning to think it is reasonable to perform what I will call a “first filter” on the Accept header at the Front Controller level, specifically in the Router. We already consider the Router as a guard to map incoming requests to appropriate Actions, inspecting the path, HTTP method, and other request information. Inspecting the acceptable types seems a reasonable addition to these elements.

A full content negotiation at the Router level is probably overkill. Really, all the Router needs to know is what content types are provided through particular Route (whether an MVC or ADR one). The matching logic can do a naive check of the Accept request header to see if one of the provided types is present with a non-zero “q” value. If none of the types is present, the Router can move along to the next route, possibly tracking the failure so a Dispatcher can directly invoke a Responder for routing failures. This way, the Router never invokes a non-matching Action, thereby conserving the Domain resources. If the match is successful, the Responder can do the “real” content negotiation work, using an Accept header value passed to it as input from the Action along with the Domain data.

As a proof of concept, I have modified the Aura.Router library to recognize “accept” specifications on the route, and the tests indicate it seems to work just fine.

Refactoring To Action-Domain-Responder

The v1 version of the Aura framework includes a controller to handle web assets. The idea for this controller was that an Aura package might have images, scripts, and stylesheets that need to be publicly available, but in development you don’t necessarily want to copy them to a public document root every time you change them. The framework dispatches all “/asset/*” routes to the asset controller, which in turn reads the requested package asset from the file system and places its contents into the response body. Performance-wise this is horrible, so in a production environment one would use a build process to copy all the package assets to a static asset server, but in a local development environment it is a valuable convenience.

Take a look at the v1 version of the asset controller. It is constructed as a Page Controller within an MVC architecture. The default actionIndex() method receives an Aura package name in the form of Vendor.Package and a trailing file path indicating the asset to load from that package, then reads that file from the package and loads it into the response body.

That v1 version is a mess. The Controller handles the response-building entirely, and there is no Model separation at all. Let’s try refactoring it to an Action-Domain-Responder architecture and clean it up some for a v2 version. (For this example refactoring, we have Hari KT to thank for getting us started.)

  1. First, we need to extract the Domain portions of the code. After some discussion, we determined that the Domain here is the file-reading portions of the code. Instead of an Aura-specific Vendor.Package algorithm, we build a map of vendor/package keys that point to arbitrary directory prefixes (typically but not necessarily in a Composer installation). Finally, we figure that the caching elements would be better as part of a build process rather than on-the-fly, so we remove those caching elements; this reduces a significant portion of the Domain work.

  2. Next, we extract the response-building activity to a separate Responder class. The response-building work turns out to be relatively straightforward: if the asset has a path, that means the service found it, and we should present it as 200 OK; if not, we present it as 404 NOT FOUND.

  3. Last, we rename the Controller to an Action, and name its one-and-only “main” entry point as __invoke(). We modify the code in the Action to (1) invoke the Domain with the incoming request input, (2) place the Domain data into the Responder, and (3) return the Responder.

The end result is three classes instead of one: AssetService to handle Domain work, AssetResponder to handle the response presentation, and AssetAction to handle the incoming request and pass data from the Domain to the Responder.

Compared to the original Controller class, we clearly have more classes, and (aside from the fact that we removed the caching functionality) we likely have somewhat more code as well. But each class, and each method in each class, is relatively short, and the package overall is much more testable:

  • the AssetServiceTest is completely freed up from the Action and Responder (as it should have been in the original MVC code)

  • the AssetResponderTest does not need either the AssetAction or the AssetService, and is able to examine both the body and the headers of the response

  • the AssetActionTest does little more than to check if __invoke() returns a Responder, and see if the assigned data was retained

This separation has the effect of making the underlying components much more independent of each other and a lot easier to test. If we wanted to get really serious we would use interfaces and test doubles to fully isolate the classes.

Right now, some readers are looking at this example and wondering “How is this different from refactoring to a better-separated MVC?” The main difference in this particular example is that, in a webbish MVC setup, the work of setting response headers is generally handled in the Controller. Doing so does not give us as clean a Separated Presentation as we see under ADR. (Remember: on the web, the template is not the view; the response is the view.) In addition, to test the full response (i.e., the headers as well as the body) we would need to run the controller action code instead of just the separated presentation code.

Two final notes:

  • This example is not the only way to do Action-Domain-Responder. The Action could invoke the Responder directly, instead of allowing the calling code to invoke it. The Action might receive a ResponderFactory instead of a Responder object directly. The Responder might receive a ResponseFactory instead of a Response object directly. The Action might just be a closure in a micro-framework route. The point is that we now have a cleanly separated presentation, where the response-building work is completely extracted from the Action, and the Domain work is simiarly completely extracted from the

  • The Action returns a Responder and not a response object; this is predicated on how Aura.Dispatcher works. When the dispatcher invokes a Controller or Action, it checks the return value from that invocation; if that return value is itself invokable, the dispatcher does so recursively until the return result is no longer invokable. This means that the Dispatcher becomes responsible for invoking the Responder returned from the Action; the invoked Responder returns the completed response object.)

That is all; if you have comments on the Action-Domain-Responder paper, please leave them here or as issues out at Github.

The Template Is Not The View

As server-side web developers, we tend to think of our templating system as providing the View layer in a Model-View-Controller architecture. I have recently come to the conclusion that this is an incorrect approach. Instead, we need to think of the HTTP response as the View.

When an HTTP client makes an HTTP request, what does it get in return? It does not receive only the body of the HTTP response. The client receives the body and the headers of the HTTP response. The response as a whole is what the web application delivers as its presentation to the client.

Templating systems, as far as I can tell, deal only with the body of the HTTP response. In practice, the rest of the response is generally handled by the Controller; for example, setting the status, setting cookies, and modifying headers.

Let’s say we accept the idea that the HTTP response is the View (i.e., the presentation that is delivered to the client). If we accept that idea, then for a clean separation of concerns a la SeparatedPresentation, we need to combine both the template work and the header work into their own layer. That layer needs to be completely separated from the Controller and Model.

Thus, anything that deals with the response, including the setting of headers, should be considered the View layer. If you are setting headers in a Controller, you are losing that clean separation of concerns. To remedy this, your Controller needs to hand off to a layer that builds the response on its own; this is the proper place for the tempalting system to be invoked, not the Controller.

In summary: the template is not the View. The response is the View. We should separate our concerns accordingly.

Afterword

If you like the line of thinking presented here, please check out the Action-Domain-Responder refinement of the MVC pattern. It’s still a work-in-progress so be sure to leave your comments and criticism either here on this blog or as a new issue at Github.

Stephan Hochdörfer and Action-Domain-Responder

I’ve been asking for feedback on the Action-Domain-Responder pattern, a refinement of MVC, to discover how it’s being used in the wild already, and to solicit criticism of the pattern to find weak points.

The key points of Action-Domain-Responder:

  • Instead of a controller class with many action methods, each Action is its own class (or closure, like with Slim).

  • The Action interacts with the Domain (model), and feeds data to a Responder (view).

  • The Responder is entirely responsible for building the response, including all headers as well as the body of the response. This means that in ADR, the template is not the view; the response is the view.

Stephan Höchdorfer has been using single-Action classes for a while now. Here is my summary of his article:

  • “we are using action classes in our application framework for almost the last decade”

  • “action classes tend to be rather small, typically less than 100 loc for us”

  • “another bonus point for action classes: It is easier to search for a class name than a method name”

  • “Controllers tend to have a lot of dependencies. … people came up with a few “creative” solutions for this problem, mainly the creation of lazly loaded dependencies”

  • “action classes depend on what they really needed. Typically that’s just a few services for a single action. Again that makes the code way easier to understand and easier to test.”

  • “Action classes in contrast to controller classes can be reusable.”

Those were the highlights for me; you should read the whole essay to find your own: http://blog.bitexpert.de/blog/controller-classes-vs.-action-classes

In addition, please write up your own commands and criticism regarding Action-Domain-Responder, so that I can improve the offering as much as possible.