Strategy Design Pattern (Apex Design Patterns)

What is Strategy Pattern?: Strategy is a behavioral design pattern that lets you define a family of algorithms, put each of them into a separate class, and make their objects interchangeable.

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.

Why Strategy Pattern?:

Sometime the code becomes complex if there are so many code behaviors included in the same class and it become hard for a new developer to fix it. Also if the team size is big, it also become tedious for multiple developers to work on single class which uses mix of codes. So in order to override this problem, we create separate classes which includes specific type of behavior instead of mix behavior and call them using strategy during runtime.

Problem: You need to provide a geographical-based search engine solution where the implementing code can choose the search provider at runtime.

geocode('test center')
//=> 37.7845456,-129.3994262

Solution:

public interface GeocodeStrategy{
    List<Double> getLatLong(String address);
}
public class GoogleMapsStrategy implements GeocodeStrategy{
    public List<Double> getLatLong(String address){
        // Web service callout
        return new List<Double>{0,0};
    }
}
public class MapQuestStrategy implements GeocodeStrategy{
    public List<Double> getLatLong(String address){
        // Web service callout
        return new List<Double>{1,1};
    }
}
public class Geocoder {
  public class GeocoderException extends Exception{}
 
  public static final Map<String,GeocodeStrategy> strategies;
 
  static{
      
      // Populate a List Collection of strategy names e.g., googleMaps, mapQuest etc
      List<String> strategyNames = Label.strategies.split(',');
 
      // Populate a map of strategy names to concrete implementations
      // using Type.forName for each strategy string
      strategies = new Map<String,GeocodeStrategy>();
      for(String name : strategyNames){
          try{
              strategies.put(name, (GeocodeStrategy)Type.forName(name + 'impl').newInstance());
          } catch(Exception e){ //skip bad name silently
              system.debug(e.getMessage());
          } 
      }
  }
 
  private GeocodeStrategy strategy;
 
  public Geocoder(String name){
      if(!strategies.containsKey(name)) {
		throw new GeocoderException(name);
	  }
      strategy = strategies.get(name);
  }
 
  public List<Double> getLatLong(String address){
      return strategy.getLatLong(address);
  }
}
Geocoder geocoder = new Geocoder('googleMaps'); //It assigns instance of GoogleMapsStrategy to geocoder
System.debug('latitudes***' + 
             geocoder.getLatLong('test location1')); //It prints latitudes***(0.0, 0.0) in debug log
Geocoder geocoder = new Geocoder('mapQuest'); //It assigns instance of MapQuestStrategy to geocoder
System.debug('latitudes***' + 
             geocoder.getLatLong('test location1')); //It prints latitudes***(1.0, 1.0) in debug log

Let’s understand this code using below pictorial representation which is self explanatory-

Geocode Strategy

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.

For all Design Patterns, please refer this.

Published by Sandeep Kumar

He is a Salesforce Certified Application Architect having 11+ years of experience in Salesforce.

One thought on “Strategy Design Pattern (Apex Design Patterns)

Leave a Reply