Patterns in Apex: Dependency Injection, Strategy, and Decorator

by Aidan Harding - April 19, 2018

When you start out in Salesforce development, there seems to be little need for software design patterns. Perhaps because development starts with little triggers doing this and that in a few lines of code. But, as soon as the requirements, codebase, and team-size grow, then the advantages of patterns and other software engineering practices kick in.In this article, we’re going to look at three patterns (which overlap) and help us to solve a problem that many Apex coders will be familiar with.

The Problem

Suppose you’re writing a function that receives a list of Contacts and needs to return them in reverse order of LastName. When you need to sort, you immediately reach for the sort() method of the standard List class. But it’s not quite that simple. sort() works by requiring the elements in the list to implement the Comparable interface (plus accepting some built-in types that don’t implement Comparable but only sort in a non-configurable way).

So, the standard approach is to write a wrapper class that contains a Contact and implements Comparable in the way you need e.g.

Make a list of wrappers, put all the Contacts into wrappers, sort it, make a list of Contacts, copy all the contents of the wrappers into that final list. Who has time for all that?

The Solution

The alternative is to write our own sorting implementation which is not configured by properties of the elements in the list. Instead, it’s configured by an object that we pass in at the time of construction. This is dependency injection. The sorting algorithm depends on being given a method to compare elements, and we’re going to supply (inject) that dependency when we create an instance of the sorter. Get this right, and we’ll have two great benefits:

No need to marshall all our sObjects into a wrapper just to sort them

No need to implement Comparable in our own classes (along with possible configuration to allow sorting by different criteria) just to make them sortable. Importantly, if I wrote a class last year, and today I decide that I need to sort lists of that object, I don’t need to modify that class to make it sortable

The first piece of the puzzle is to define an interface for comparing two objects. Like Comparable , but not tied to the objects we’re comparing:

public interface Comparator {
// Compares its two arguments for order. Returns a negative integer,
// zero, or a positive integer as the first argument is less than,
// equal to, or greater than the second.
Integer compare(Object o1, Object o2);
}

Then, we can write a sorting class which uses an instance of Comparator to do the comparisons:

We won’t get into the details of the quicksort sorting algorithm, but we will note that in lines 29 and 31 we are using the Comparator to compare the elements. The Quicksort class doesn’t entirely perform a sorting algorithm, it is missing the part where it knows exactly how to compare two elements in the list. That detail is provided at runtime by passing in a instance of Comparator. This is a use of the Strategy Pattern and, as we noted before, dependency injection.

What if I wanted to reverse the ordering? Do I have to write a new Comparator for each combination of sorting criteria that I’ll ever want? Or maybe one MegaComparator with lots of parameters and switches? No… we can keep things clean by using the Decorator Pattern. This allows us to modify the behaviour of a Comparator by wrapping it inside another one (decorating it). For example, we can write a reversing comparator like this:

If you’re a Java programmer, you’ll be familiar (and probably a bit frustrated by) the decorator pattern due to its extensive use in the IO libraries (Reader , BufferedReader , etc.).

If you’ve been paying very close attention, you’ll notice that ReverseComparator is using dependency injection and the strategy pattern on its way to being part of the decorator pattern.

Final Thoughts

This all seems like fun, but do you use it every day? I don’t write the utility classes with these patterns every day, but I do use code written with these patterns every day. When you’re trying to pull out general solutions that you can re-use everywhere, and pondering how to make them configurable for scenarios that you can’t yet imagine, these patterns give you some great ways to build in all the flexibility that you need. So, if you’re a senior engineer building some of the tracks for your colleagues to run on, this gives you a great way of doing it.

For example, we have utility classes to convert sObjects to/from JSON using metadata to specify the JSON structure. How can you deal with external systems that have a million different ways of storing dates? Or when they decide to store some numbers in strings? By writing the utility classes with the strategy pattern, and allowing the developer in a specific situation to fill in those details themselves. The utility class can deal with how to fetch Contact.Account.Name through those object relations, and it can deal with building nested JSON objects. You can concentrate on whether or not there should be a ‘T’ or not between the date and the time on this particular integration.