Paul M. Jones

Don't listen to the crowd, they say "jump."

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.



"Of course you have freedom of speech! You just don't get to lie."

Democracy depends on having a strong sense of the value of diverse opinions. If one imagines (as the Soviets did) that one already has the final truth, and that everyone who disagrees is mad, immoral, or stupid, then why allow opposing opinions to be expressed or permit another party to exist at all? The Soviets insisted they had complete freedom of speech, they just did not allow people to lie. It is a short step, John Stuart Mill argues, from the view that one’s opponents are necessarily guided by evil intentions to the rule of what we have come to call a one-party state or what Putin today calls “managed democracy.” If universities embody the future, then we are about to take that step.

Source: Article Why College Kids Are Avoiding The Study Of Literature


Modernizing Serialized PHP Objects with class_alias()

Several weeks ago, a correspondent presented a legacy situation that I've never had to deal with. He was working his way through Modernizing Legacy Applications in PHP, and realized the codebase was storing serialized PHP objects in a database. He couldn't refactor the class names without seriously breaking the application.

I was carefully moving my classes to a PSR-0/4 structure when I found this. The application saves the output of serialize($shoppingCart) in a BLOB column, and unserializes it later to recreate the ShoppingCart object. The serialized object string looks like this:

O:12:"ShoppingCart":17:{s:13:"\00Basket\00items";a:25:{...}; ...}

See how the class name is embedded in the serialized string? If I rename the ShopppingCart class to PSR-0/4 namespace, then the old class won't be found when the application tries to unserialize() the serialized representation. How can I begin refactoring this without breaking the whole application?

Before I was able to reply, my correspondent ended up changing the serialization strategy to use JSON, which was a rather large change. It ended up well, but it turns out there is a less intrusive solution: class_alias().

If you're in a serialized situation, and you need to change a class name, you can use a class_alias() to point the old class name to the new one. (Call class_alias() early in execution, probably before you register your autoloader.) You can then rename and move the class according to PSR-0/4 rules, and PHP will handle the rest for you.

For example, if you renamed ShoppingCart to Domain\Orders\Cart, you might do this:

class_alias('Domain\Orders\Cart', 'ShoppingCart');

Now when you call unserialize($shoppingCart) to create an object, PHP will create it as an instance of Domain\Orders\Cart instead of ShoppingCart. Re-serialized representations of the recreated object will retain the new class name, not the old one: O:18:"Domain\Orders\Cart":....

As soon as there are no more serialized representations using the old class name, you can remove the class_alias() call entirely.



The Failure of Female Engagement Teams in Afghanistan

Female Engagement Teams in Afghanistan were easily manipulated by the locals and proved to be largely ineffective in their intended counter-insurgency role.

...

Azarbaijani-Moghaddam found that the FETs were easily manipulated by Afghans with experience of three decades of relief and development interventions prior to the arrival of all these well-intentioned young military personnel in their area. There was, in fact, very little understanding within the military regarding the role of women, potential and actual, both within the insurgency in Afghanistan and in support of it. - See more at: http://spp.ceu.edu/article/2014-03-19/failure-female-engagement-afghnistan#sthash.1jqxoP9d.dpuf

Source: The Failure of Female Engagement Teams in Afghanistan | School of Public Policy


MLAPHP Boot Camp!

You may have seen my introductory talk on steps toward modernizing a legacy application at Nashville PHP or at php[world]. That was the presentation that formed the first few chapters of Modernizing Legacy Applications in PHP.

The MLAPHP book has been a great help to a lot of people. But there are a lot of other developers who learn best by watching-and-listening first, instead of reading. They know it can be a great help to have someone talk them through the whole moderizing process, and see the steps being performed.

Usually you have to go to a conference for that sort of thing. You have to pay for the ticket, and for the hotel, and for travel, and meals, and everything else. Even if your employer helps with the money, there's still the time involved: you have to be away for several days at a time.

Well, now you can have a conference-level training experience in the comfort of your own home, without the travel hassle and hotel expense. I have put together an online weekend "boot camp" where we go through the entire modernization process, from basic prerequisities at the beginning to setting up a DI container at the end. After that end-to-end study of the steps involved, you should be able to jump-start your own modernizing project much more easily.

The 8-hour camp will combine lecture and "live" coding with examples. In particular, there will be plenty of opportunity for you to get answers specific to your own modernizing situation, and to chat with other attendees.

The two-day camp will be on Sat 11 July and Sun 12 July. Each day will run from 12 noon to 4pm (US Central Daylight), with time for breaks built in. That makes it 10am-2pm for Pacific time zone attendees, and 1-5pm for Eastern, which should be convenient for almost everyone.

With your ticket to attend the boot camp, you get:

  • Two days of online boot camp, four hours each
  • A review of the entire modernization process from beginning to end
  • A bonus recording of the camp
  • For $399

This might be the only time I lead this kind of boot camp, so get your ticket while there are still seats available!



Technical Speaker Uninvited When SJWs Politicize Event

Latest hullaballoo: Curtis Yarvin (aka “Mencius Moldbug”) was invited to give a presentation on his new computer system Urbit to the Strange Loop tech conference. Then some of his ideological enemies (actually literal Communists) found out, objected to his political views, and he got banned from the conference.

Article here, Hacker News thread here, impressively prescient Moldbug post here, demonstration of inevitable Streisand Effect here.

I did consider not linking this since it’s so obviously toxoplasma, but I was convinced to do so by this letter where the conference organizer states he’s never read any Moldbug himself, but decided to cave to the ban request because otherwise politics overshadow the conference, which was supposed to be about tech.

This kind of crystallizes a pattern I’ve been noticing recently where some social justice activists use a tactic along the lines of “Nice institution youse gots here, shame if somebody were to politicize it”.

I sympathize with the desire to give into that to avoid trouble, but I think maybe the only way to avoid enshrining that kind of heckler’s veto always working is to make it clear that the choice to give in will also be politicized.

Maybe if organizers know that banning all insufficiently-leftist-people and not banning all insufficiently-leftist-people will both result in politicization and Internet firestorms, they’ll say “screw it” and just follow their principles.

Via Slate Star Codex. Apparently you're not allowed to speak about anything at all if you don't have The Right Political Opinions At The Right Time, especially when the #hashTagMob start bullying and heckling. The best response to the #hashTagMob is to double down and invite *more* people they disagree with. Giving in gives them the ability to say "See, we were right!" and then they'll do more of it. Once you pay extortion, you never get rid of the extortionist.


Relay: A PSR-7 Middleware Dispatcher

UPDATE (2015-06-09): Due to a conflict with the "pipeline" design pattern name, which this project does not implement, the project name has been changed from Pipeline to Relay. Links and naming have been updated inline, with the original text block quoted beneath.

In a fit of inspiration over the weekend, I extracted the middleware dispatcher from the Radar ADR core into its own standalone library: Relay. If you need to execute a queue of middleware, Relay is for you.

Relay uses a common PSR-7 middleware signature: function ($request, $response, $next) and return $response. That is what Slim 3 uses, along with Stratigility and Radar, and is modeled on Sencha Connect. Any callable/invokable with that signature will work with Relay.

As a standalone library, Relay is framework-independent, so you can use it anywhere. You could even build your own framework around it, picking a dotenv-loader of your choice, a DI container of your choice, and a middleware queue of your choice.

Speaking of DI containers, Relay is also container-independent. You can use any dependency-injection system you like to build your middleware queue and pass it to Relay. All you need to do is pass in a callable that converts each queue entry to an object or callable. Try it with PHP-DI, Pimple, Auryn, or even Aura.Di.

I have converted Radar to use Relay at its core, and soon I'll be extracting two of the basic Radar middleware classes to standalone packages. When I do, they'll be listed on the Relay wiki.

ORIGINAL RELEASE:

In a fit of inspiration over the weekend, I extracted the middleware dispatcher from the Radar ADR core into its own standalone library: Pipeline. If you need to execute a queue of middleware, Pipeline is for you.

Pipeline uses a common PSR-7 middleware signature: function ($request, $response, $next) and return $response. That is what Slim 3 uses, along with Stratigility and Radar, and is modeled on Sencha Connect. Any callable/invokable with that signature will work with Pipeline.

As a standalone library, Pipeline is framework-independent, so you can use it anywhere. You could even build your own framework around it, picking a dotenv-loader of your choice, a DI container of your choice, and a middleware queue of your choice.

Speaking of DI containers, Pipeline is also container-independent. You can use any dependency-injection system you like to build your middleware queue and pass it to Pipeline. All you need to do is pass in a callable that converts each queue entry to an object or callable. Try it with PHP-DI, Pimple, Auryn, or even Aura.Di.

I have converted Radar to use Pipeline at its core, and soon I'll be extracting two of the basic Radar middleware classes to standalone packages. When I do, they'll be listed on the Pipeline wiki.



Semantic Versioning and Public Interfaces

