Apex triggers are powerful tools for automating business processes in Salesforce. However, without proper structure, triggers can become hard to maintain and prone to errors. In this post, we’ll look at advanced patterns and best practices for writing scalable and maintainable Apex triggers.
- Multiple triggers on the same object causing unpredictable execution order.
- Logic directly in triggers, making code hard to test and reuse.
- Difficulty in handling bulk updates and governor limits.
Best Practice:
Always write a single trigger per object and delegate logic to handler classes.
// OpportunityTrigger.trigger
trigger OpportunityTrigger on Opportunity (before insert, before update, after insert) {
OpportunityTriggerHandler handler = new OpportunityTriggerHandler();
if (Trigger.isBefore) {
handler.beforeInsert(Trigger.new);
handler.beforeUpdate(Trigger.new, Trigger.oldMap);
}
if (Trigger.isAfter) {
handler.afterInsert(Trigger.new);
}
}
// OpportunityTriggerHandler.cls
public class OpportunityTriggerHandler {
public void beforeInsert(List<Opportunity> newOpps) {
// Add business logic here
for (Opportunity opp : newOpps) {
if (opp.StageName == 'Prospecting') {
opp.Description = 'Initial stage';
}
}
}
public void beforeUpdate(List<Opportunity> newOpps, Map<Id, Opportunity> oldOpps) {
// Business logic for before update
}
public void afterInsert(List<Opportunity> newOpps) {
// Business logic for after insert
}
}
Always write trigger logic to handle bulk operations:
// Example: Bulk assigning a field value
for (Opportunity opp : newOpps) {
opp.Custom_Field__c = 'Value';
}
- Avoid SOQL/DML inside loops.
- Use collections and maps for efficient processing.
Keep your trigger handler methods public and testable:
@isTest
private class OpportunityTriggerHandlerTest {
@isTest
static void testBeforeInsert() {
List<Opportunity> opps = new List<Opportunity>{
new Opportunity(Name='Test', StageName='Prospecting', CloseDate=Date.today())
};
OpportunityTriggerHandler handler = new OpportunityTriggerHandler();
handler.beforeInsert(opps);
System.assertEquals('Initial stage', opps[0].Description);
}
}
By following these patterns—one trigger per object, using handler classes, and bulkifying your logic—you’ll create Apex automation that is reliable, scalable, and easy to maintain. Advanced developers should always prioritize code quality, testability, and future-proofing in their Salesforce automation.
Have your own trigger patterns or tips? Share them in the comments!
Post a Comment