Facade provides a simplified, unified interface to a complex subsystem made of many interacting classes, so client code doesn't need to understand or coordinate all those parts directly.
// A complex subsystem with many interacting parts
class CPU { function freeze() {} function jump(pos) {} function execute() {} }
class Memory { function load(pos, data) {} }
class HardDrive { function read(sector, size) {} }
// The facade hides all that complexity behind one simple method
class ComputerFacade {
private cpu = new CPU()
private memory = new Memory()
private hardDrive = new HardDrive()
function start() {
this.cpu.freeze()
this.memory.load(0, this.hardDrive.read(0, 1024))
this.cpu.jump(0)
this.cpu.execute()
}
}
computer = new ComputerFacade()
computer.start() // caller doesn't need to know about CPU, Memory, or HardDrive at all
This is one of the most common patterns in everyday application code — a UserService or OrderService class is often, in essence, a facade over many lower-level repositories, validators, and external API clients.
Composite lets you treat individual objects and groups of objects uniformly, through a shared interface — ideal for representing tree-like, part-whole hierarchies such as file systems (files and folders), UI components (a button vs. a panel containing many buttons), or organization charts.
interface FileSystemItem {
function getSize(): number
}
class File implements FileSystemItem {
function __construct(private size) {}
function getSize(): number { return this.size }
}
class Folder implements FileSystemItem {
private items = []
function add(FileSystemItem item) { this.items.push(item) }
function getSize(): number {
total = 0
for item in this.items:
total += item.getSize() // works the same whether item is a File or another Folder
return total
}
}
root = new Folder()
root.add(new File(100))
subfolder = new Folder()
subfolder.add(new File(200))
subfolder.add(new File(50))
root.add(subfolder)
print(root.getSize()) // 350 — calculated recursively, callers never distinguish File from Folder
The key insight: both File and Folder implement the same FileSystemItem interface, so code that calls getSize() never needs to check 'is this a leaf or a container?' — the recursive structure and shared interface handle that transparently, another instance of polymorphism at work.