Facade means: put one simple, high-level entry point in front of a subsystem made of several classes.
The facade does not replace the subsystem or hide it forever. It takes on the job of knowing how the pieces fit together — the right order to call them in, the right objects to wire up — so callers do not have to.
Unlike Adapter, Facade is not fixing a mismatch between two interfaces. The subsystem’s classes already work fine on their own. The problem is that there are too many of them.
The problem it solves
A home theater has an amplifier, a DVD player, and a projector, each with its own small interface.
public class Amplifier { public void on() { System.out.println("Amplifier on"); } public void setVolume(int level) { System.out.println("Volume: " + level); } public void off() { System.out.println("Amplifier off"); }}public class DvdPlayer { public void on() { System.out.println("DVD player on"); } public void play(String movie) { System.out.println("Playing: " + movie); } public void off() { System.out.println("DVD player off"); }}public class Projector { public void on() { System.out.println("Projector on"); } public void wideScreenMode() { System.out.println("Widescreen mode"); } public void off() { System.out.println("Projector off"); }}// without a facade, every caller repeats this:projector.on();projector.wideScreenMode();amplifier.on();amplifier.setVolume(5);dvdPlayer.on();dvdPlayer.play("Inception");
type Amplifier struct{}func (a Amplifier) On() { fmt.Println("Amplifier on") }func (a Amplifier) SetVolume(l int) { fmt.Println("Volume:", l) }func (a Amplifier) Off() { fmt.Println("Amplifier off") }type DvdPlayer struct{}func (d DvdPlayer) On() { fmt.Println("DVD player on") }func (d DvdPlayer) Play(m string) { fmt.Println("Playing:", m) }func (d DvdPlayer) Off() { fmt.Println("DVD player off") }type Projector struct{}func (p Projector) On() { fmt.Println("Projector on") }func (p Projector) WideScreenMode() { fmt.Println("Widescreen mode") }func (p Projector) Off() { fmt.Println("Projector off") }// without a facade, every caller repeats this:projector.On()projector.WideScreenMode()amplifier.On()amplifier.SetVolume(5)dvdPlayer.On()dvdPlayer.Play("Inception")
That is fine to write once. It is a problem the second, third, and tenth time it is written, because the correct order now lives in every call site instead of one place.
How it works
A facade sits in front of the subsystem, holds references to its pieces, and exposes a small number of high-level methods that coordinate internally.
Callers do not need to know that a projector needs widescreen mode enabled, or that the volume needs setting before the DVD starts — they just ask to watch a movie. Notice Amplifier, DvdPlayer, and Projector did not change at all.
Worked example: an order-processing facade
A checkout flow that has to touch inventory, payment, and shipping in a specific order, with rollback if something fails partway through.
If the order of operations ever needs to change, there is exactly one method to update, and every caller benefits automatically.
When it helps
Reach for Facade when a subsystem has grown enough moving parts that using it correctly means remembering a sequence or wiring several objects together. It is especially valuable at the boundary between layers — a controller talking to several services, or app code talking to a complex third-party SDK.
Facade also helps when you want to restructure what is underneath later, since callers depend on the facade’s interface, not on the subsystem’s classes directly.
When it hurts
Do not build a facade for two or three classes that are already simple to use together.
Its job is to delegate and coordinate, not to accumulate business logic of its own. A facade that grows validation rules and branching logic is turning into a god object — exactly the complexity Facade was supposed to prevent. Also avoid exposing getters for the internal services just to let callers reach around the facade; that quietly gives up the decoupling that was the whole point.
Practical tips
Give the facade a small number of high-level, task-shaped methods, not a thin pass-through for every subsystem method.
Let the facade delegate — each method should be a sequence of calls in the right order, not new logic.
Document what each facade method does end to end.
Do not confuse Facade with Adapter: Facade assumes the subsystem’s interfaces already work; Adapter exists because two interfaces do not match.
Check your understanding
What is Facade, in one sentence?
A class that provides one simple entry point in front of a subsystem made of several classes, hiding the coordination needed to use them correctly.
How is Facade different from Adapter?
Adapter reconciles two interfaces that do not match. Facade simplifies access to a subsystem whose interfaces already work but has too many pieces to use comfortably.
Does Facade replace the subsystem classes?
No. The subsystem classes stay exactly as they are; the facade sits in front of them.
What is the biggest risk when building a facade?
Letting it absorb business logic and become a god object, instead of staying a thin layer that delegates.
What to learn next
Next: Proxy Pattern — also stands in front of another object, but controls access to one instead of simplifying access to many.