Design Patterns Elements of Reusable Object Oriented Software