Paul M. Jones

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

Doris Lessing on Communism and Language

It is not a new thought that Communism debased language and, with language, thought. There is a Communist jargon recognizable after a single sentence. Few people in Europe have not joked in their time about “concrete steps,” “contradictions,” “the interpenetration of opposites,” and the rest.

The first time I saw that mind-deadening slogans had the power to take wing and fly far from their origins was in the 1950s when I read an article in The Times of London and saw them in use. “The demo last Saturday was irrefutable proof that the concrete situation...” Words confined to the left as corralled animals had passed into general use and, with them, ideas. One might read whole articles in the conservative and liberal press that were Marxist, but the writers did not know it. But there is an aspect of this heritage that is much harder to see.

Even five, six years ago, Izvestia, Pravda and a thousand other Communist papers were written in a language that seemed designed to fill up as much space as possible without actually saying anything. Because, of course, it was dangerous to take up positions that might have to be defended. Now all these newspapers have rediscovered the use of language. But the heritage of dead and empty language these days is to be found in academia, and particularly in some areas of sociology and psychology.

via Questions You Should Never Ask a Writer - New York Times. Looks like she has a longer form of that article here.


PSR-4 "Autoloader" Has Passed

I wrote up the initial “Towards A Package-Oriented Autoloader” essay on 26 Mar, and the first formal proposal document on 03 Apr. Counting from the date of that first formal proposal, it has taken exactly 8 months of discussions, one botched vote, one rescinded vote, an entirely new FIG workflow, and four or five rewrites to get PSR-4 passed. Maybe 8 months doesn’t sound so long when you look back on it, but while you’re in the middle of it, it’s interminable.

The core concept has not changed since the initial essay: provide a way to map the “namespace prefix” of a class to an arbitrary directory, to make directory structures shallower than they are under PSR-0. This means no more empty directories in Composer (etc) packages just to suit the strict class-to-file rule of PSR-0, which itself is descended from the Horde and PEAR standards by way of Solar, Symfony, Zend, and others.

The initial implementation of the ruleset has not changed in any major way in that entire time, although the language describing the ruleset has gone through several major variations.

For what it’s worth, the existing Aura v2 libraries are already structured according to the PSR-4 rules, and work with Composer through their own package-specific autoloader files:

Many thanks to everyone who helped bring the initial proposal to its completed state. In particular, thanks to Beau Simensen who (on what turned out to be the final major rewrite) came up with the idea of mimicking the PSR-0 language style. Also, thanks to Phil Sturgeon, who (as sponsor and vote coordinator) finally saw fit to let a vote actually go through. ;-)



Quicker, Easier, More Seductive: The Difference Between Factories, Registries, and Service Locators

In last week’s episode of this unexpected series, I said, “Go ahead and use Service Locator, but make sure each Locator contains only one type of object. This condition of restraint will keep a single locator from becoming a menace.” (I recommend “real” dependency injection containers as the preferred inversion-of-control mechanism; try the Aura.Di container.)

The “only one type of object” constraint generated some discussion regarding factories and registries. On Reddit, teresko commented:

I don’t think I have ever seen a use of Service Locator where it adhered to this rule. Hell … I am not even sure that you can call it “Service Locator” then, because it is just a smarter sounding name for Registry pattern.

When you apply this rule, what you get instead is a factory, which enforces uniqueness of an instances, that it creates.

On the blog itself, Adrian Mu asked:

In the case of the Aura’s filter package am I wrong to interpret the “rule service locator” as a “rule factory”? If no, what is the difference between a factory and a service locator as you describe it? If yes, where?

And on Twitter, Taylor Otwell asked a similar question:

that “one type” of service locator is just a “factory”, right?

The differences between factories, registries, and containers (both service locators and dependency injection containers) can be subtle and hard to grasp at first. Here’s how I keep them straight:

  • a Factory creates and returns an object, but does not retain the created object for future use;

  • a Registry retains an object instance by name for repeated use, but does not create that object;

  • a Service Locator contains a named object (a “service”) and creates it if it
    has a definition for that service; the creation logic might itself be a Factory, and the retention logic might itself be a Registry.

By way of example, I have put together an example service locator implementation along with an embedded test case. It has only two methods: set() and get():

  • The set() method takes an object name as its first argument, and
    a factory (in this case, a callable). The factories are retained in a registry (in this case, a plain-old PHP array).

  • The get() method looks in a registry of instances for the requested object by name and returns it. If the object is not there, it uses the factory for that object name and retains it in the instance registry.

Here’s an example use:

