GoF Design Patterns For Apex
Notes about the book “Apex Design Patterns” by Jitendra Zaa and Anshul Verma.
I read the book and make smth-like bookmarks about patterns on my Twitter. External sources to better understand the idea of some patterns were the original book by GoF, my enterprise experience and Google search. This paper is a compilation of my notes.
And a small introduction. “The motive of the design patterns is to design an application with loosely coupled layers and easy-to-maintain and reusable code. While developing the code, keep in mind that it is going to change in the future. How less and easily the code can be changed defines the proper usage of design principles and patterns.” One more point is it’s easier to understand a code base when you see familiar concepts.
Creational P. 🆕
- Factory method
- Abstract factory
- Singleton
- Builder
- Prototype
The Factory method p. (Virtual Constructor) — a concept of delegating the creation of similar types of classes.
The Abstract factory p. (Kit) — a families producer of related objects without specifying their concrete classes. It unites a number of factory methods.
The Singleton p. It’s needed to work with some limited or costly resources as only one class instance (getInstance () and a private constructor). Useful to set up a connection with DB for example. But don’t use singleton class in a global context, better to use it on low layers.
The next creational pattern is “Builder” which is used to instantiate an object of a complex class using the step-by-step approach and return a constructed object at once.
Table to compare Builder 🏗 with Abstract Factory 🏭
Share a little UML with Builder class for creating objects for testing in Salesforce Apex (create = insert to DB in test mode, build = exists during transaction only). The interesting thing is a chain ⛓ of Builder and Factory p.
One more about a Factory — Salesforce Apex Selector sample and schema (sorry, NDA). But I can say about our reference.

The Prototype p. is about creating a new object on the basis of an existing object of the same type. We control how data is copied or shared with a new object.
“There is one more approach frequently followed by Salesforce developers to clone a complete Apex class, which is by serializing it as JSON and then deserializing it back to an approach Apex class type,” said authors and it has a place to be.
Structural P. 🧱
- Façade
- Adapter
- Bridge
- Composite
- Decorator
- Flyweight
The Façade p. is used to convert complex classes into simplified classes or interfaces with a number of methods where groups of classes are either wrapped into one class that knows the logic of a complex process.
The problem for the client is too complicated and waste logic to launch. “Code work with a set of objects that belong to a library or framework. Ordinarily, we need to initialize all of those objects, keep track of dependencies, execute methods in the correct order, and etc”.
The façade is widely used in API development to provide easier client interaction.
The Adapter p. adapts one interface to another. Two incompatible classes should interact with each other, without those classes knowing about each other’s implementation.
2 types — object adapter (only one third-party library) and runtime adapter (dynamically created object of adapter interface by i.e. a factory).
Both the façade and adapter p. use the wrapper class. However, the adapter p. is used to allow interactions between the exciting systems. but the façade p. is used to create a new simplified interface.
The Bridge p. decouples an abstraction from its implementation so both parts can be changed independently.
In the ⬆️ example CoreFramework class consists of a reference to the Theme class.
Bridge VS Adapter
“The adapter p. works for the existing code; however, in the bridge p. we design it from the beginning.”
Bridge VS Strategy
“The strategy p. is meant for runtime polymorphism. The bridge p. is a structural p. where the code changes frequently and its implementation is decoupled from its abstraction”.
The Composite p. helps interact uniformly with a part as well as a part-whole hierarchy (an object and a group of objects). “In OOP with a part-whole relationship, an object has its own life cycle and can be part of the other object.”
This p. uses the concept of the Liskov substitution principle, “where objects in an app should be replaced by instances of their child implementations without altering the correctness of a program.”
The Decorator p. adds additional functionality to the existing objects at runtime to achieve a single objective. The idea is composition (or aggregation) can be most beneficial than inheritance in some cases. Good illustration with a pizza as an example.
The Flyweight p. improves memory usage using shared objects.
After discussing how to create objects or structure our code to enhance its modularity and reusability, we can focus on communication between objects and keep them loosely coupled at the same time
Behavior P. 🙌
- Chaing of responsibility
- Command
- Interpreter
- Iterator
- Visitor
- Memento
- Observer
- State
- Strategy
The Chain of responsibility p. follows the launch and leaves the design with a single execution path, allowing more than one object to process the request.

How our Validators work:
The Command p. is used to create an instance of operation, thereby enabling it to be passed and queued. The p. separates a requestor from a receiver so that receiver can invoke the processor without knowing the requestor.
“The point here is what 👐 is to be done and when ⏰ to do it. A requestor knows what is to be done and provides the info to a receiver. A receiver just knows when it has to be done and invokes the process appropriately.”
The Interpreter p. helps in designing a code structure to interpret a language by dividing the language into various grammatical constructs.
The Iterator p. Problem: you have a collection of a complex data structure and want to iterate over it or want to overwrite the traversal behavior of a collection. Solution: to extract the traversal behavior of a collection into a separate object called an iterator.
The Visitor p. is often associated with a double dispatch problem, so first of all let’s define dispatches.
The typical example for the single dispatch is a standard virtual method, which is polymorphic on the containing object’s type. I think all is clear with the concept.
DOUBLE dispatch is polymorphism on two parameters. The problem case is when there is a complex object structure with many classes and different interfaces and a client needs to perform several operations on these objects depending on their CONCRETE classes.
Code is a better language to understand:
So Visitor p. is used to separate the algorithm from the object structure on which it operates. And if an object has special logic for concrete class we can call the method despite the double dispatch.
The Memento p. is devised to handle scenarios where the internal state of the object is to be persisted at various points in time. It’s just like keeping multiple versions to enable reverting to any previous version if needed.
“The Observer p. is a p. in which an object (a subject or publisher) maintains a list of all its dependents (an observer or subscriber) and notifies them whenever there is any change in its state”. In SF we can create an Object and write a Trigger on it.
This p. is really familiar for JS devs or reactive programming enthusiasts.
The State p. helps to encapsulate the state’s specific behavior on an object. The key thing is that the behavior of functionality is dependent on the state of the object. A case from me is a chatbot when there are different user commands and special logic to launch them.
The Strategy p. is used to determine an algorithm at runtime. The idea is to define a family of algorithms, put each of them into a separate class, and make their objects interchangeable.
My recent experience of data export in CSV (and excel in future) format realization with Strategy p.

And the last chapter in “Apex Design Patterns” book is Handling Concurrency in Apex. “In this chapter, we learned that Apex is very different from other programming languages when it comes to handling concurrency issues…
…Due to these differences, we cannot use many concurrent design patterns that are accepted by the industry, in Apex”. This is so soft words how to say that Apex is the worst in concurrency programming 👎
However, there are some small opportunities to make something async.
Also, check my notes about “Clean Code” [RU]