Uncover the Alias Pattern

May 11, 2022
oop design pattern object thinking

The article cover

While I write OOP code I apply some practices of Elegant Objects.

One of them is that classes should be final. This means that they cannot be extended through inheritance but only through composition.

The advantage is simplicity. I mean that, in this way, each object is seen as a cohesive block. What interest to its clients is its exposed behaviour. Nothing more. Instead, through extension, a client can break it.

For instance, an object can interrelate two of its methods. So, if we can replace through extension one of them we can break the other. For this reason, to be sure, we should check its implementation. In this way we increase coupling between the extended and the extension.

In other words, final classes enforces the idea that we should care only of exposed behaviour. And not of implementation. Nonetheless, it requires a change of how we reason about them. The Alias pattern simplifies an aspect of this change.

Intent

The Alias pattern allows to extend the way a class can build its objects without subclassing or modifying it.

Motivation

Suppose a final class that creates its objects using some mandatory parameters. How can we add another way to create its objects? For instance, how we can add a constructor that use a default value for one or more of its missing parameters?

One approach could be to add another constructor to the class. But this could get out of hand. Furthermore, it could be not possible. For instance, the aforesaid final class could be in an external library.

Another drawback of this approach is that we can pollute the final class. For instance, we can have a final class that builds its objects given a JSON. But after some time we need to add also XML. As you can imagine adding the code to map XML to JSON will pollute inevitably that class.

However, the Alias pattern isn’t limited to final classes. For instance, we cannot have two constructors with same parameters but different semantic.

To resolve this issue we can add static factory methods to the class code. But the same aforesaid drawbacks affects this approach. That is: this gets out of hand; this couldn’t be always possibile; this will pollute the class.

A better approach to both problems is to create another class with the desired constructor behaviour. This class encapsulates its own construction logic. And it will delegate everything to the other class, including the actual creation. This is the Alias pattern.

Applicability

Use the Alias pattern when:

Structure

The structure is simple. We need at least two class that implements the same interface: an Alias and an Aliased.

The Alias pattern UML structure

Partecipants

Collaboration

Consequences

The Alias Pattern has the following consequences:

Implementation

To implement the Alias pattern you need:

  1. to define an interface;
  2. to implement the previously defined interface with a class. This will be the aliased one;
  3. to implement the previously defined interface with an alias class, and you need:
    1. to define a constructor that builds an aliased object according some needs;
    2. a private instance variable that reference to the previously built aliased object;
    3. to delegates everything to the aliased object.

Sample Code

The below Java-ish code expresses the Alias pattern. In this code the alias injects a default value for an otherwise mandatory parameter:

interface AnInterface {
    void aMethod();

    Something anotherMethod();
}

final class Aliased implements AnInterface {
    private final A a;
    private final B b;

    Aliased(final A a, final B b) {
        this.a = a;
        this.b = b;
    }

    void aMethod() {
        // implementation
    }

    Something anotherMethod() {
        // implementation
    }
}

final class Alias implements AnInterface {
    private final Aliased aliased;

    Alias(final A a) {
        this(
                new Aliased(
                        a,
                        new InstanceOfB(...)
                )
        );
    }

    private Alias(final Aliased aliased) {
        this.aliased = aliased;
    }

    void aMethod() {
        this.aliased.aMethod();
    }

    Something anotherMethod() {
        return this.aliased.anotherMethod();
    }
}

Related Patterns

At a certain degree, the Alias pattern could be also seen as a way to decorate the objects construction. This vision is especially true if we see a class as an object which responsibility is to create objects.

Playwright on Steroids: Overcoming Limits With Object-Oriented Programming

November 14, 2023
playwright oop object thinking multithreading performance java

Object Thinking, Boundaries and Reality

January 29, 2022
oop object thinking java

Implementing an Event Loop in Java for Fun and Profit

November 12, 2021
oop event loop object thinking java