Design Patterns: Elements of Reusable Object-Oriented Software. Erich Gamma, Richard Helm, John Vlissides, Ralph Johnson.