5

I know from this blog post and this answer that a one trigger design pattern per object is ideal. Are there ever exceptions to that rule? If so, what are they?

Here is my situation to argue that there are exceptions to this rule, but I hope I'm wrong.

I have an AccountTrigger, that then calls a class that makes a callout to an API, let's call this AccIntegrationUtility. The AccountTrigger also has other classes in it for modularity.

The AccIntegrationUtility class is also used in a batch on the account object that runs nightly, lets call it AccountBatch. The business requirement is they need to get third-party data when the account meets certain conditions during normal business hours and to get that same data for all accounts at 5am, before the business opens.

So I have the AccIntegrationUtility class split between my AccountTrigger and AccountBatch.

I'm following sfdx on creating "artifacts", and they say you should have each artifact self contained. I want to create an artifact on the Account Integration, but the problem is the split. I don't want to have my entire AccountTrigger and it's dependent class in my Account Integration artifact. What makes sense to me is to have two triggers, AccountTrigger and AccountTriggerIntegration. So, remove the integration from AccountTrigger and place it all in the AccountTriggerIntegration. That way I have an Account Integration artifact that doesn't need any of the other AccountTrigger code, and can be tested on it's own and be in its own source. Thoughts?

1
  • consider Force.com enterprise patterns (see Trailhead)
    – cropredy
    Feb 28, 2018 at 18:14

2 Answers 2

6

It's not really a rule, it's a strong suggestion. Understanding the reason behind the rule is what's important. When you have more than one trigger on one object, and those triggers each fire on the same DML event, you cannot be sure which order they will execute in, and further, side effects from one won't be necessarily be visible in the other, which can frustrate a developer when they realize their validations are not working correctly, or two different triggers update the same field, causing one of the values to be lost, etc.

It's also likely that different triggers might need the same data, so you'll end up wasting SOQL calls that could have been aggregated together, etc. In short, having more than one trigger fire per object can make an unpredictable mess of things very quickly. To avoid this mess, they recommend having one object per trigger. You can logically follow the flow of the trigger from one line to the next, and there won't be any unintentional surprises in behavior. Having code that flows predictably, instead of randomly, is always a good idea.

That said, having more than one trigger per object is entirely possible, if you're sure you avoid wasted DML operations, SOQL/SOSL operations, unintentional clobbering of data, missed validations, and so on. It's entirely reasonable to expand the rule to say "you can only have one trigger per DML event per object." This means that one trigger handles, say "before update", while another handles "after update."

Or, again, assuming you make the necessary effort to avoid governor limits and invalid data states, it's also perfectly reasonable to say "you can have one trigger per business rule," in your case, a trigger that calls the API stuff, and another trigger for everything else. So long as they don't share any queries, DML operations, updates, validations, or anything else, there's no problem doing this.

Just be aware that the code will flow in whatever order it feels like (e.g. the API call might happen first, or not). Since you have to end up calling API calls asynchronously anyways, it doesn't really matter here, just be aware that if anything does go wrong, debugging the situation might get more complicated. Do not make any assumptions about which trigger goes first, and do not rely on data that may or may not have already been set by the other trigger.

It's not impossible to use multiple triggers per object. However, it happens that it is much easier to screw something up subtly in ways that not even a unit test can properly test for, so for novice developers, the rule is do not do it, while the rule for a more experienced developer is do it with caution, and document everything carefully. As long as you have good documentation so that someone doesn't come along later and introduces operation-dependent behavior, you should be fine.

1
  • 1
    my my how I've been blessed by sfdcfox over the last 24 hours. The man has written 11 paragraphs for two of my questions. I appreciate it!
    – Tyler Zika
    Feb 28, 2018 at 18:15
1

There's a trade-off between the simplicity of one-trigger-per-business-requirement on the one hand, and performance optimization and level of control provided by adopting a trigger dispatching framework on the other.

I suggest putting off adopting a trigger framework as long as possible by writing your triggers carefully, checking the field values of the old and new objects, and short-circuiting if there are no changes relevant to each trigger's functionality.

Writing small, readable triggers allows new developers to grok how they work quickly without understanding the complexity of a trigger framework, and having multiple trigger on the same object often doesn't pose any problems. Following the YAGNI principle, you should avoid adding the complexity of a trigger framework until you need it.

1
  • 1
    the counterargument of course is "if you're even thinking about this issue, you are probably smart enough to use a trigger framework and can realize its benefits in the mid-to-long term" :-)
    – cropredy
    Feb 28, 2018 at 22:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .