The Service Layer Pattern
By the end of this lesson, you'll be able to:
- Explain what belongs in a service class versus a trigger handler
- Write a simple service class method
Prerequisites: Why a Trigger Framework Matters
What belongs in a service class
Business operations like "close all open Opportunities for an Account" or "recalculate a Contact's loyalty tier" — logic that's meaningful on its own, independent of what triggered it. A trigger handler can call into the service; so could a button's Apex controller, a scheduled job, or a Platform Event subscriber.
Why this separation pays off
Without a service layer, the same "close all Opportunities" logic often gets copy-pasted into a trigger, a batch class, and a Lightning controller separately — three places to keep in sync, three places bugs can diverge. A service class means one implementation, called from wherever it's needed.
A reusable service method
public with sharing class OpportunityService {
public static void closeAllOpenFor(Id accountId) {
List<Opportunity> opps = [
SELECT Id, StageName FROM Opportunity
WHERE AccountId = :accountId AND IsClosed = false
];
for (Opportunity o : opps) {
o.StageName = 'Closed Lost';
}
update opps;
}
}
This method has no idea whether it was called from a trigger, a button, or a batch job — that is the point. It is a pure, reusable business operation.
Exercise
Write a ContactService class with a static method markAsVip(List<Contact> contacts) that sets each Contact's VIP__c field to true and updates them.
Show hint
Loop over the list setting the field, then a single bulk update statement outside the loop.
The Service Layer Pattern — Quick Check
My Notes
Log in to keep private notes on this lesson.
Questions about this lesson
No questions yet — be the first to ask.
Log in to ask a question about this lesson.
Summary
A service layer holds reusable business logic as plain, testable methods — callable from a trigger handler, a Lightning Web Component controller, a batch job, or anywhere else — instead of that logic being duplicated or buried inside a single entry point.