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