This idea is so frequently quoted that I wonder if sometimes it is being blindly followed without much thought. Here are some points in favor of triggers containing implementation code:

  • Keeping the code in the trigger ensures its' (important) execution context - inside a trigger, before or after, insert or update etc - is clear.
  • Always creating separate classes results in extra named (hard to name?) components that end up listed in profiles and deployment artifacts. More clutter, less cohesion.
  • Note the advice usually isn't to create classes that represent the domain (and so are likely to be re-used) but to create utility methods that are less likely to be re-used particularly as their signatures have to include various trigger context variables.
  • In any case the time to factor out code for re-use is when the need for re-use is discovered not before. Simple problems are best solved by simple solutions.
  • Having test classes 1:1 with triggers is a simple to follow pattern.

So I suggest the advice should be: "A trigger is much like a method in a class and should have its logic factored out into other classes when it becomes unwieldy or violates the DRY principle".

Ok so I've answered my own question - I disagree. But I would like hear what others think...

  • 1
    I agree fully with your suggested advice versus the title of your question, definitely. – AMM Mar 20 '13 at 21:37
  • 2
    Hey Keith, had to close this because the site is intended for questions with definite answers as opposed to those that invite discussion (salesforce.stackexchange.com/faq). That said, this is a definitely a topic of interest and although it doesn't 'fit' the meta site either I'd be easier to let it run there. – Matt Lacey Mar 20 '13 at 23:59
  • No problem, I agree there is no definite answer. The text in the title does often get quoted as if it is a definite answer though... – Keith C Mar 21 '13 at 9:32

Triggers run in system mode, so depending on whether you want run with or without sharing , a class becomes mandatory to ensure that a user is not able to update records they don't have edit access to, depending on your use case.

That apart, it is recommended to delegate your logic to a class rather than bloating up your triggers. One that I've used in the past is an Entity specific Handler (business logic) and Provider (Soql and database operations). Have only one trigger per object which handles all events and merely delegates processing to the handler. This also keeps trigger invocation more predictable as having multiple triggers per sObject can result in a debug log tracing nightmare as the numbers increase and you're developing for the enterprise.

Depending on how extensible you want to make it, you can create Interfaces and abstract the implementation, so that say if you wanted to switch the Handler or Provider implementation based on certain logic, you could invoke an implementation transparently. Common object oriented best practices largely apply, although Apex does not completely support advanced features such as reflection to the extent possible in say Java (though there are workarounds)

This is a great resource on Apex Design Patterns https://github.com/financialforcedev/df12-apex-enterprise-patterns

  • Your first point is a great one to think about. The salesforce documentation suggests that "Most of the time, system context provides the correct behavior for system-level operations such as triggers and Web services that need access to all data in an organization" but it certainly isn't "all of the time". But I question the idea that putting code in one place rather than another addresses bloat. I'm suggesting introducing complexity only when it is needed not day one (though perhaps I'm naive in thinking that appropriate refactoring happens). Great link thanks. – Keith C Mar 20 '13 at 22:01
  • It's a bit like building a house, whether you're building a bungalow or a sky scraper, it probably makes sense to lay the foundation first :) Whilst it is true that you can do a lot of things quickly with point and click on salesforce, any code customisations should generally follow best practice to set you up for success. – techtrekker Mar 20 '13 at 22:11
  • Good luck making money on your house after you've built 55 foot deep foundations (which apparently the Empire State Building has)... Seriously I do understand your argument; just trying to get to the bottom of the pros/cons of these best practices. – Keith C Mar 20 '13 at 22:21

Not the answer you're looking for? Browse other questions tagged or ask your own question.