Create an interface ITrigger as following
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 for records during a BEFORE
* trigger. Never execute any SOQL/SOSL etc in this and other iterative methods.
*/
void beforeInsert(List newlstObj);
/**
* beforeUpdate
*
* This method is called for records to be updated during a BEFORE
* trigger.
*/
void beforeUpdate(List newlstObj,List oldlstObj,Map newMapObj, Map oldMapObj);
/**
* beforeDelete
*
* This method is called for records to be deleted during a BEFORE
* trigger.
*/
void beforeDelete(List oldlstObj,Map oldMapObj);
/**
* afterInsert
*
* This method is called for records 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(List newlstObj,Map newMapObj);
/**
* afterUpdate
*
* This method is called for records updated during an AFTER
* trigger.
*/
void afterUpdate(List newlstObj,List oldlstObj,Map newMapObj, Map oldMapObj);
/**
* afterDelete
*
* This method is called for records deleted during an AFTER
* trigger.
*/
void afterDelete(List oldlstObj,Map oldMapObj);
/**
* 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();
}
Create TriggerException class as following
public class TriggerException extends Exception {}
Create TriggerFactory class
public 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) {
handler.beforeDelete(trigger.old,trigger.oldMap);
}
// Iterate through the records to be inserted passing them to the handler.
else if (Trigger.isInsert) {
handler.beforeInsert(trigger.new);
}
// Iterate through the records to be updated passing them to the handler.
else if (Trigger.isUpdate)
{
handler.beforeUpdate(trigger.new,trigger.old,trigger.newMap,trigger.oldMap);
}
}
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) {
handler.afterDelete(trigger.old,trigger.oldMap);
}
// Iterate through the records inserted passing them to the handler.
else if (Trigger.isInsert) {
handler.afterInsert(trigger.new,trigger.newMap);
}
// Iterate through the records updated passing them to the handler.
else if (Trigger.isUpdate) {
handler.afterUpdate(trigger.new,trigger.old,trigger.newMap,trigger.oldMap);
}
}
// 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.
*/
public static ITrigger getHandler(Schema.sObjectType soType)
{
if (soType == Contact.sObjectType){
return new ContactTriggerHandler();
}
return null;
}
}
ContactTriggerHandler is a class that implements ITrigger interface.
Now create only one trigger on a object. Following example shows a trigger created on Contact object.
trigger ContactTrigger on Contact (after delete, after insert, after undelete, after update, before delete, before insert, before update) {
TriggerFactory.createHandler(Contact.sobjectType);
}
Do we need to write Unit Test for the Trigger Factory?
Its better if you write.