<?php
// create the service locator
$locator = new PmjonesServiceLocator;

// add a factory; this can be any callable, whether
// a closure, an object with an __invoke() method,
// a function name, a static class method, an object
// instance and method name, etc.
$locator->set('my_object', function () {
    return new VendorPackageClassName;
});

// get back an object instance; the locator
// will create and retain it the first time
$one = $locator->get('my_object');

// the next and subsequent times, the locator
// return the same instance
$two = $locator->get('my_object');
var_dump($one === $two); // true
?>

That should help illustrate the difference between a factory, a registry, and a service locator.

Again, I must stress: Service locators can easily get out of control. If you can avoid using a service locator, you should. Instead of service locators, use dependency injection proper as much as possible, even though it is more work up front. If you must use a service locator: place only one type of object in it, use multiple locators if necessary, and inject each locator instead of using static calls for access.

Afterword

In Aura, we use dependency injection everywhere, all the time. In the rare cases that a service locator makes sense, that locator follows the “only one type of object” rule, and the locator itself is injected via the DI container. This makes the codebase very clean and a lot easier to test.

If you like clean code, fully decoupled libraries, and truly independent packages, then the Aura project is for you. Download a single package and start using it in your project today, with no added dependencies.



Quicker, Easier, More Seductive: Restraining Your Service Locators

tl;dr: Go ahead and use Service Locator, but make sure each Locator contains only one type of object. This condition of restraint will keep a single locator from becoming a menace.

Quicker, Easier, More Seductive

I mentioned in passing last week, “When it comes to Inversion of Control, a Service Locator is like the Dark Side of the Force: quicker, easier, more seductive. But it gets you into trouble later on. Go with Dependency Injection whenever you can instead.” I want to elaborate on that a bit.

The question is not “Which is better and which is worse, DI container or Service Locator?” The question is “What are the proper limits on DI containers and Service Locators?”

To establish my bona fides here, I’ll point out that I used Service Locator almost exclusively for several years. Solar::dependency() was Solar’s inversion-of-control system, and it was very useful for its purpose. But knowing what I know now, it is much more a Service Locator than a Dependency Injection container. (As a side note, universal constructor was a natural outgrowth of having a Service Locator try to take on Dependency-Injection-like behaviors.)

Service locators are a great boon, and very easy to set up and use. But they also present great problems as systems grow larger. Testing becomes more and more difficult. Dependencies are obscured. If the locator is used via static methods, it’s even harder, and more obscure.

Dependency injection containers take more up-front setup, and more up-front skill and discipline on the part of the developer. They are harder to understand, and it’s harder to get the concepts that go along with DI containers (factories in particular). I’m not kidding when I say it took me a year (!) of reading Misko Hevery and getting input from more experienced DI developers before I began to get it.

It is for that reason I say that Service Locator is “quicker, easier, more seductive.” It’s not that Service Locator is bad, it’s that it gets out of control very quickly.

Restraining Your Service Locators

Service Locator still has a useful purpose, but its scope must be limited to make sure it does not grow into a monster. Other people have suggested various rules on when to use a Service Locator, and when to use a Dependency Injection container. I will not add to those rules.

Instead, I will tell you to go ahead and inject a Service Locator (no static calls!) but on one condition:

A Service Locator should contain only one type of object.

When I say “type” I don’t mean “anything my controller might happen to need.” I mean, loosely speaking, “one class of object” or “objects with the same purpose”. For example, the Aura filter system uses a locator to make different validation and sanitizing rules available. The v1 view package uses a locator for the helper objects; we have gone so far as to extract the locator and helpers to their own package in v2. Note that these locators are highly specific and handle only one type of object.

  • What if you need multiple types of objects? Inject multiple types of Service Locators.

  • What if you only need one each of several different objects? Inject those objects directly, probably via constructor arguments, instead of retrieving them from a Service Locator.

  • What if some of the objects are optional, or only needed some of the time? Inject them via setter methods.

  • What if it ends up that you genuinely need to inject lots of different locators? Take it as a sign that you need to refactor the object that needs the many different locators. Consider wrapping those parts of the object into a service, inject the locators to the service, and inject the service to the original object.

  • If you find yourself injecting a Dependency Injection container into an object so that the object can retrieve dependencies from the container, you are using the Dependency Injection container as a Service Locator. The "only one type of object" rule applies in that case. The only way around it is to stop injecting the Dependency Injection container and instead inject a particular Service Locator, or to inject the specific needed objects.

