The Separated Interface pattern consists of defining an interface in one package (or module) and placing its implementation in a different package. This allows the client of the interface to depend solely on the definition rather than the concrete implementation.
It is a fundamental technique for applying the Dependency Inversion Principle (DIP) and achieving a highly modular, easy-to-test system.
# When to use it?
It is essential when you want to decouple components that interact with each other, allowing you to change the implementation without affecting the code that uses the interface. It is especially useful for external services, data access, or any component whose implementation may vary.
# Pros
-
verified
Low Coupling
Clients only know the interface, not the implementation.
-
verified
Substitutability
Facilitates swapping one implementation for another (e.g., for testing or different providers).
-
verified
Clean Structure
Promotes a clear separation of responsibilities between packages.
# Cons
-
warning
Additional Complexity
Requires managing more files and package structures.
-
warning
Indirection
Can make tracking the execution flow slightly more complex initially.
# Detailed Example in Java
Let's assume an email interface defined in the domain, with real and test implementations in separate packages:
domain/EmailService.java
public interface EmailService {
void send(String to, String message);
}
infrastructure/SMTPEmailService.java
public class SMTPEmailService implements EmailService {
@Override
public void send(String to, String message) {
// Real implementation using mail protocols
}
}
# Conclusions
The Separated Interface pattern is a pillar of clean architecture. By separating what is done from how it is done, we create systems that are resilient to change, easy to test, and have a clear, professional modular structure.