SlideShare a Scribd company logo
1 of 20
Download to read offline
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

More Related Content

More from Salesforce Developers

More from Salesforce Developers (20)

Sample Gallery: Reference Code and Best Practices for Salesforce Developers
Sample Gallery: Reference Code and Best Practices for Salesforce DevelopersSample Gallery: Reference Code and Best Practices for Salesforce Developers
Sample Gallery: Reference Code and Best Practices for Salesforce Developers
 
Maximizing Salesforce Lightning Experience and Lightning Component Performance
Maximizing Salesforce Lightning Experience and Lightning Component PerformanceMaximizing Salesforce Lightning Experience and Lightning Component Performance
Maximizing Salesforce Lightning Experience and Lightning Component Performance
 
Local development with Open Source Base Components
Local development with Open Source Base ComponentsLocal development with Open Source Base Components
Local development with Open Source Base Components
 
TrailheaDX India : Developer Highlights
TrailheaDX India : Developer HighlightsTrailheaDX India : Developer Highlights
TrailheaDX India : Developer Highlights
 
Why developers shouldn’t miss TrailheaDX India
Why developers shouldn’t miss TrailheaDX IndiaWhy developers shouldn’t miss TrailheaDX India
Why developers shouldn’t miss TrailheaDX India
 
CodeLive: Build Lightning Web Components faster with Local Development
CodeLive: Build Lightning Web Components faster with Local DevelopmentCodeLive: Build Lightning Web Components faster with Local Development
CodeLive: Build Lightning Web Components faster with Local Development
 
CodeLive: Converting Aura Components to Lightning Web Components
CodeLive: Converting Aura Components to Lightning Web ComponentsCodeLive: Converting Aura Components to Lightning Web Components
CodeLive: Converting Aura Components to Lightning Web Components
 
Enterprise-grade UI with open source Lightning Web Components
Enterprise-grade UI with open source Lightning Web ComponentsEnterprise-grade UI with open source Lightning Web Components
Enterprise-grade UI with open source Lightning Web Components
 
TrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer HighlightsTrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer Highlights
 
Live coding with LWC
Live coding with LWCLive coding with LWC
Live coding with LWC
 
Lightning web components - Episode 4 : Security and Testing
Lightning web components  - Episode 4 : Security and TestingLightning web components  - Episode 4 : Security and Testing
Lightning web components - Episode 4 : Security and Testing
 
LWC Episode 3- Component Communication and Aura Interoperability
LWC Episode 3- Component Communication and Aura InteroperabilityLWC Episode 3- Component Communication and Aura Interoperability
LWC Episode 3- Component Communication and Aura Interoperability
 
Lightning web components episode 2- work with salesforce data
Lightning web components   episode 2- work with salesforce dataLightning web components   episode 2- work with salesforce data
Lightning web components episode 2- work with salesforce data
 
Lightning web components - Episode 1 - An Introduction
Lightning web components - Episode 1 - An IntroductionLightning web components - Episode 1 - An Introduction
Lightning web components - Episode 1 - An Introduction
 
Migrating CPQ to Advanced Calculator and JSQCP
Migrating CPQ to Advanced Calculator and JSQCPMigrating CPQ to Advanced Calculator and JSQCP
Migrating CPQ to Advanced Calculator and JSQCP
 
Scale with Large Data Volumes and Big Objects in Salesforce
Scale with Large Data Volumes and Big Objects in SalesforceScale with Large Data Volumes and Big Objects in Salesforce
Scale with Large Data Volumes and Big Objects in Salesforce
 
Replicate Salesforce Data in Real Time with Change Data Capture
Replicate Salesforce Data in Real Time with Change Data CaptureReplicate Salesforce Data in Real Time with Change Data Capture
Replicate Salesforce Data in Real Time with Change Data Capture
 
Modern Development with Salesforce DX
Modern Development with Salesforce DXModern Development with Salesforce DX
Modern Development with Salesforce DX
 
Get Into Lightning Flow Development
Get Into Lightning Flow DevelopmentGet Into Lightning Flow Development
Get Into Lightning Flow Development
 
Integrate CMS Content Into Lightning Communities with CMS Connect
Integrate CMS Content Into Lightning Communities with CMS ConnectIntegrate CMS Content Into Lightning Communities with CMS Connect
Integrate CMS Content Into Lightning Communities with CMS Connect
 

Recently uploaded

The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
Enterprise Knowledge
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 

Recently uploaded (20)

A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 

Build Great Triggers Quickly with STP (the Simple Trigger Pattern)

  • 1. Build Great Triggers Quickly with STP (the Simple Trigger Pattern) ​ Vivek M. Chawla ​ Salesforce MVP | Senior Software Developer – Intuit ​ @VivekMChawla
  • 2. Vivek M. Chawla Salesforce MVP | Senior Software Engineer, Intuit | @VivekMChawla
  • 3. ​  Review Three Key Trigger Best Practices ​  Introduce the Simple Trigger Pattern (STP) ​  Demo ​  Q & A Overview
  • 4. Best Practices for Apex Triggers
  • 5. ​ 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?
  • 6. 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”
  • 7. 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 •  Dene 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”
  • 8. 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 les Best Practice #2 ​ “No Business Logic in Triggers”
  • 9. 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 specic “Action Handler” methods •  Trigger Handler should leverage Service Classes for greater reusability Best Practice #2 ​ “No Business Logic in Triggers”
  • 10. 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 res that causes a eld update Best Practice #3 ​ “Prevent Recursion Using Static Variables”
  • 11. 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”
  • 12. ​ Bulkied Code is not a trigger best practice... ​ Bulkied Code is an Apex best practice! •  Bulkication means your code can handle batches of 200 records •  An Apex developer should always think “bulk rst” •  Service and Utility methods should be “bulkied from birth” Wait a Minute…What About Bulkication?
  • 13. The Simple Trigger Pattern (STP)
  • 14. ​ 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
  • 15. •  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)
  • 16. Demo
  • 17. ​ 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
  • 18. ​ 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