✅ Apex Best Practices: Separation of Concerns & Modular Coding
Writing clean, scalable Apex code requires following key best practices such as Separation of Concerns (SoC) and Modular Coding. These help you build maintainable, testable, and reusable Salesforce applications.
๐ What is Separation of Concerns?
Separation of Concerns means dividing code into distinct sections, each handling a specific responsibility. In Apex, this typically involves:
- ๐ Keeping Triggers free of business logic
- ๐ง Moving logic to Handler and Helper classes
- ๐ง Using Utility classes for common logic
๐ Recommended Structure
/triggers ContactTrigger.trigger /classes ContactTriggerHandler.cls ContactHelper.cls ValidationUtils.cls---
๐งฉ Example: Good Modular Design
1️⃣ Trigger (Only Entry Point)
ContactTrigger.trigger
trigger ContactTrigger on Contact (before insert) {
ContactTriggerHandler.handleBeforeInsert(Trigger.new);
}
2️⃣ Handler Class
ContactTriggerHandler.cls
public class ContactTriggerHandler {
public static void handleBeforeInsert(List newContacts) {
ContactHelper.setDefaultTitle(newContacts);
}
}
3️⃣ Helper Class
ContactHelper.cls
public class ContactHelper {
public static void setDefaultTitle(List contacts) {
for(Contact c : contacts) {
if(String.isBlank(c.Title)) {
c.Title = 'Customer';
}
}
}
}
๐ Comparison Table
Approach | Without SoC | With SoC (Best Practice) |
---|---|---|
Trigger | Contains all logic | Delegates to handler |
Handler | Not used | Controls flow based on event |
Helper | Logic mixed into trigger | Contains actual business logic |
๐งช Benefits of Modular Design
- ✅ Easier to test individual components
- ✅ Encourages code reuse
- ✅ Simplifies debugging and maintenance
- ✅ Enhances team collaboration
๐ Final Best Practices
- Use
TriggerHandler
classes for all triggers - Move logic to
Helper
andService
classes - Use utility classes for reusable functions (e.g., validation, formatting)
- Keep classes focused on a single responsibility
- Use meaningful method and variable names