Lecture 19
Last updated
Last updated
Methods in this pattern create objects for us, without having to specify which exact type of object to create
Factory Method Pattern Example:
Write a video game with 2 kinds of enemies: turtle and bullets
System randomly sends turtle and bullets, but bullets more frequent in harder levels
Example UML:
Never know exactly which enemy comes next, so can't call turtle/bullet constructors directly
Instead, put a factory method in Level that creates enemies
design pattern where we override some behaviour from a superclass, but not all of it
superclass is used as a template for subclass
Template Method:
method that outlines an algorithm
May have steps of the algorithm call virtual methods (often private) which are implemented in subclass
Does most of the work, but subclasses responsible for implementing
Want subclasses to override superclass behaviour, but some aspects must stay the same
eg. There are red and green turtles
Example:
Subclasses can't change the way a turtle is drawn (head, shell, feet), but can change the way the shell is drawn
Generalization: the Non-Virtual Interface (NVI) idiom
A public virtual method is really 2 things:
Interface to the client (public)
indicates provided behaviour with pre/post conditions
Interface to subclasses (virtual)
a "hook" to insert specialized behaviour
However, these two are conflicting goals.
NVI says:
All public methods should be non-virtual.
All virtual methods should be private (or at least protected)
(Except the destructor)
Example:
Generalizes TemplateMethod
puts every virtual method inside a template method
eg. "arrays" that map strings to ints
Important Note: If you call a key that does not exist, the map will create a key with initial value of 0 for ints
Iterates in sorted key order
i.e. does not iterate in order that you added into the map like an array
notice p.first
and p.second
are FIELDS, not METHODS
pair is a template structure, and the fields are actually PUBLIC
Why is this ok?
Because pair is not an abstraction and there is no invariance - you WANT to manipulate the keys (the struct only acts like glues, there are no rules)
For implementing double dispatch
Double Dispatch: Dispatching methods based on type of multiple objects, also used for adding extra functionality to class hierarchy without changing any of the classes in the hierarchy
Virtual methods in Visitor Pattern are chosen based on the actual type (at runtime) of the receiving object
What if you want to choose based on two objects? eg. striking enemies with weapon
Want something like virtual void (Enemy, Weapon)::strike();
If strike is a method of Enemy - choose based on enemy, but on a weapon If strike is a method of Weapon - choose based on weapon but not on enemy
The trick is to get dispatch on both (double dispatch)
combines overriding and overloading
**Bullet::beStruckBy
runs (virtual method)
calls Weapon::strike
, *this is a bullet
Bullet version of strike is chosen at compile-time
virtual method strike on Weapon resolves to Stick::strike(Bullet &b)