The condition of “only one type of object” is imperfect, but it should begin set you on the correct path; that is, toward being able to identify dependencies. The goal is not immediate perfection, but gradual improvement. The idea is to purposely make Service Locator a little less seductive, to add constraints to it, so that it does not become a menace later.

Afterword

If you like clean code, fully decoupled libraries, and truly independent packages, then the Aura project is for you. Download a single package and start using it in your project today, with no added dependencies.



ServiceLocator is like the Dark Side: Quicker, Easier, More Seductive

When it comes to Inversion of Control, a Service Locator is like the Dark Side of the Force: quicker, easier, more seductive. But it gets you into trouble later on. Go with Dependency Injection whenever you can instead.

A lot of things calling themselves Dependency Injection containers are actually Service Locators. If you inject the container into an object, or if you call it statically from inside an object, and the object then pulls things out of the container, the container is acting as a Service Locator.


A Peek At Aura v2 -- Aura.Router

Most routing systems combine the “routing” task with the “dispatch” task. That is, they both extract the parameters and pick the controller/action. Aura.Router v2, because of its truly independent nature, only does routing. It turns out that dispatching is something that can be independent of routing, and so we have a separate Aura.Dispatcher package to handle that (although you can use any dispatching system you like).

Aura.Router v2 allows you to examine the $_SERVER values and pick a route based on them using the addServer() method. For example, if you want to match routes based on the HTTP_ACCEPT value …

<?php
$router->addRoute('json_only', '/accept/json/{id}')
->addServer(array(
  // must be of quality *, 1.0, or 0.1-0.9
  'HTTP_ACCEPT' => 'application/json(;q=(*|1.0|[0.[1-9]]))?'
));
?>

Sometimes we need a params in the route path to be sequentially optional. The classic example is a blog archive organized by year, month, and day. We don’t want to have to write three routes, one for /{year}, /{year}/{month}, and /{year}/{month}/{day}, each with repeated information about the route.

In Aura.Router v2, there is a special notation similar to URI Templates that indicates sequentially optional params: {/param1,param2,param3}

We can now add REST resource routes in a single call to attachResource():

<?php
$router->attachResource('blog', '/blog');
?>

This will add seven REST routes with appropriate names, paths, HTTP methods, and token regexes …

If you decide those routes are not to your liking, you can override the default behavior by using setResourceCallable() to pass callable of your own to create resource routes.

Via A Peek At Aura v2 -- Aura.Router.


If you respect a [developer], you talk about the [code]; if not, you psychoanalyze the [developer].

... if you respect a writer, then you talk about the work. If you disdain the writer, then you try to psychoanalyze the writer and figure out why would he write this. ... If they mention my work at all, which they rarely do, it’s to dismiss it and to psychoanalyze me, which they are incapable of doing ... They have no idea what I’m talking about.

A lot of criticism is like, including project criticism. Via Critics, community and 'Ender's Game': An interview with Orson Scott Card | Deseret News.


A Peek At Aura v2: Aura.Web

... it turns out extracting Aura.Dispatcher was the key to reducing the Aura.Web package contents. With Aura.Dispatcher, any object can be a controller, since it can dispatch to any method on any object (as well as dispatching to closures). In turn, there is no more need for the Aura.Web package to provide a base controller with interfaces for various implementations. Instead, you can dispatch to any object you like, with the dependencies you prefer, as your controller. That controller object can be implemented at the framework level, or in a separate package or bundle.

As a result, this means that web-specific request and response objects can be in their own package independent of any particular controller implementation. The Aura.Web v2 package contains only those request and response objects.

via A Peek At Aura v2 -- Aura.Web.


A Peek At Aura v2: Aura.Dispatcher

It turns out that dispatching at the framework level, and at the web and CLI levels, is all remarkably similar. After realizing that, we extracted the dispatching logic to its own independent package, without any dependendcies on any other packages.

The Aura.Dispatcher package lets you define named objects that will get instantiated only as they are dispatched to (i.e., lazy loading). It picks which named object to instantiate, and optionally which method to invoke, based on an array of router values (or any other array you wish to pass). It also works as a micro-framework dispatcher; instead of using an object factory proper, you can add a named closure and that will be invoked.

Additionally, if you want a two-stage invocation where the dispatcher picks an object, and the object picks its own method, Aura.Dispatcher comes with a trait that lets you pass named parameters to any method you like. You can use that trait in any object to pick a method and invoke it with the router (or other) parameters.

via A Peek At Aura v2 -- Aura.Dispatcher.

If you like clean code, fully decoupled libraries, and truly independent packages, then the Aura project is for you. Download a single package and start using it in your project today, with no added dependencies.