Build Great Triggers Quickly with STP (the Simple Trigger Pattern)
-
Upload
salesforce-developers -
Category
Technology
-
view
251 -
download
1
Transcript of Build Great Triggers Quickly with STP (the Simple Trigger Pattern)
Build Great Triggers Quickly with STP (the Simple Trigger Pattern)
Vivek M. Chawla Salesforce MVP | Senior Software Developer – Intuit @VivekMChawla
Vivek M. Chawla Salesforce MVP | Senior Software Engineer, Intuit | @VivekMChawla
Review Three Key Trigger Best Practices
Introduce the Simple Trigger Pattern (STP)
Demo
Q & A
Overview
Best Practices for Apex Triggers
Trigger best practices are important because trigger logic is usually…
• Complex
• Often mission critical!
• Entwined with other logic
• You don’t always control the other logic!
• High Volume
• Build for scale now…Don’t play catch-up later!
Why is This Important?
trigger AccountValidation on Account (before insert, before update) { // Do validation stuff... }
trigger AccountRollup on Account (after insert, after update) { // Do rollup stuff... }
trigger ShadowAccountBuilder on Account (after insert, after update) { // Do contact building stuff... }
Core Problems
• Unknown order of execution
• Duplicated business logic
• Code is harder to maintain
Best Practice #1 “One Trigger Per Object”
trigger AccountTrigger on Account (before insert, before update, after insert, after update) { if (Trigger.isBefore && Trigger.isInsert) { // Do validation stuff... } else if (Trigger.isBefore && Trigger.isUpdate) { // Do validation stuff... } else if (Trigger.isAfter && Trigger.isInsert) { // Do rollup stuff... // Do shadow account stuff... } else if (Trigger.isAfter && Trigger.isUpdate) { // Do rollup stuff... // Do shadow account stuff... } }
Recommendations
• Define a single “master” trigger
• Capture all “trigger actions” in the master trigger
• Use trigger context variables to determine what trigger action is being executed
Best Practice #1 “One Trigger Per Object”
trigger AccountTrigger on Account (before insert, before update, after insert, after update) { if (Trigger.isBefore && Trigger.isInsert) { // Do validation stuff... } else if (Trigger.isBefore && Trigger.isUpdate) { // Do validation stuff... } else if (Trigger.isAfter && Trigger.isInsert) { // Do rollup stuff... // Do shadow account stuff... } else if (Trigger.isAfter && Trigger.isUpdate) { // Do rollup stuff... // Do shadow account stuff... } }
Core Problems
• Code is harder to maintain
• Static variables aren’t available in trigger files
Best Practice #2 “No Business Logic in Triggers”
trigger AccountTrigger on Account (before insert, before update, after insert, after update) { AccountTriggerHandler handler = new AccountTriggerHandler(); if (Trigger.isBefore && Trigger.isInsert) { handler.beforeInsert(); } else if (Trigger.isBefore && Trigger.isUpdate) { handler.beforeUpdate(); } else if (Trigger.isAfter && Trigger.isInsert) { handler.afterInsert(); } else if (Trigger.isAfter && Trigger.isUpdate) { handler.afterUpdate(); } }
Recommendations
• Implement a Trigger Handler Class
• Dispatch to specific “Action Handler” methods
• Trigger Handler should leverage Service Classes for greater reusability
Best Practice #2 “No Business Logic in Triggers”
public class AccountTriggerHandler { public void afterInsert(list<Account> newAccounts, map<Id, Account> newAccountsMap) { // Create shadow accounts list<Account> shadowAccs = new list<Account>(); for (Account newAccount : newAccounts) { Account shadowAcc = new Account(); shadowAcc.Name = newAccount.Name + ‘ (Shadow)’; shadowAccs.add(shadowAccount); } insert shadowAccs; } }
Core Problem
• Something causes your trigger logic to execute more than once
• Trigger performs DML on a same-type object
• Workflow fires that causes a field update
Best Practice #3 “Prevent Recursion Using Static Variables”
public class AccountTriggerHandler { // Define a recursion check variable. private static boolean aiFirstRun = true; public void afterInsert(list<Account> newAccounts, map<Id, Account> newAccountsMap) { // Check the “first run” flag. if (aiFirstRun == false) { return; } // Flip the “first run” flag. aiFirstRun = false; // Create shadow accounts... createShadowAccounts(newAccounts); } }
Recommendations
• Use static variables to create a “gatekeeper” for your trigger logic
• Solves recursion issues in large majority of use cases
• Bonus Tip: Use private helper methods to keep handler methods semantically clean and direct
Best Practice #3 “Prevent Recursion Using Static Variables”
Bulkified Code is not a trigger best practice...
Bulkified Code is an Apex best practice!
• Bulkification means your code can handle batches of 200 records
• An Apex developer should always think “bulk first”
• Service and Utility methods should be “bulkified from birth”
Wait a Minute…What About Bulkification?
The Simple Trigger Pattern (STP)
Many Excellent Alternatives
• Tidy Pattern
• Simple Trigger Template
• TriggerX
• Hari Krishnan’s Framework
• Andrew Fawcett’s SOC
• Just to name a few...
Wait…Do we Really Need Another Trigger Pattern?
Simple Trigger Pattern
• One parent class
• One test class
• One Apex trigger template
• One Apex class template
• Encapsulates multiple best practices
• Enables rapid development
• Provides a straightforward standard that’s easy to implement
GitHub Repository
• bit.ly/SimpleTriggerPattern
GitHub Gist
• bit.ly/SimpleTriggerPatternGist
What Is It? What Does It Offer? Where Can I Get It?
Introducing the Simple Trigger Pattern (STP)
Demo
Three critical best practices for writing Apex triggers
• “One trigger per object”
• “No business logic in triggers”
• “Prevent recursion using static variables”
Introduced the Simple Trigger Pattern
Learned where to get and how to use the code
Review
GitHub Repo
• bit.ly/SimpleTriggerPattern
GitHub Gist
• bit.ly/SimpleTriggerPatternGist
Tidy Pattern
• bit.ly/TidyTriggerPattern
Simple Trigger Template
• bit.ly/SimpleTriggerTemplate
TriggerX
• bit.ly/TriggerXPattern
Hari Krishnan’s Pattern
• bit.ly/HariKrishnansPattern
GistBox
• GistBoxApp.com
Trigger Frameworks and Apex Trigger Best Practices
• sforce.co/1IMaN3n
Andrew Fawcett on “Separation of Concerns”
• bit.ly/FawcettBlogSOC
Simple Trigger Pattern (STP) Other Trigger Patterns Tools & Helpful Articles
Resources
Q&A @VivekMChawla
Thank you