build great triggers quickly with stp (the simple trigger pattern)
TRANSCRIPT
![Page 1: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/1.jpg)
Build Great Triggers Quickly with STP (the Simple Trigger Pattern)
Vivek M. Chawla Salesforce MVP | Senior Software Developer – Intuit @VivekMChawla
![Page 2: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/2.jpg)
Vivek M. Chawla Salesforce MVP | Senior Software Engineer, Intuit | @VivekMChawla
![Page 3: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/3.jpg)
Review Three Key Trigger Best Practices
Introduce the Simple Trigger Pattern (STP)
Demo
Q & A
Overview
![Page 4: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/4.jpg)
Best Practices for Apex Triggers
![Page 5: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/5.jpg)
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?
![Page 6: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/6.jpg)
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”
![Page 7: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/7.jpg)
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”
![Page 8: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/8.jpg)
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”
![Page 9: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/9.jpg)
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”
![Page 10: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/10.jpg)
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”
![Page 11: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/11.jpg)
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”
![Page 12: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/12.jpg)
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?
![Page 13: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/13.jpg)
The Simple Trigger Pattern (STP)
![Page 14: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/14.jpg)
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
![Page 15: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/15.jpg)
• 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)
![Page 16: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/16.jpg)
Demo
![Page 17: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/17.jpg)
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
![Page 18: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/18.jpg)
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
![Page 19: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/19.jpg)
Q&A @VivekMChawla
![Page 20: Build Great Triggers Quickly with STP (the Simple Trigger Pattern)](https://reader031.vdocuments.us/reader031/viewer/2022022419/58a4561d1a28ab55068b5ffb/html5/thumbnails/20.jpg)
Thank you