Apex Design Patterns in Salesforce

Apex Design Patterns in Salesforce

Singleton:
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.

Sample Code:


Apex Class:
public class Utility {
    
    public static Utility objInstance = null;
    public Integer acctCount;
    
    public Utility() {
        acctCount = [ SELECT COUNT() FROM Account ];
    }
    
    public static Utility getInstance() {
        if ( objInstance == null )
            objInstance = new Utility();
        return objInstance;
    }
    
}


If you execute the below code, the SOQL will be executed only once.

for ( Integer i = 0; i < 3; i++ ) {
    Utility obj = Utility.getInstance();
    system.debug(‘Count is ‘ + obj.acctCount);
}


Strategy:
Defining a family of algorithms, enscapsulating each one and making them interchangeable and selectable at runtime.

Sample Code:

1. Create an interface.

public interface Strategy {


   Integer doOperation(Integer num1, Integer num2);
   
}


2. Create concrete classes implementing the same interface.


public class OperationAdd implements Strategy {


   public Integer doOperation(Integer num1, Integer num2) {
      return num1 + num2;
   }
   
}


public class OperationSubstract implements Strategy {


   public Integer doOperation(Integer num1, Integer num2) {
      return num1 – num2;
   }
   
}

3. Create Context Class.

public class Context {


   private Strategy strategy;


   public Context(Strategy strategy) {
      this.strategy = strategy;
   }


   public Integer executeStrategy(Integer num1, Integer num2) {
      return strategy.doOperation(num1, num2);
   }
   
}

4. Use the Context to see change in behaviour when it changes its Strategy.

      Context context = new Context(new OperationAdd());
      System.debug(’10 + 5 = ‘ + context.executeStrategy(10, 5));


      context = new Context(new OperationSubstract());
      System.debug(’10 – 5 = ‘ + context.executeStrategy(10, 5));

Decorator:
Extending the functionality of an sObject in Apex.

Example is Wrapper Class – https://www.infallibletechie.com/2015/03/sample-wrapper-class-using-apex-in.html

Facade:
Simplifying the execution of classes with complex interfaces (e.g. web service callouts).

Sample Code:

/* Complex parts */


class CPU {
    public void freeze() { … }
    public void jump(long position) { … }
    public void execute() { … }
}


class HardDrive {
    public byte[] read(long lba, int size) { … }
}


class Memory {
    public void load(long position, byte[] data) { … }
}


/* Facade */


class ComputerFacade {
    private CPU processor;
    private Memory ram;
    private HardDrive hd;


    public ComputerFacade() {
        this.processor = new CPU();
        this.ram = new Memory();
        this.hd = new HardDrive();
    }


    public void start() {
        processor.freeze();
        ram.load(BOOT_ADDRESS, hd.read(BOOT_SECTOR, SECTOR_SIZE));
        processor.jump(BOOT_ADDRESS);
        processor.execute();
    }
}


/* Client */


class You {
    public static void main(String[] args) {
        ComputerFacade computer = new ComputerFacade();
        computer.start();
    }
}

Composite:
Treating a group of objects in a similar manner to a single instance of that object. Composite pattern is used where we need to treat a group of objects in similar way as a single object. Composite pattern composes objects in term of a tree structure to represent part as well as whole hierarchy. This type of design pattern comes under structural pattern as this pattern creates a tree structure of group of objects.

Sample Code:


Apex Class:


public class Employee {


   private String name;
   private String dept;
   private Integer salary;
   private List<Employee> subordinates;


   // constructor
   public Employee(String name,String dept, Integer sal) {
      this.name = name;
      this.dept = dept;
      this.salary = sal;
      subordinates = new List < Employee >();
   }


   public void add(Employee e) {
      subordinates.add(e);
   }


   public List<Employee> getSubordinates() {
     return subordinates;
   }

}


Execute the below code to set the hierarchy and view the debug log.
      
      Employee CEO = new Employee(‘John’,’CEO’, 30000);


      Employee headSales = new Employee(‘Robert’,’Head Sales’, 20000);


      Employee headMarketing = new Employee(‘Michel’,’Head Marketing’, 20000);


      Employee clerk1 = new Employee(‘Laura’,’Marketing’, 10000);
      Employee clerk2 = new Employee(‘Bob’,’Marketing’, 10000);


      Employee salesExecutive1 = new Employee(‘Richard’,’Sales’, 10000);
      Employee salesExecutive2 = new Employee(‘Rob’,’Sales’, 10000);


      CEO.add(headSales);
      CEO.add(headMarketing);


      headSales.add(salesExecutive1);
      headSales.add(salesExecutive2);


      headMarketing.add(clerk1);
      headMarketing.add(clerk2);


      //print all employees of the organization
      System.debug(CEO); 
      
      for ( Employee headEmployee : CEO.getSubordinates() ) {
         System.debug(headEmployee);
         
         for ( Employee employee : headEmployee.getSubordinates() ) {
            System.debug(employee);
         }

      }

Bulk State Transition:
Efficiently tracking the change of a field value in a trigger and executing functionality based on this change.

Example is bulking the trigger.

Leave a Reply