Adherence to Semantic Versioning is just The Right Thing To Do, but it turns out you have to be extra-careful when modifying public interfaces to maintain backwards compatibility. This is obvious on reflection, but I never thought about it beforehand. Thanks to Hari KT for pointing it out.

Why do you have to be extra-careful with interfaces and SemVer? To see it more clearly, let's use a concrete class as an example.

class Foo
{
    public function bar() { ... }
    public function baz() { ... }
}

If we remove a public method, that's clearly a BC break. If we add a non-optional parameter to an existing public method, that's also clearly a BC break. Those kinds of changes will break any code already using the Foo class; that code will have to be modified to accommodate the changes in Foo.

However, if we add a new public method to the concrete class, that is not a BC break. Likewise, changing the signature of an existing method to add an optional parameter is not a BC break either. (UPDATE: See note below.) Code using the Foo class does not have to change to accommodate the new method or the new optional parameter.

But what happens with an interface?

interface FooInterface
{
    public function bar();
    public function baz();
}

Removing a method, or adding a non-optional parameter to an existing method, is the same as with a concrete class: it's BC break.

However, unlike with a concrete class, adding methods is also a BC break. So is changing an existing method sigature to add an optional parameter. Existing code that implements FooInterface will no longer comply with the interface; that code will have to change to accommodate the new method or the new optional parameter.

Thus, interfaces are more susceptible to BC breaks than concrete classes. Once an interface is published as "stable", I don't see how it can be changed at all per the rules of SemVer (that is, unless you bump the major version). The only thing you can do to maintain BC is add an entirely new interface to the package while leaving the old one in place, perhaps even extending the old one if needed.

Again, it's obvious in hindsight, but I did not have the foresight to anticipate it. Perhaps this realization will save you some trouble in the future.

p.s. On further examination, the interface constraints apply to abstract classes, too. Changes to an abstract mean that child classes will have to be modified as well, otherwise they won't comply with the modified abstract.

UPDATE: Dave Marshall notes on Twitter that in the concrete class case, if you add an optional parameter to a method, and a user has extended and overridden that method, the extended class will break under PHP E_STRICT. He links to Symfony policy on the subject, which I will now have to read.



Radar: Answering Questions, and New Middleware

Last week’s announcement of Radar, an implementation of Action-Domain-Responder using PSR-7, was a resounding success. The feedback has been mostly positive, with some confusion and misunderstanding, and with one particular question being raised more than once.

This Reddit thread is typical of the various questions and comments I’ve received so far:

[“ADR” is just] the hipster slang for ‘c’, ‘m’ and ‘v’.

In other words, “Why ADR in the first place, and not just MVC?” This is answered by the ADR white paper, and again by some commentary here. In short, ADR is a refinement of “web” MVC to more accurately describe how we actually work in a request/response environment. The renaming of the components is intended to break the association with “real” MVC. (Special thanks to “lordofworms” for his patient and civil responses to the questioner.)

Why [is the project called] “Radar”?

As noted in the Reddit thread by others, “Radar” is a sound-alike from the ADR acronym. (An early version of the ADR paper was titled Request-Action-Domain-Response, the acronym for which lends itself even more to “Radar”, and I had that in mind too.)

why use classes at all? If most of your classes contain a single __invoke method, could they not just be substituted with namespaced functions?

The questioner was answered quite thoroughly on Twitter. I will add only that there’s nothing about ADR that says you must use classes. If you can implement ADR using all functions all the time, go for it. ADR is a pattern, not an implementation; Radar is an implementation, not a pattern.

Finally, we have this very good criticism referring to the middleware implementation:

Passing arguments by reference will confuse users.

Variations on this theme came up elsewhere as well. As a result, I have re-worked the middleware implementation completely.

Previously, Radar used a “filter” style of middleware, where an iterator calls each middleware handler in turn at different points in the execution path. This is the style used by Slim 2 and Silex, and works well with globally mutable request and response objects.

However, PSR-7 requests and response are immutable. I have not previously used immutables very much, and I tried to subvert the immutability by allowing middleware to use reference parameters. The references would make the request and response objects appear globally mutable, even though the objects were in fact immutable.

The critics who noted that this was potentially confusing, as well as a subversion of the immutable intent, turned out to be worth listening to. I experimented a bit with a wrapper-style (or chain-style) of middleware, and I’m much happier with it.

In the new implementation, each middleware calls the next one in turn, instead of an external iterator looping over them. (There is a Dispatcher object that “holds” the queue of handlers, and that it what gets passed to each handler for its $next call.) I got the idea from reading MWOP’s Conduit code, although this is greatly pared down from that. You can read more about the new implementation here.



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.