Close Menu

    Subscribe to Updates

    Get the latest creative news from FooBar about art, design and business.

    What's Hot

    How to Handle High-Volume API Integrations in Salesforce Without Hitting Limits

    December 19, 2025

    How to Think Like a Salesforce Architect: Mindset Shifts Every Pro Should Learn

    December 17, 2025

    Salesforce Business Rules Engine (BRE) Explained: Smarter Decisioning Beyond Apex & Custom Metadata

    December 15, 2025
    Facebook X (Twitter) Instagram
    Facebook Instagram LinkedIn WhatsApp Telegram
    Salesforce TrailSalesforce Trail
    • Home
    • Insights & Trends
    • Salesforce News
    • Specialized Career Content
      • Salesforce
      • Administrator
      • Salesforce AI
      • Developer
      • Consultant
      • Architect
      • Designer
    • Certifications Help
    • About Us
    • Contact Us
    Salesforce TrailSalesforce Trail
    Home - Developer - How to Build a Clean Apex Trigger Framework: Step-by-Step Guide
    Developer

    How to Build a Clean Apex Trigger Framework: Step-by-Step Guide

    Ritika GoelBy Ritika GoelNovember 28, 20255 Mins Read
    Facebook LinkedIn Telegram WhatsApp
    How to Build a Clean Apex Trigger Framework: Step-by-Step Guide
    Share
    Facebook LinkedIn Email Telegram WhatsApp Copy Link Twitter

    Suppose you have been developing on Salesforce for a while. In that case, you have probably encountered the same nightmare: multiple triggers on a single object, business logic scattered across classes, and the occasional “Too many SOQL queries” error haunting your deployments.

    Messy triggers are one of the biggest causes of technical debt in Salesforce orgs. As the project grows, so does the complexity, and without structure, even a small update can break production logic.

    So, what’s the solution?
    Apex Trigger Framework: a structured way to manage trigger logic that keeps your code clean, scalable, and easy to maintain.

    In this post, we’ll break down how to design your own Apex Trigger Framework, step by step, with best practices and sample code you can use right away.

    Table of Contents

    What’s wrong with Traditional Triggers?

    Before diving into the framework, let’s quickly look into which typically goes wrong in trigger-heavy orgs:

    • Multiple triggers per object – no control over execution order.
    • Business logic inside triggers – hard to read, debug, and test.
    • No bulk handling– leads to governor limit errors.
    • Copy-pasted code – changes in one place break others.

    In short, no structure = chaos.

    What Is an Apex Trigger Framework?

    An Apex Trigger Framework is simply a design pattern that separates trigger logic from business logic.

    Instead of writing logic directly inside the trigger, you route everything through handler classes. This makes your code modular, reusable, and testable.

    Benefits:

    • Enforces the “one trigger per object” rule.
    • Promotes separation of concerns.
    • Improves code reusability and readability.
    • Makes testing and debugging easier.
    • Supports bulk-safe operations.

    Building a Simple Trigger Framework (Step-by-Step)

    Let’s create a clean trigger setup for the Account object.

    Simple Trigger Framework

    Step 1: Create the Trigger

    				
    					Trigger AccountTrigger on Account(before insert, before update, before delete, 
        after insert, after update, after delete, after undelete){
    	AccountHandler.dispatch(AccountHandler.class);
    }
    				
    			

    Step 2: Base Handler (All logic lives here)

    				
    					public abstract class TriggerBaseHandler {
        public static void dispatch(Type handlerType) {
            TriggerBaseHandler handler = (TriggerBaseHandler) handlerType.newInstance();
    
            if (Trigger.isBefore) {
                if (Trigger.isInsert)  handler.beforeInsert(Trigger.new);
                if (Trigger.isUpdate)  handler.beforeUpdate(Trigger.new, Trigger.oldMap);
    if(Trigger.isDelete)   handler.beforeDelete(Trigger.old);
            }
    
            if (Trigger.isAfter) {
                if (Trigger.isInsert)    handler.afterInsert(Trigger.new);
                if (Trigger.isUpdate)    handler.afterUpdate(Trigger.new, Trigger.oldMap);
    if(Trigger.isDelete)    handler.afterDelete(Trigger.old);
                if (Trigger.isUndelete)  handler.afterUndelete(Trigger.new);
            }
        }
    
        // Virtual methods allow child handlers to override only the needed events
        public virtual void beforeInsert(List<SObject> newList) {}
        public virtual void beforeUpdate(List<SObject> newList, Map<Id,SObject> oldMap) {}
        public virtual void beforeDelete(List<SObject> oldList) {}
    
        public virtual void afterInsert(List<SObject> newList) {}
        public virtual void afterUpdate(List<SObject> newList, Map<Id,SObject> oldMap) {}
        public virtual void afterDelete(List<SObject> oldList) {}
        public virtual void afterUndelete(List<SObject> newList) {}
    }
    				
    			

    Step 3: AccountHandler (Overrides only needed methods)

    				
    					public with sharing class AccountHandler extends TriggerBaseHandler {
    
         public static void dispatch(Type t){
    TriggerBaseHandler.dispatch(t);
         }
    
        public override void beforeInsert(List<SObject> newList) {
            AccountService.beforeInsert((List<Account>) newList);
        }
    
        public override void beforeUpdate(List<SObject> newList, Map<Id, SObject> oldMap) {
            AccountService.beforeUpdate( (List<Account>) newList, (Map<Id, Account>) oldMap);
        }
      
       public override void beforeDelete(List<SObject> oldList){
            AccountService.beforeDelete((List<Account>) oldList);
        }
    
      public override void afterInsert(List<SObject> newList){
            AccountService.afterInsert((List<Account>) newList);
        }
    
       public override void afterUpdate(List<SObject> newList, Map<Id,SObject> oldMap){
            AccountService.afterUpdate( (List<Account>) newList, (Map<Id,Account>) oldMap);
        }
    
       public override void afterDelete(List<SObject> oldList){
            AccountService.afterDelete((List<Account>) oldList);
        }
    
        public override void afterUndelete(List<SObject> newList) {
            AccountService.afterUndelete((List<Account>) newList);
        }
    }
    				
    			

    Step 4: Service class- (Put all business logic here)

    				
    					public with sharing class AccountService {
    
        public static void beforeInsert(List<Account> newList) {
            // business logic here
        }
    
        public static void beforeUpdate(List<Account> newList, Map<Id, Account> oldMap) {
            // business logic here
        }
    
       public static void beforeDelete(List<Account> oldList){
            // business logic here
        }
    
       public static void afterInsert(List<Account> newList){
            // business logic here
        }
    
       public static void afterUpdate(List<Account> newList, Map<Id,Account> oldMap){
            // business logic here
        }
    
        public static void afterDelete(List<Account> oldList) {
           // business logic here
        }
    
        public static void afterUndelete(List<Account> newList) {
            // business logic here
        }
    
    
    				
    			

    This setup makes it easier to add consistent functionality across all your objects.

    Advanced Enhancements:

    Once you have the basics, you can enhance your framework with:

    • Recursion control – prevent the same trigger from running twice.
    • Custom metadata or custom settings – to control trigger activation.
    • Centralized logging – track errors and trigger execution.
    • Dependency injection – for improved testability.

    Best Practices for Trigger Frameworks:

    • One trigger per object.
    • Never write business logic directly in the trigger.
    • Keep triggers bulk-safe and governor-limit friendly.
    • Use meaningful method and class names.
    • Write unit tests for each handler method.
    Salesforce Trail

    Conclusion:

    A Trigger Framework isn’t just a coding pattern; It’s a mindset.

    It helps you write cleaner, more predictable code that scales with your Salesforce org and keeps deployments painless.

    If your current triggers are hard to read or constantly breaking, it’s time to refactor them using this approach. Start small, pick one object, and feel the difference in clarity and maintainability.

    References:

    [Apex Triggers Documentation]- https://developer.salesforce.com/docs/atlas.enus.apexcode.meta/apexcode/apex_triggers.htm

    [Apex Triggers Best Practices] – https://developer.salesforce.com/docs/atlas.enus.apexcode.meta/apexcode/apex_triggers_bestpract.htm

    [Define Triggers Help]- https://help.salesforce.com/s/articleViewid=platform.code_define_trigger.htm&type=5

    [Trigger Context Variables]- https://developer.salesforce.com/docs/atlas.enus.apexcode.meta/apexcode/apex_triggers_context_variables.htm

    Certified_Agentforce-Specialist
    Salesforce Administrator
    Business Analyst New
    Sales-Cloud-Consultant
    Salesforce Platform-Developer-1

    Most Reads:

    • Build a Dynamic, Reusable Lightning Datatable in Salesforce LWC (With Metadata-Driven Columns, Search & Pagination)
    • Beyond Triggers: The Apex Developer’s New Job in the Age of AI
    • Agentforce Explained: The New Era of AI Agents Inside Salesforce
    • Salesforce Marketing Cloud to Agentforce: The Future of Marketing Automation
    • How to Create a WhatsApp Business Channel and Configure It in Meta Business Suite

    Resources

    • [Salesforce Developer]- (Join Now)
    • [Salesforce Success Community] (https://success.salesforce.com/)

    For more insights, trends, and news related to Salesforce, stay tuned with Salesforce Trail

    Ritika Goel
    Ritika Goel
    Salesforce Developer – ritikagoel028@gmail.com – Web

    I’m a Salesforce Developer who enjoys turning complex business requirements into clean, scalable solutions. I specialize in Apex, Lightning Web Components, Flows, and Salesforce integrations. My focus is always on writing optimized, bulkified, and maintainable code that follows industry best practices.

      This author does not have any more posts.
    Apex Apex Development ApexTriggers Clean Code salesforce Salesforce Architecture Salesforce Coding salesforce developers SFDC Trigger Framework
    Share. Facebook LinkedIn Email Telegram WhatsApp Copy Link

    Related Posts

    How to Handle High-Volume API Integrations in Salesforce Without Hitting Limits

    December 19, 2025

    How to Think Like a Salesforce Architect: Mindset Shifts Every Pro Should Learn

    December 17, 2025

    Salesforce Business Rules Engine (BRE) Explained: Smarter Decisioning Beyond Apex & Custom Metadata

    December 15, 2025
    Add A Comment
    Leave A Reply Cancel Reply

    Advertise with Salesforce Trail
    Connect with Salesforce Trail Community
    Latest Post

    6 Proven Principles to Drive Faster Salesforce CRM Adoption

    November 3, 2025

    Driving Revenue Efficiency with Sales Cloud in Product Companies

    October 30, 2025

    How to Become a Salesforce Consultant: A Complete Guide to Success

    August 15, 2025

    5 Expert Tips for Salesforce Consultants and Architects to Improve Collaboration

    April 9, 2025
    Top Review
    Designer

    Customizing Salesforce: Tailor the CRM to Fit Your Business Needs

    By adminAugust 6, 20240

    Salesforce is an adaptable, powerful customer relationship management (CRM) software that businesses can customize, and…

    Sales Professional

    Unlock 10 Powerful Sales Pitches to Boost Your Revenue by 30X

    By Mayank SahuJuly 4, 20240

    Sales is a very competitive arena, and it is followed by one must have a…

    Salesforce Trail
    Facebook X (Twitter) Instagram LinkedIn WhatsApp Telegram
    • Home
    • About Us
    • Write For Us
    • Privacy Policy
    • Advertise With Us
    • Contact Us
    © 2025 SalesforceTrail.com All Right Reserved by SalesforceTrail

    Type above and press Enter to search. Press Esc to cancel.