On this page
Facade
The Facade pattern provides a unified, simplified interface to a set of interfaces in a subsystem, making it easier to use.
Problem
A subsystem has many classes and complex interactions, but clients only need a small subset of functionality.
Solution
// Complex subsystem
class VideoFile { /* ... */ }
class AudioMixer { void mix() { } }
class VideoCodec { void decode(VideoFile f) { } }
class BitrateReader { void read(VideoFile f) { } }
// Facade — simplified interface
class VideoConverter {
public File convert(VideoFile source, String format) {
AudioMixer mixer = new AudioMixer();
VideoCodec codec = new VideoCodec();
BitrateReader reader = new BitrateReader();
reader.read(source);
codec.decode(source);
mixer.mix();
// ... complex conversion logic
return new File("converted." + format);
}
}
// Client — simple usage
VideoConverter converter = new VideoConverter();
File result = converter.convert(videoFile, "mp4");
Java Examples
// SLF4J is a facade over Log4j, Logback, JUL
Logger log = LoggerFactory.getLogger(MyClass.class);
// JPA EntityManager hides JDBC complexity
entityManager.persist(user);
// Spring JdbcTemplate simplifies JDBC
jdbcTemplate.queryForObject("SELECT count(*) FROM users", Integer.class);
// HttpClient (Java 11+) simplifies HTTP operations
HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
Facade vs Adapter vs Decorator
| Pattern | Purpose |
|---|---|
| Facade | Simplify a complex subsystem |
| Adapter | Convert one interface to another |
| Decorator | Add behavior to an object |
When to Use
- Subsystem is complex and clients need a simple entry point
- You want to decouple clients from subsystem internals
- Layering — facade defines the boundary between layers
Best Practices
- Facade should not contain business logic — delegate to subsystem
- One facade per subsystem — do not create a god class
- Clients can still access subsystem directly if needed
- Common in service layers:
OrderServicefacades over repository, payment, and notification subsystems