The SFDC-trigger-framework

A couple of years ago, Salesforce MVP Kevin O'Hara released on GitHub the SFDC-trigger-framework. You can find it at https://github.com/kevinohara80/sfdc-trigger-framework. There are a number of trigger frameworks available for the platform, but this one is my favorite and the one I highly recommend. Since SFDC-trigger-framework is a bit of a mouthful, I will refer to it as the framework. The framework allows us to separate the logic from triggers in a way that allows us to create a deterministic order for those triggers to fire, and in a better way, for us to test the logic triggers. Because the trigger interface is controlled by Salesforce, very little of the actual trigger file will be different than traditional trigger development. Specifically, we still have to determine the context of our trigger and specify that in the trigger file for salesforce:

trigger AccountTrigger on Account (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
  new AccountTriggerHandler().run();
}

You'll notice a few differences in this trigger definition, namely that it includes all possible timeframes and DML statements. You'll also see that it calls the run method of the AccountTriggerHandler class. This effectively causes the trigger to fire on all possible account contexts and call the Run() method. We do this so that our trigger logic, which exists in its own dedicated class, can determine whether or not it should run, when it should run, and in what order its components should run. This also introduces Rule #2, Only one trigger per object. Using a framework like this one allows us to have a single trigger per object because the logic is separated into its own class, which is Rule #3: Triggers should contain no logic—only exercising logic in another class. Ideally, we have triggers that run in all possible contexts and contain no logic!

The framework makes this crazy sounding idea possible by providing a series of methods that we can override. Our handler class will extend the framework provided by the TriggerHandler class. This provides the following methods that we can overwrite:

  • beforeInsert()
  • beforeUpdate()
  • beforeDelete()
  • afterInsert()
  • afterUpdate()
  • afterDelete()
  • afterUndelete()

Our override methods allow us to determine what, if any, code is run before or after any given DML statement. When combined with an object, these seven methods cover all possible trigger contexts. The trigger framework handles determining the DML and timeframe, and it only calls methods that match context of this execution instance. While the trigger will always fire in every context, the framework ensures that only the code matching the current context runs. Thus, only the code referenced by the beforeInsert() method is called before the account is inserted, and only the code referenced by the afterUpdate() method is called after the update completes.

A cautionary note

While it may be tempting to put your logic directly inside these methods, it's better to think of these overriden methods (beforeInsert() and others) as dispatch methods, that is, methods that call other classes or methods. For instance, in the beforeInsert() method, you might call an accountLib.sanitizeAccountData() method followed by the caseLib.createCase() and OpportunityLib.createOpp() methods. Or you can call private helper methods found within the AccountTriggerHandler itself. This dispatch technique allows you to deterministically order the logic your trigger executes within a given DML context. For instance, your beforeInsert() override method might look something like this:

public class AccountTriggerHandler extends triggerHandler {
  public override void beforeInsert() {
    AccountLib.sanitizeDataForAccounts(Trigger.new);
    ContactLib.createContacts(Trigger.new);
    OpportunityLib.createOpps(Trigger.new);
  }
}

Rule #3 states that the triggers' logic should exist, not in the trigger, but in standard classes. Using this framework means buying into this idea wholeheartedly. Mixing in-trigger logic and class-based logic called by this framework negates the maintainability gains the framework provides. Regardless of whether or not you ever utilize this particular framework, placing your logic inside of a class and having the trigger call that class is an architectural and testing best practice. This makes the code more maintainable in the long run as you can edit classes and test classes more efficiently and deeply.

The framework is very lightweight, imposing few restrictions on developers. You can name your logic class anything you like but the convention created by Kevin O'Hara, and the one used in this book, is to call them trigger handlers. Therefore, if you have a trigger on the Account object, you would have an accountTriggerHandler class to dispatch the logic.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.37.196