Trailblazer Community Session - Patterns & Anti-Patterns_ The Good, The Bad, and The Ugly Code.pptx

mansoorahmad941764 15 views 29 slides Oct 27, 2025
Slide 1
Slide 1 of 29
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29

About This Presentation

A Lightweight Intro for Salesforce folks on Patterns & Anti-Patterns


Slide Content

Patterns & Anti-Patterns: The Good, The Bad, and The Ugly Code A Lightweight Intro for Salesforce Folks 25th October 2025 Salesforce Architects Group, Sharjah, United Arab Emirates

Mansoor Ahmad 17x Certified Salesforce Application & System Architect AWS Certified Architect Sharjah Salesforce Architect Community Group Leader https://www.linkedin.com/in/ahmad-mansoor/

Today’s Journey What are Patterns & Anti-Patterns? The Official Salesforce Framework Common Examples (Good vs Bad vs Ugly) Advanced Performance Concepts Your Action Plan & Resources Let’s begin!

Have you ever…? β€’ Spent hours debugging simple code? β€’ Seen governor limits at the worst time? β€’ Wondered "what was this person thinking?" Congratulations, you’ve encountered anti-patterns!

What even are Patterns & Anti-Patterns? And why talk about it?

What are Patterns & Anti-Patterns? Patterns = Proven Recipes Like your grandma's perfect chocolate chip cookie recipe Repeatable, reliable, proven to work Example : "Trigger Handler pattern" Anti-Patterns = Common Cooking Mistakes Like overcrowding the pan or burning the garlic Seem logical but cause more problems Example: "The 'God Trigger'"

The β€œUgly Code” // THE UGLY - Don't try this at home! trigger EverythingTrigger on Account ( before insert , after insert , before update , after update , before delete , after delete ) { if ( Trigger . isBefore && Trigger . isInsert ) { for ( Account a : Trigger . new ) { // SOQL in loop - dangerous! List < Contact > contacts = [ SELECT Id FROM Contact WHERE AccountId = : a . Id ]; } } // And 100 more lines of chaos... }

The Official Salesforce Framework

Well-Architected Framework Overview https://architect.salesforce.com/well-architected/explorer Three Pillars β†’ Trusted Β· Easy Β· Adaptable

Deep Dive & Explanation

🧩 1. Pattern β€” Bulkification What good looks like: Collect records, query once, DML in bulk. Handles governor limits and improves throughput. (Trusted β†’ Reliable β†’ Performance / Throughput) Anti-Pattern β€” SOQL or DML inside loops

🧩 2. Pattern β€” Risk Assessment Framework What good looks like: Maintain risk matrix (people, process, technology). Identify owner + mitigation plan + review cadence. (Trusted β†’ Reliable β†’ Availability) Anti-Pattern β€” Ad-hoc Risk Assessment

🧩 2. Pattern β€” Risk Assessment Framework (Trusted β†’ Reliable β†’ Availability) Example Risk Category Example Risk Impact Likelihood Mitigation Strategy Owner People Key admin leaves without handover High Medium Maintain documentation; enable delegated admins Salesforce Admin Process No deployment rollback plan High Low Use version control (Git) + sandbox staging Release Manager Technology API rate-limit breach Medium High Monitor via Event Logs; implement retry with exponential backoff Integration Lead Data Data corruption or loss Critical Low Weekly backup + sandbox restore testing Data Steward Security Integration credentials compromised Critical Medium Use OAuth Named Credentials + rotate tokens Security Officer Performance Batch jobs exceeding limits Medium Medium Split batches; use Queueables + monitoring alerts Salesforce Tech Lead

🧩 3. Pattern β€” Consistent Naming & Design Standards What good looks like: Uniform object + field naming rules. Prefix custom metadata (e.g., SAP_ for SAP integration). Centralized Design Standards doc. (Easy β†’ Intentional β†’ Readability) Anti-Pattern β€” Inconsistent or Redundant Naming

🧩 4. Pattern β€” Separation of Concerns & Composability What good looks like: Decouple UI, Service, Integration layers. Example: use Apex Enterprise Patterns (Domain + Service + Selector). Reuse flows and invocable actions instead of hardcoding steps. (Adaptable β†’ Composable β†’ Separation of Concerns) Anti-Pattern β€” Monolithic Logic

🧩 5. Pattern β€” Data Archiving & Purging Strategy What good looks like: Define retention policy (archival objects or Big Objects). Monitor record skew > 10 k child records. Schedule ETL or Batch purge jobs. (Adaptable β†’ Resilient β†’ Continuity Planning / Data Volume) Anti-Pattern β€” No Data Archiving Plan or Large Parent/Child Skew

