4.2 Introducing trigger handler class

Why do we want a Trigger handler class

If you think about the code we wrote in 3.4 Write a more difficult trigger and 4.1 Write an advanced trigger . Both triggers are on Transaction__c object. In the previous examples, we have put them into two separate triggers. But this is not the best practice. In Salesforce, it is always good to have one trigger only for each SObject. The reason is, the execution sequence of each independent trigger is always undefined. So it can cause unpredictable behaviour if we have multiple triggers.

However, think about it. Since triggers doesn’t have separate methods, if we put multiple logic into one single trigger, it can be really messy. Now we have only two triggers combined together, it can already become messy and less readable. So what about the real-world enterprise level projects?

That’s the main reason we want to introduce TriggerHandler class. In Salesforce, the good practice is to keep Trigger free with actual business logic and put the logic code into TriggerHandler class.

Let’s say how we do it with some code.

The code

Let’s take the example in 3.4 Write a more difficult trigger . And we will transfer it into TriggerHandler class style.

TriggerHandler Class:

public class TriggerHandlerTransaction
{
    private List<String> relatedMerchandiseIdList = new List<String>();
    private Map<Id, Merchandise__c> merMap;

    public void afterInsert()
    {
        initializeData();
        calculateRevenue();
        updateData();
    }

    private void initializeData()
    {
        for(Transaction__c curTrans: (List<Transaction__c>)Trigger.New)
        {
            relatedMerchandiseIdList.add(curTrans.Merchandise__c);
        }
         
        Map<Id, Merchandise__c> merMap = new Map<Id, Merchandise__c>([Select Id, Name, 
                                                                            Overall_Revenue__c,
                                                                            Discounted_Price__c 
                                                                      From  Merchandise__c
                                                                      Where Id in :relatedMerchandiseIdList]);
    }

    private void calculateRevenue()
    {
        for(Transaction__c curTrans: (List<Transaction__c>)Trigger.New)
        {
            Merchandise__c mer = merMap.get(curTrans.Merchandise__c);
            if(mer.Overall_Revenue__c == null) 
            {
                mer.Overall_Revenue__c = mer.Discounted_Price__c * curTrans.Amount__c;
            } 
            else
            {
                mer.Overall_Revenue__c += mer.Discounted_Price__c * curTrans.Amount__c;
            }
        }
    }

    private void updateData()
    {
        update merMap.values();
    }
}

Trigger:

trigger TransactionTrigger on Transaction__c (after insert) 
{
    TriggerHandlerTransaction handler = new TriggerHandlerTransaction();
    handler.afterInsert();
}

A bit explanation

The grammar here is nothing new. But the design is. Actually, we will make this TriggerHandler method even more rigorous later on. But now this is a much better version than the previous one.

Why? First, it separates the business logic from the trigger itself. So from now on, if we want to add more logic into the existing trigger, we can simply add a new method in our existing class – instead adding a new trigger, or directly adding some code into our trigger code, which will eventually make it horribly unreadable.

Second, it separates the process of the initialisation of data, the process of data and finally the DML process. This separation is not mandatory, but it will help centralise the code. If you move our code in Chapter 4.1 into this class, you will understand the benefits even more.

Exercise

Merge the code in 4.1 Write an advanced trigger into this TriggerHandler class.

Next post

4.3 Avoid infinite loops

Subscribe to Sfdcinpractice

Subscribe to get the latest blogs and tutorials of sfdcinpractice. No spam, no trash, only the awesome posts from sfdcinpractice. 

Leave a Reply

Your email address will not be published / Required fields are marked *