Skip to content

Instantly share code, notes, and snippets.

@JitendraZaa
Last active July 25, 2019 00:05
Show Gist options
  • Save JitendraZaa/036bd15906f5a288e7b0a9160e55bebf to your computer and use it in GitHub Desktop.
Save JitendraZaa/036bd15906f5a288e7b0a9160e55bebf to your computer and use it in GitHub Desktop.
Factory Pattern
/**
* Interface containing methods Trigger Handlers must implement to enforce best practice
* and bulkification of triggers.
*/
public interface ITrigger
{
/**
* bulkBefore
*
* This method is called prior to execution of a BEFORE trigger. Use this to cache
* any data required into maps prior execution of the trigger.
*/
void bulkBefore();
/**
* bulkAfter
*
* This method is called prior to execution of an AFTER trigger. Use this to cache
* any data required into maps prior execution of the trigger.
*/
void bulkAfter();
/**
* beforeInsert
*
* This method is called iteratively for each record to be inserted during a BEFORE
* trigger. Never execute any SOQL/SOSL etc in this and other iterative methods.
*/
void beforeInsert(SObject so);
/**
* beforeUpdate
*
* This method is called iteratively for each record to be updated during a BEFORE
* trigger.
*/
void beforeUpdate(SObject oldSo, SObject so);
/**
* beforeDelete
*
* This method is called iteratively for each record to be deleted during a BEFORE
* trigger.
*/
void beforeDelete(SObject so);
/**
* afterInsert
*
* This method is called iteratively for each record inserted during an AFTER
* trigger. Always put field validation in the 'After' methods in case another trigger
* has modified any values. The record is 'read only' by this point.
*/
void afterInsert(SObject so);
/**
* afterUpdate
*
* This method is called iteratively for each record updated during an AFTER
* trigger.
*/
void afterUpdate(SObject oldSo, SObject so);
/**
* afterDelete
*
* This method is called iteratively for each record deleted during an AFTER
* trigger.
*/
void afterDelete(SObject so);
/**
* andFinally
*
* This method is called once all records have been processed by the trigger. Use this
* method to accomplish any final operations such as creation or updates of other records.
*/
void andFinally();
}
/**
* Class LeadHandler
*
* Trigger Handler for the Lead SObject. This class implements the ITrigger
* interface to help ensure the trigger code is bulkified and all in one place.
*/
public with sharing class LeadHandler
implements ITrigger
{
// Constructor
public LeadHandler()
{
}
/**
* bulkBefore
*
* This method is called prior to execution of a BEFORE trigger. Use this to cache
* any data required into maps prior execution of the trigger.
*/
public void bulkBefore()
{
// If this a delete trigger Cache a list of Account Id's that are 'in use'
if (Trigger.isDelete)
{
}
}
public void bulkAfter()
{
}
public void beforeInsert(SObject so)
{
}
public void beforeUpdate(SObject oldSo, SObject so)
{
}
/**
* beforeDelete
*
* This method is called iteratively for each record to be deleted during a BEFORE
* trigger.
*/
public void beforeDelete(SObject so)
{
}
public void afterInsert(SObject so)
{
}
public void afterUpdate(SObject oldSo, SObject so)
{
}
public void afterDelete(SObject so)
{
}
/**
* andFinally
*
* This method is called once all records have been processed by the trigger. Use this
* method to accomplish any final operations such as creation or updates of other records.
*/
public void andFinally()
{
}
}
trigger LeadTrigger on Lead (before insert) {
TriggerFactory.createHandler(Lead.sObjectType);
}
public class TriggerException extends Exception {}
/**
* Class TriggerFactory
*
* Used to instantiate and execute Trigger Handlers associated with sObjects.
*/
public with sharing class TriggerFactory
{
/**
* Public static method to create and execute a trigger handler
*
* Arguments: Schema.sObjectType soType - Object type to process (SObject.sObjectType)
*
* Throws a TriggerException if no handler has been coded.
*/
public static void createHandler(Schema.sObjectType soType)
{
// Get a handler appropriate to the object being processed
ITrigger handler = getHandler(soType);
// Make sure we have a handler registered, new handlers must be registered in the getHandler method.
if (handler == null)
{
throw new TriggerException('No Trigger Handler registered for Object Type: ' + soType);
}
// Execute the handler to fulfil the trigger
execute(handler);
}
/**
* private static method to control the execution of the handler
*
* Arguments: ITrigger handler - A Trigger Handler to execute
*/
private static void execute(ITrigger handler)
{
// Before Trigger
if (Trigger.isBefore)
{
// Call the bulk before to handle any caching of data and enable bulkification
handler.bulkBefore();
// Iterate through the records to be deleted passing them to the handler.
if (Trigger.isDelete)
{
for (SObject so : Trigger.old)
{
handler.beforeDelete(so);
}
}
// Iterate through the records to be inserted passing them to the handler.
else if (Trigger.isInsert)
{
for (SObject so : Trigger.new)
{
handler.beforeInsert(so);
}
}
// Iterate through the records to be updated passing them to the handler.
else if (Trigger.isUpdate)
{
for (SObject so : Trigger.old)
{
handler.beforeUpdate(so, Trigger.newMap.get(so.Id));
}
}
}
else
{
// Call the bulk after to handle any caching of data and enable bulkification
handler.bulkAfter();
// Iterate through the records deleted passing them to the handler.
if (Trigger.isDelete)
{
for (SObject so : Trigger.old)
{
handler.afterDelete(so);
}
}
// Iterate through the records inserted passing them to the handler.
else if (Trigger.isInsert)
{
for (SObject so : Trigger.new)
{
handler.afterInsert(so);
}
}
// Iterate through the records updated passing them to the handler.
else if (Trigger.isUpdate)
{
for (SObject so : Trigger.old)
{
handler.afterUpdate(so, Trigger.newMap.get(so.Id));
}
}
}
// Perform any post processing
handler.andFinally();
}
/**
* private static method to get the appropriate handler for the object type.
* Modify this method to add any additional handlers.
*
* Arguments: Schema.sObjectType soType - Object type tolocate (SObject.sObjectType)
*
* Returns: ITrigger - A trigger handler if one exists or null.
*/
private static ITrigger getHandler(Schema.sObjectType soType)
{
if (soType == Lead.sObjectType)
{
return new LeadHandler();
}
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment