Friday 17 April 2015

Writing Apex Triggers - One trigger per object - Framework!

Apex triggers are one of the most essential part of Force.com platform for back end automation. Apex trigger code is always executed before or after the events insert, update, delete, undelete, merge (update + delete), upsert (update + insert)

When to use before triggers?
When you have a requirement to update the record on same object on which trigger is implemented. Before triggers are also implemented when there is any kind of custom validations to be done based on set of fields (compound key) or a field to show a custom message (addError).

When to use after triggers?
When you have a requirement to create/update/delete operation on other object than the object on which trigger is implemented. i.e. Create a Warranty__c record after opportunity is "Closed Won"

Very important rule to keep in mind while implementing triggers is "Only ONE trigger per Object"

3 ways to write Apex Triggers:

  1. Modular Programming Approach – Simplest
    • We use this 70% of times
  2. Factory Pattern (20%)
  3. Abstraction of Handlers (10%)
    • When there are multiple handlers for a object 
    • Sequencing of handlers is required in execution
    • Dynamic instance creation is required.
    • CustomSettings__c cs = CustomSettings__c.getInstance('Vehicle'); 
    • Type t = Type.forName(cs.className__c);
    • Vehicle v = (Vehicle) t.newInstance(); 


Standard batch size of any bulkified trigger is 200. But if required then you can split it in code as n < 200 batch size. So, let's get started with a robust, easy to control and easy to maintain framework for a trigger on Account object!

How my AccountTrigger code will look like?

How my AccountTriggerHandler code will be?

How my AccountTriggerActions code will be?

How my AccountTriggerTest code will be?

Some technical specifications about above code:
1. Trigger_Control__c : This is a Hierarchical custom setting object which is used to control the execution of Account trigger. At this moment, I am looking at OrgDefaults but you can code it to look at a specific profile/users custom settings. This is very useful when you are working on an enterprise scale project and want to migrate millions of records without keeping these triggers on (Historic Data migration). You can have a user like "API Connect" and configure Trigger_Control__c for him on those trigger fields like Account_Trigger__c by marking it false. Once done, you can turn this field on again!

2. Naming convention: Naming conventions I followed in above code are usually best way I found so far. It helps to see all components in one shot listed under each other and also variable naming convention helps not to keep all variables in mind while coding.


Advantages of above framework:
1. Precise control on order of execution inside a singleton trigger
2. Separation of concerns
3. Control over re-entrant code
4. Clear organization and structure

What happens when upsert / merge event occurs?
1. Upsert: Upsert triggers fire both before and after insert or before and after update triggers as appropriate.
2. Merge: Merge triggers fire both before and after Delete triggers for the losing records and Before update triggers for the winning record only.


No comments:

Post a Comment