Hey friends,
The best-known Apex design patterns are the Apex Enterprise Patterns: a Service layer for business processes, a Domain layer for each object's validation and calculations, and a Selector layer that owns the SOQL, with triggers kept thin and routed to the Domain class. They all come from one idea, separation of concerns (SOC).
I'm sticking to what Salesforce teaches in the Trailhead modules Apex Enterprise Patterns: Service Layer and Domain and Selector Layers. The Platform Developer II exam asks for maintainable, reusable code that follows design patterns, and its Performance section asks when and how to reuse code.

If you can name the layer a line of code belongs to, you're most of the way there.
What is the Service layer?
Trailhead quotes Martin Fowler's definition: it "defines an application's boundary with a layer of services." Its clients are other code: Lightning controllers, @AuraEnabled methods, Batch Apex, APIs. The design rules Trailhead gives:
- Name methods for the business task, like
InvoiceService.calculateTax(...), not for one caller, likehandleTaxCodeForACME(...). - Bulkify signatures. Take lists, so callers don't loop over single calls.
- Run with user security. Use
with sharingon service classes, and elevate only briefly with a privatewithout sharinginner class. - Leave error display to callers. Throw exceptions and let the UI, batch job or API decide how to show them.
- Offer compound services so callers don't chain many calls in one transaction.
What is the Domain layer?
One Domain class per object (Trailhead names them in the plural, like Opportunities) holds that object's behavior: complex validation, defaulting and calculations. Both the Service layer and the trigger call into it, so the same rules apply whether a record is saved from the UI, an API or a batch job.
What is the Selector layer?
A Selector class holds the queries for an object. Trailhead's reasons: the same query copied around drifts over time, and code receiving records can't be sure which fields were queried. A selector gives every caller (Domain, Service, controllers, Batch Apex) the same fields and criteria.
Cert Lab by Nick Frates
Let the Platform Developer II Cert Lab test you to success
Questions on trigger design, code reuse, sharing keywords and refactoring sample code, with every option explained.
Start the Platform Developer II Cert Lab for $9.99 →Not ready to buy? Try a free lesson and see how fast you learn.
What does a thin trigger look like?
Trailhead says triggers "make poor places for even moderately complex logic." The trigger only routes events. Trailhead's version uses the open source fflib library's fflib_SObjectDomain.triggerHandler. Without a library, a plain handler does the same job:
One trigger per object, logic in a class, bulkified. My Apex trigger best practices post covers recursion guards and the order of execution.
Which other patterns should Platform Developer II candidates know?
| Pattern | What it solves | Where it shows up |
|---|---|---|
| Trigger handler | Logic out of triggers, one trigger per object | Process Automation, Logic, and Integration |
| Unit of Work | Collect DML and commit once, in order | Trailhead's service example calls uow.commitWork() |
| Stub API mocks | Test a class in isolation with System.StubProvider and Test.createStub() | Testing, Debugging, and Deployment |
| Custom metadata for config | Change behavior without code changes | Advanced Developer Fundamentals |
The Stub API page in the Apex Developer Guide is the official source for the mocking row.
What design pattern mistakes should you avoid?
- Logic in the trigger body. It can't be reused or unit tested on its own.
- Caller-specific service methods. They multiply and drift apart.
- Single-record signatures. They force loops that burn SOQL and DML limits.
- SOQL scattered everywhere. Put it in a selector so fields and filters stay consistent.
- Adopting every layer on day one. For a small org, a trigger handler and a selector or two may be plenty. Add layers when complexity earns them.
A bit about how I study. Focus on Force was my favorite resource on the way to 17 Salesforce certs. I started the traditional way, reading the study guide first and testing second, but rapid-fire practice tests are what actually made things stick. That's the loop Cert Lab is built on: quick questions, then explanations with current links, then go again.
FAQ
What are Apex Enterprise Patterns?
A set of layering patterns Salesforce teaches on Trailhead: Service, Domain and Selector layers, built on separation of concerns and adapted from Martin Fowler's enterprise application patterns.
Is fflib required?
No. Trailhead's examples use the open source fflib library, but the layering works with your own simple classes.
Where does trigger logic go?
In the Domain layer, called from a thin trigger. Trailhead notes triggers are missing from the Service layer's clients for that reason.
Are design patterns on the Platform Developer II exam?
Yes. The exam guide expects maintainable, reusable code following design patterns, and asks about trigger best practices and code reuse.
Where should you go next?
- The pattern and anti-pattern master list for more examples.
- Apex managed sharing for when a service needs to grant access.
- The Platform Developer II study guide for the full outline.
Nick Frates, a senior Salesforce developer with 17 certifications, built the Platform Developer II Cert Lab at nickfrates.com: rapid-fire practice questions for every exam section, each answer explained.
Cert Lab by Nick Frates
Let the Platform Developer II Cert Lab test you to success
Lessons, flashcards, a quiz for each of the five exam sections and full practice exams, every answer explained.
Start the Platform Developer II Cert Lab for $9.99 →Not ready to buy? Try a free lesson and see how fast you learn.
Hope this helps!
Best,
Nick


