When to use Flashcards
You want to use different variants of an algorithm within an object and be able to switch from one algorithm to another during runtime
Strategy
You have a lot of similar classes that only differ in the way they execute some behavior.
Strategy
You want isolate the business logic of a class from the implementation details of algorithms that may not be as important in the context of that logic.
Strategy
Your class has a massive conditional statement that switches between different variants of the same algorithm.
Strategy
Changes to the state of one object may require changing other objects, and the actual set of objects is unknown beforehand or changes dynamically.
Observer
Some objects in your app must observe others, but only for a limited time or in specific cases.
Observer
You need to be able to assign extra behaviors to objects at runtime without breaking the code that uses these objects.
Decorator
It’s awkward or not possible to extend an object’s behavior using inheritance.
Decorator
You don’t know beforehand the exact types and dependencies of the objects your code should work with.
Factory Method
You want to provide users of your library or framework with a way to extend its internal components
Factory Method
You want to save system resources by reusing existing objects instead of rebuilding them each time
Factory Method
Your code needs to work with various families of related products, but you don’t want it to depend on the concrete classes of those products—they might be unknown beforehand or you simply want to allow for future extensibility
Abstract Factory
You have a class with a set of Factory Methods that blur its primary responsibility
Abstract Factory
You want to parametrize objects with operations
Command
You want to queue operations, schedule their execution, or execute them remotely
Command
You want to implement reversible operations
Command
You want to use some existing class, but its interface isn’t compatible with the rest of your code
Adapter
You want to reuse several existing subclasses that lack some common functionality that can’t be added to the superclass
Adapter
You need to have a limited but straightforward interface to a complex subsystem
Fasade
You want to structure a subsystem into layers
Fasade
You have a heavyweight service object that wastes system resources by being always up, even though you only need it from time to time - lazy initialization
Proxy
You want only specific clients to be able to use the service object; for instance, when your objects are crucial parts of an operating system and clients are various launched applications (including malicious ones)
Proxy
Local execution of a remote service. This is when the service object is located on a remote server
Proxy
You want to keep a history of requests to the service object.
Proxy
You need to cache results of client requests and manage the life cycle of this cache, especially if results are quite large
Proxy
You need to be able to dismiss a heavyweight object once there are no clients that use it
Proxy
You want to divide and organize a monolithic class that has several variants of some functionality (for example, if the class can work with various database servers)
Bridge
You need to extend a class in several orthogonal (independent) dimensions.
Bridge
You need to be able to switch implementations at runtime
Bridge, Strategy
You want to let clients extend only particular steps of an algorithm, but not the whole algorithm or its structure
Template Method
You have several classes that contain almost identical algorithms with some minor differences. As a result, you might need to modify all classes when the algorithm changes
Template Method
You have to implement a tree-like object structure
Composite
You want the client code to treat both simple and complex elements uniformly
Composite
Your collection has a complex data structure under the hood, but you want to hide its complexity from clients (either for convenience or security reasons).
Iterator
Your code to be able to traverse different data structures or when types of these structures are unknown beforehand.
Iterator
You have an object that behaves differently depending on its current state, the number of states is enormous, and the state-specific code changes frequently
State
You have a class polluted with massive conditionals that alter how the class behaves according to the current values of the class’s fields
State
You have a lot of duplicate code across similar states and transitions of a condition-based state machine
State
Use the this pattern to get rid of a “telescopic constructor” (constructor with several optional parameters)
Builder
Use this pattern when you want your code to be able to create different representations of some product (for example, stone and wooden houses)
Builder
Use this pattern to construct Composite trees or other complex objects
Builder
Use this pattern when your code shouldn’t depend
on the concrete classes of objects that you need to copy
Prototype
Use the pattern when you want to reduce the number of subclasses
that only differ in the way they initialize their respective
objects. Somebody could have created these subclasses to
be able to create objects with a specific configuration
Prototype
Use this pattern when a class in your program should
have just a single instance available to all clients; for example,
a single database object shared by different parts of the
program.
Singleton
Use this pattern when you need stricter control over
global variables
Singleton
Use the this pattern only when your program must support a huge number of objects which barely fit into available RAM.
Flyweight
Use this pattern when your program
is expected to process different kinds of requests in various
ways, but the exact types of requests and their sequences are
unknown beforehand
Chain of Responsibility
Use the pattern when it’s essential to execute several handlers
in a particular order
Chain of Responsibility
Use the this pattern when the set of handlers and their order
are supposed to change at runtime
Chain of Responsibility
Use this pattern when it’s hard to change some of the
classes because they are tightly coupled to a bunch of other
classes
Mediator
The pattern lets you extract all the relationships between
classes into a separate class, isolating any changes to a specif-
ic component from the rest of the components
Mediator
Use the pattern when you can’t reuse a component in a differ-
ent program because it’s too dependent on other components
Mediator
Use the pattern when you find yourself creating tons of com-
ponent subclasses just to reuse some basic behavior in various
contexts
Mediator
Use the pattern when you want to produce snapshots of the object’s state to be able to restore a previous state
of the object
Memento
Use the pattern when you need to deal with transactions (i.e., if you need to roll back an operation
on error)
Memento
Use the patern when you need to perform an operation on all elements of a complex object structure (for example, an object tree).
Visitor
Use the pattern to clean up the business logic of auxiliary behaviors.
Visitor
Use the pattern when a behavior makes sense only in some classes of a class hierarchy, but not in others.
Visitor