general, reusable solutions to commonly occurring problems (non-language specific)
- Creational - Singleton, Factory, Prototype
- These are about instantiating objects.
- Structural - Flyweight
- These are about how do we use the objects that we've created.
- Behavioral - Iterator
- These are about what interface the objects provide to us.
What:
A class that only has one single instance.
How:
- Private constructor
- static instance field + static GetInstance method
- Then get instance by code like
Name & n = Name::GetInstance()
.
- Then get instance by code like
- private or deleted copy constructor and assignment operators
When to use:
- Logger System
- GUIs (Graphical User Interfaces) — certain windows
- Thread recycling pool
- When you actually need only 1 object to exist
When not to use:
- When you just want global variables.
- When you just want to save space (look at other alternatives).
What: One instance per type of the given class. to ponder: creational/structural/behavioral?
How: Often, you will use an array or fields (or a map) to store the examples of the objects that you're creating. Depends entirely on programmer discipline (in c++).
- In your "distribution" class - you will have method that will control the user's access to the objects
When to use:
- when an individual object is memory intensive and we are using the same kind over and over again
When not to use:
- No need to flyweight objects that are essentially glorified enums
What:
Specifies an order of traversal for a collection and provides a standard interface
to that traversal.
How:
- define the starting point for the iterator
- define how to go to the next element
- define the ending point for the iterator
collection<type>::iterator it = collection_var.begin();
while (it != collection_var.end()) {
// do whatever
std::cout << *(it) << std::endl;
it++;
}
Problem: sometimes objects are cumbersome to create, for instance with a class representing time.
Time class:
- Time(hours, minutes, seconds, timezone)
- Time(hours, minutes)
Provides an interface:
- get the current time
- get a time representing a certain date
- get a time X hours from now
What: a method or class whose primary objective is to manage the creation of other objects
- frequently used with inheritance (we won't look at this today, but have this on your radar)
- Abstract away constructors with many parameters/flags
- Manage any heavy dependcies between objects
- Manage creation of Flyweighted objects
How: Create a wrapper class or method for object constructors or linked dependencies.
When to use:
- if you have highly configurable objects with some common configurations
- if you need more control over creating objects
- if you have subclasses and you would like an easy interface to instantiate the specific subclass that you need
When not to use:
- for all objects (only use when you have a reason to)
- if your "basic" constructor will do, no need
Problem: you want the "client" to have a copy of an object without giving them the actual object. You want to control how objects are created.
How: provide a (virtual) Clone() method (examples in both PE 6 (Item) and in Creature)
- in C++, we have a copy constructor -- not the prototype design pattern is because:
- it is language specific
- these are not inherited (special inheritance rules)
When to use: When you want easy but controlled copying of an object
When not to use: In c++, if your only purpose is reimplementing the copy constructor