Design Patterns
Structural Patterns
Patterns for composing classes and objects into larger structures while keeping those structures flexible — wrapping, adapting, and simplifying without changing the components underneath.
- Adapter: converts one interface into another that a client expects — makes incompatible interfaces work together without modifying either side
- Decorator: attaches new behavior to an object dynamically by wrapping it in another object with the same interface — an alternative to subclassing for extending behavior
- Facade: provides a single simplified interface in front of a complex subsystem — hides complexity, doesn't add capability
- Composite: treats individual objects and compositions of objects uniformly through a shared interface — the natural fit for tree structures
- Proxy: stands in for another object, controlling access to it (lazy loading, access control, remote calls, caching) behind the same interface
| Pattern | Wraps to… | Changes the interface? |
|---|---|---|
| Adapter | make an incompatible interface fit | yes — translates one interface to another |
| Decorator | add behavior transparently | no — same interface, extra behavior |
| Proxy | control access transparently | no — same interface, extra control |
| Facade | simplify a subsystem | yes — offers a smaller, simpler interface |
interface DataSource { void write(String s); String read(); }
class FileDataSource implements DataSource { /* base behavior */ }
abstract class DataSourceDecorator implements DataSource {
protected final DataSource wrapped;
DataSourceDecorator(DataSource wrapped) { this.wrapped = wrapped; }
}
class CompressionDecorator extends DataSourceDecorator {
CompressionDecorator(DataSource wrapped) { super(wrapped); }
public void write(String s) { wrapped.write(compress(s)); }
public String read() { return decompress(wrapped.read()); }
}
// Stack decorators freely — this is exactly what new BufferedReader(new InputStreamReader(in)) does
DataSource source = new CompressionDecorator(new EncryptionDecorator(new FileDataSource()));