180 likes | 204 Views
Learn about Prototype Pattern - Intent, Applicability, Structure, Participants, Consequences (Good and Bad), Implementation Tips, Related Patterns. Type Laundering - solving issues in domain-specific subclass creation and operations access.
E N D
Prototype Pattern & Type Laundering Billy Bennett June 22, 2009
Prototype Pattern • Intent • Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype
Prototype Pattern • Applicability • System must be independent of how products are created, composed, and represented (usually true of Creational patterns) AND • Classes to instantiate are specified at run-time • To avoid building a class hierarchy of factories for a class hierarchy of products • Instances of classes have only a few different combinations of state
Prototype Pattern Structure
Prototype Pattern • Participants • Prototype – declares an interface for cloning itself • ConcretePrototype – implements an operation for cloning itself • Client – creates a new object by asking a prototype for a clone of itself
Prototype Pattern • Consequences – GOOD • Can add/remove products at run time • Can specify new objects by varying values • Can specify new objects by varying structure • Less subclassing – why is everyone so down on inheritance? • Configuring an application with classes dynamically
Prototype Pattern • Consequences – BAD • Every subclass of Prototype must implement the Clone operation • Can be difficult when classes to be constructed already exist • Can be difficult when internal objects within a Prototype can’t be copied or have circular references
Prototype Pattern • Implementation Tips • Using a prototype manager • Implementing the Clone operation • Initializing Clones
Prototype Pattern • Related Patterns • Often used with Composite or Decorator • Abstract Factory • May compete with Prototype • May store a set of Prototypes
Type Laundering • To Start: • We have an abstract base class “Event” • Event has few operations • virtual long timestamp() = 0; (time of event) • virtual const char* rep() = 0; (packet of data) • The problem: no universal interface to define events • A vending machine would need CoinType() and CoinReturn(), etc.
Type Laundering • The Questions: • 1. How does the framework create instances of domain-specific subclasses? • 2. How does the application code access subclass-specific operations, when all it gets is an Event object?
Type Laundering • The Questions: • 1. How does the framework create instances of domain-specific subclasses? • How about Prototype? • Add an operation to the base Event class: virtual Event* copy() • Can be an instance of any Event subclass
Type Laundering • The Questions: • 2. How does the application code access subclass-specific operations, when all it gets is an Event object? • We could just dynamic_cast over and over…Yuck • We could use Visitor… • add void accept(EventVisitor&) to base Event class • But then we have to define a bunch of domain-specific events within the Visitor class…Yuck (just like dynamic casting)
Type Laundering • Another solution – Memento • Implement a cursor (a la Iterator) as a Memento itself • “Type Laundering” – define a cursor base class that indicates which aspects of the cursor should be public (e.g. the destructor)