Demo

❌ Anti-pattern (SOQL/DML inside loops a.K.a β€œ God Trigger”) // OpportunityTrigger.apxt (ANTI-PATTERN) trigger OpportunityTrigger on Opportunity ( after update ) { if ( Trigger . isAfter && Trigger . isUpdate ) { for ( Opportunity opp : Trigger . new ) { Opportunity oldOpp = Trigger . oldMap . get ( opp . Id ); // ❌ SOQL in loop Account acc = [ SELECT Id , Type FROM Account WHERE Id = : opp . AccountId LIMIT 1 ]; // Suppose business rule: when Opp becomes Closed Won β†’ mark Account.Type = 'Customer' if ( oldOpp . StageName != 'Closed Won' && opp . StageName == 'Closed Won' ) { acc . Type = 'Customer' ; // ❌ DML in loop update acc ; } } } }

Solution?

βœ… Pattern (Bulkification + Separation of Concerns) // OpportunityTrigger.apxt (PATTERN) trigger OpportunityTrigger on Opportunity ( after update ) { if ( Trigger . isAfter && Trigger . isUpdate ) { OpportunityTriggerHandler . onAfterUpdate ( Trigger . new , Trigger . oldMap ); } } Thin trigger -> delegate to handler

βœ… Pattern (Bulkification + Separation of Concerns) // OpportunityTriggerHandler.cls public class OpportunityTriggerHandler { public static void onAfterUpdate ( List < Opportunity > newList , Map < Id , Opportunity > oldMap ) { // Filter only those that transitioned to Closed Won and have an AccountId List < Opportunity > justClosedWon = new List < Opportunity >(); for ( Opportunity opp : newList ) { Opportunity oldOpp = oldMap . get ( opp . Id ); if ( opp . AccountId != null && oldOpp . StageName != 'Closed Won' && opp . StageName == 'Closed Won' ) { justClosedWon . add ( opp ); } } if ( ! justClosedWon . isEmpty ()) { OpportunityService . handleClosedWon ( justClosedWon ); } } } 2) Handler extracts intent and calls service

βœ… Pattern (Bulkification + Separation of Concerns) // OpportunityService.cls public class OpportunityService { public static void handleClosedWon ( List < Opportunity > closedWonOpps ) { // Collect unique AccountIds Set < Id > accountIds = new Set < Id >(); for ( Opportunity o : closedWonOpps ) { if ( o . AccountId != null ) accountIds . add ( o . AccountId ); } if ( accountIds . isEmpty ()) return ; // βœ… Single, selective query via selector Map < Id , Account > accountsById = AccountSelector . selectByIds ( accountIds ); // Apply business rule in-memory for ( Id accId : accountsById . keySet ()) { Account acc = accountsById . get ( accId ); acc . Type = 'Customer' ; // example: promote to Customer on first Closed Won } // βœ… Single DML statement if ( ! accountsById . isEmpty ()) { update accountsById . values (); } } } 3) Service runs bulk logic (one SOQL, one DML)

βœ… Pattern (Bulkification + Separation of Concerns) // AccountSelector.cls public class AccountSelector { public static Map < Id , Account > selectByIds ( Set < Id > ids ) { if ( ids == null || ids . isEmpty ()) return new Map < Id , Account >(); List < Account > rows = [ SELECT Id , Type FROM Account WHERE Id IN : ids ]; return new Map < Id , Account >( rows ); } } 4) Selector centralizes queries (DRY + testable)

Bigger Picture

How This Relates to Design Patterns & Apex Enterprise Patterns Design Patterns (Universal) Apex Enterprise Patterns (Code Architecture) Well-Architected Patterns & Anti-Patterns (Platform Architecture)

How This Relates to Design Patterns & Apex Enterprise Patterns Category Focus Example Audience Design Pattern Conceptual, universal Factory, Singleton All software engineers Apex Enterprise Pattern Implementation pattern for Apex Architecture Trigger Handler, Service, Domain, Selector Salesforce developers/ Architects Pattern / Anti-Pattern (Well-Architected Framework) Platform-wide architectural best practices Bulkification / SOQL-in-loop Salesforce architects, admins, consultants

Key Takeaways

Key Takeaways Start Simple - Use basic patterns like bulkification Consult the Framework - architect.salesforce.com is your guide Think Holistically - Consider trade-offs in your solutions Identify 1 anti-pattern in your org β†’ find the pattern counterpart Build a team practice around reviewing patterns quarterly