Interface Segregation: Stop Building Fat Interfaces
How to keep your Apex interfaces lean, mean, and actually useful.
Interface Segregation: Keep Your Interfaces Lean
The Interface Segregation Principle (ISP) tells us that it is better to have many specific interfaces than one giant, "do-it-all" interface.
In Salesforce, we often fall into the trap of creating a single ITriggerHandler or IIntegration that has 10 different methods. The problem? Most classes implementing those interfaces only actually care about two or three of them.
The "Fat Interface" Problem (The Wrong Way)
Imagine an interface for a generic "Worker" that handles various record actions.
public interface IRecordWorker {
void validate();
void transform();
void syncToExternalSystem();
void archive();
}Now, suppose you just need a simple class to validate a Lead's phone number. Because of the interface, you're forced to implement everything:
public class LeadValidator implements IRecordWorker {
public void validate() {
// Real logic here
}
// Dead code required by the interface:
public void transform() {}
public void syncToExternalSystem() {}
public void archive() {}
}Why this is a mess: You’ve created "Polluted" code. If you ever change the signature of archive(), you now have to update the LeadValidator, even though it doesn't even use that feature!
Smarter, Smaller Interfaces (The Right Way)
The fix is to split the big interface into smaller, specialized "roles."
1. The Role-Based Interfaces
public interface IValidator {
void validate();
}
public interface ITransformer {
void transform();
}
public interface ISyncable {
void syncToExternalSystem();
}2. The Implementation
Now, your classes can "pick and choose" exactly what they do.
// This class only validates. Clean and simple.
public class LeadValidator implements IValidator {
public void validate() { /* Logic */ }
}
// This class handles a complex integration flow.
public class OrderProcessor implements IValidator, ITransformer, ISyncable {
public void validate() { /* ... */ }
public void transform() { /* ... */ }
public void syncToExternalSystem() { /* ... */ }
}Why ISP Matters in Salesforce
-
Smaller Test Classes: You don't have to write "dummy" tests for empty methods just to meet the 75% coverage requirement.
-
Reduced Coupling: Changing the "Sync" logic won't trigger a re-compile or potential failure in your "Validation" logic.
-
Better Documentation: When a developer looks at LeadValidator and sees implements IValidator, they immediately know exactly what that class is for.
Summary
Don't be afraid to have multiple interfaces. It’s much easier to maintain five small, focused interfaces than one "God Interface" that tries to predict every future use case. By following ISP, you make your Apex code more modular and your intent much clearer.