Apex allows you to build just about any custom solution on the Force.com platform. But what are the common design patterns and associated best practices for Apex development, and how can you leverage these patterns and best practices to avoid reinventing the wheel?
This article describes how to leverage common design patterns to optimize your code and ensure reusability, maintainability and performance. This is a wiki version of the Dreamforce 2012 presentation 'Apex Design Patterns'.
The following are a list of design patterns, some of which are standard object-oriented patterns in a Force.com context, and some of which are specific Force.com patterns.
The Singleton pattern attempts to solve the issue of repeatedly using an object instance, but only wishing to instantiate it once within a single transaction context. Common uses for this pattern include:
However, it's most common use is to create an object instance that's instantiated only once for the lifetime of that execution context.
Developers often write inefficient code that can cause repeated instantiation of objects. This can result in inefficient, poorly performing code, and potentially the breaching of governor limits. This most commonly occurs in triggers, as they can operate against a set of records.
The following code shows an example of repeated code invocation that can result in a breach of governor limits:
The trigger will cause a repeated execution of the sObject getDescribe() method, resulting in a breach of the total number of describes governor limit if the trigger operates against more than 100 records.
In order to implement a Singleton pattern in Apex, the class must instantiate only a single instance and be globally accessible. It is implemented by:
The following code sample demonstrates an implementation of the Singleton pattern for returning a record type describe within a trigger:
The Singleton Class
The above code demonstrates the following:
This allows the trigger to obtain a reference to the record type without breaching governor limits.
The following code sample shows how to use eager-initialization so that a new instance is always created when the class is instantiated.
The Singleton Class - Eager Initialization variant
The instance of the class is instantiated as a final, static variable, which means that only one instance ever exists. This method is typically used if the cost of creating the instance is small.
The Singleton design pattern allows Apex code to repeatedly reference an object instance in an optimal manner, whilst mitigating the impact of governor limits.
The Strategy pattern (aka the policy pattern) attempts to solve the issue where you need to provide multiple solutions for the same problem so that one can be selected at runtime.
You need to provide a geographical-based search engine solution where the implementing code can choose the search provider at runtime.
In order to implement a Strategy pattern in Apex, you need to define a family of algorithms, encapsulate each one, make them interchangeable, and selectable at runtime. It is implemented by:
The following code demonstrates an implementation of the Strategy pattern for the underlying GeocodeService strategy and implementations.
So the specific Unified Modeling Language (UML) for this implementation is
Now that we have our core strategy interface and implementations, we need to make use of them. There are a couple of ways you might be tempted to do this, however, in order to decouple as much as possible, consider the following:
As you can see above, the calling code has a choice of implementations and the only change is the string passed to the Strategy interface.
The Strategy design pattern uses aggregation instead of inheritance, allowing better decoupling between the behavior and the class that uses the behavior. This allows the behavior to be changed without breaking the classes that use it, and the classes can switch between behaviors by changing the specific implementation used without requiring any significant code changes.
The Decorator pattern attempts to solve the issue where you need temporary fields for processing (typically in Visualforce) but do not need to add these fields to the sObject.
Common uses for this pattern include:
This pattern is primarily for Visualforce use cases.
You need to obtain or display temporary information on a Visualforce page that is not needed beyond the context of the interaction.
In order to implement the Decorator pattern in Apex, we need to be aware that this is not a true OO implementation, but the intent is to add behavior at runtime rather than via inheritance at compile time. It is implemented by:
Note that this is not a “true” implementation of the OO Decorator pattern:
In our example scenario, we have a Weather sObject with City__c and TempInFahrenheit__c fields, and our Visualforce requirements are:
The Code - Decorated sObject Class
The above code demonstrates how the decorator class extends or wraps the Weather sObject with new functionality.
The Code - Custom Controller
The above code demonstrates how the Weather Controller is the client
The Code - Visualforce Page
The above code demonstrates that the Visualforce page only needs to implement a little AJAX action support to rerender the page if the temperature changes. There is no real client side logic and no other fancy tricks, just a simple rerender. The getter and setter in the decorator class takes care of all the work.
So what we have is an example of how to extend sObject functionality in Apex with behavior at runtime, rather than through inheritance using a pseudo decorator pattern. Most of you will have seen this done with selection checkboxes, but it’s something that can be applied with other use-cases as well.
The primary purpose of the Facade pattern is to provide a simpler interface to a complex class. This avoids repeated code and increases maintainability. Common uses include:
This pattern effectively abstracts one or more complex classes, simplifying their execution for the rest of the application.
Often times, the execution of a particular class method requires multiple lines of code or is complex in nature. If the same code is repeated multiple times across different parts of the application, this degrades maintainability.
In Force.com, one of the biggest examples of this is the execution of Web Service callouts. The generated Apex code often times requires complex code, such as setting timeout values, setting the target host, as well as setup of the various inputs and parsing of the callout results.
The following demonstrates the issue of repeated code when executing Web Service callouts, especially if the business process requires the execution of multiple web services.
In the above example, multiple clients attempt to create an account and contact in a target system. This results in repeated code to setup two web service proxies, degrading maintainability.
To implement a facade class, simply create another class that abstracts the implementation of the complex class(es). This facade class usually contains a simpler interface and in some cases, orchestrates the execution of multiple complex classes.
The purpose of the facade class is to simplify the execution of one or more complex classes with a simpler interface, increasing maintainability.
The following code sample shows a facade class that orchestrates the creation of an account and contact in an external system by calling multiple web services:
In the above facade class:
The facade class is then called in other parts of the application as follows:
The Facade design pattern increases the maintainability of Apex code by simplifying the execution of one or complex classes with a facade class.
The Composite Design Pattern allows for representation of expressions, such as;
Our developer has a requirement to create a custom version of the Create/Edit List View screen. However, he is really struggling with how to represent an expression (outlined in red). The difficulty is due to the level of recursion involved.
Note: This discussion does not cover developing the actual screen or parsing the expression - it is limited to representing an expression in Apex.
To implement the Composite Design Pattern, deploy the following interface and classes in your environment.
The examples below illustrate how to use the Expression interface.
Example: 1 AND 2
Example: 1 OR (2 AND 3)
Example: Method Chaining
Example: 1 OR (2 AND 3)
The Composite design pattern can be used to represent an expression in Apex regardless of expression complexity, whilst mitigating the impact of governor limits that can result from recursions.
The Bulk State Transition design pattern is a general pattern used for performing bulk actions in Apex based on the change of state of one or more records.
Our developer has written a trigger to create an order upon the close of an opportunity, however, he has noted that:
The Offending Code
The above code has more than a few issues. Namely;
Our developer has rewritten the offending code, this time using a trigger and class.
Attempt 2: Trigger
Attempt 2: Class
While his second attempt improves reusability, there are still the issues:
Our developer makes yet another attempt at addressing these concerns.
Attempt 3: Trigger
Attempt 3: Class
This last attempt is slightly better. At least it now handles state transition (i.e. only if the opportunity is closed). Also, it's now bulkified – separate list to keep track of orders, and a single bulk insert. However, the order class is highly coupled and is very hard to reuse outside of the trigger context. You can pass in null into the second argument, but that relies on you knowing the inner workings of the class.
In the Bulk State Transition design pattern:
We will implement the Bulk State Transition pattern utilizing two components:
Above, we have the trigger, OpptyTrigger:
Above we have the utility class, OrderClass:
With the above example, we've demonstrated implementing the Bulk State Transition design pattern as a means to perform bulk actions in Apex based on the change of state in one or more records.
Dennis Thong is a New York-based Director of Technical Architecture in Salesforce Services. An industry veteran with 13 years in building and architecting CRM solutions, he specializes in all things platform related, including integrating with, securing, and customizing Salesforce.com. If he's not working for a customer, he's trying to find the best coffee in the city.
Manu Erwin is a Cloud Computing professional with experience of implementing varied, full lifecycle CRM solutions. With over 5 years at Salesforce.com, 7 years working with the product, 6 years technical support management experience, and 11 years global consulting experience (Deloitte AU & US, Salesforce EMEA & APAC). Read more...
Eric Santiago has been involved with the Salesforce platform since 2005. As a Technical Architect with the Salesforce Services team, he has a broad expertise in all aspects of the platform particularly Apex/VisualForce development, Sites, and Portals. Eric loves adventure travel and has visited 28 countries on 5 continents. He is based in New York City.