Over a million developers have joined DZone.

How a LazyDecorator can let your application avoid building massive object graphs

DZone's Guide to

How a LazyDecorator can let your application avoid building massive object graphs

· Web Dev Zone
Free Resource

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

Here's a performance optimization scenario: you have set up a large object graph, but only part of it is used to satisfy a single request to your application. In languages such as PHP that live in a shared-nothing environment, this can become wasteful as each new request creates the whole object graph again: each contained objects may depend on database connections or other limited resources that are set up every time but only needed in a subset of cases.

To avoid revolutionizing the design of the appication but at the same time only allocating the machine resources the application actually needs, two patterns come to the rescue: Lazy Loading and Decorators.

An example

Here is a Lazy Decorator I wrote after I found out we were using an array of Phonebook objects, each with its own dependencies, in a map where only one of them could be selected at each request. To optimize their creation, I substituted each of these Phonebooks with a Lazy Phonebook wrapping a closure capable of creating the original one.

class LazyPhonebook implements Phonebook
  private $factoryMethod;
  private $original;

  public function __construct($factoryMethod)
    if (!is_callable($factoryMethod)) {
      throw new ConfigurationException("The method that should create a Phonebook is not a callable.");
    $this->factoryMethod = $factoryMethod;

  public function nextStep(A $a, B $b, C $c)
    if ($this->original === null) {
       $this->original = call_user_func($this->factoryMethod);
       if (!($this->original instanceof Phonebook)) {
         throw new ConfigurationException("The method that should create a Phonebook returned something else.");

    return $this->original->nextStep($a, $b, $c);

A Decorators always implements the original interface, and this is a piece of advice about introducing interfaces while designing code: it lets you see seams where to insert structural well-known solutions such as Composite and Decorator which would not be available otherwise.

This Decorators forwards the call unaltered to the to wrapped object, but creating it first. The wrapped object is created one by closure injected in the constructor, but only once for each request. The overhead is just that of introducing a closure and a private field, which only influence fast resources such as CPU and memory (not touching the disk or the network).

Dynamic languages let us create closures quickly to get an indirection over the creation process, but in case of misconfiguration they can be hard to detect (you need end2end acceptance tests to exercise all creation code). The checks this code makes are that a callable must be injected, and that it should return an implementation of the selected interface when called.

From the dynamic point of view, note also that it's difficult to reuse this kind of code due to the implements keyword. Using implicit interfaces may let you write these Decorators by using __call(), but I found it safer to use type hints and strict, explicit interfaces to take advantage of PHP automatic checks while wiring objets together (not only for documentation purposes).

Use case

This is not the only alternative when it comes to create an indirection over the creation of objects for performance reasons: introducing a Factory that creates Phonebooks in the client code would be an equally functional solution.

The advantages of a Decorator approach are two.

First, it lets you change between the Lazy and Eager loading versions of the code (and back) very quickly, both while writing code (it's an Open/Closed Principle solution) and while setting up the wiring. If performance optimization of this creation is something you're not sure will always be needed, this is more flexible, while I may have gone for a PhonebookFactory if I knew about this from the start (who ever does?).

It minimizes the number of new interfaces needed, keeping just the Phonebook one instead of introducing also a PhonebookFactory along with it. This simplifies the unit tests, which can test real Phonebooks and Decorators in isolation; but also building up more designs as you can introduce other patterns on top of this one:

new SecurePhonebook(
  new CompositePhonebook(array(
    new LazyPhonebook(function() { return new ItPhonebook(...); }),
    new LazyPhonebook(function() { return new UkPhonebook(...); }),
  new SecurityGuard(/* list of allowed ip addresses */)


Wiring code is a great way to document your designs, as it's always in sync with the rest of the code while diagrams aren't. However, it's important to consider all non-functional concerns of your Factories: how readable they are, but also how efficient they are in creating objects to satisfy the most common use case in your application.

Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.


Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}