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