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