Patterns are mechanisms that invoke an instant understanding of what's happening. At least they're supposed to be. In many scenarios, devs pause blankly for a moment trying to remember what processes that pattern name is supposed to represent.
I wonder if how we index software development patterns is one reason that many people don't remember and use them more often. For example, the Visitor pattern obviously implies that something goes and visits something else. Presumably this happens for decoupling reasons, but other than these basic assumptions, I can't really derive from the pattern name what the pattern really does, or what an optimal use case for it is.
I'm going to propose better names for several well known patterns. The names are longer, but I believe they do a much better job of explaining the pattern. I'll also give a tweet sized explanation. I call these pattern recipes.
Encapsulate a Task == Command
Make an object that can run a task, maybe even undo the task it ran, etc.
Register for Notifications == Observer
Registering and unregistering for notifications by letting an object call a known methods on you.
Algorithm delivery truck == Visitor
Visit me and run an algorithm or method on my data.
Composition over Inheritance == Strategy
Add behaviors by adding objects that encapsulate those behaviors.
Choose Implementation at Runtime == Factory
A class that manages creation, teardown, and resources of related implementations(subclasses).
Choose Implementation Groups at Runtime == Abstract Factory
A class that manages creation, teardown, and resources of implementation groups(factories).
Adapt One Call to Another == Adapter
With API mismatches, create a class that can converts data and bridge any mismatches.
Hide Complex Behavior == Facade
Make code easier to read and use by encapsulating more and hiding dependencies.
Template == Template :)
Like a mix of facade pattern and using an interface or subclasses
one easy call exists, which runs some more complex code. when that one simple call is running, there is the possiblity for it to ask some subclass or implementing class whether it should execute certain steps.
the simplest version is just a superclass and set of subclasses.
the more complex version then may or may not run specific parts of the complex code.
Mix Composition and Inheritance == Bridge pattern
By using both inheritance and composition, you can decouple more
if you have a long chain of subclasses, try keeping some as subclasses and turn others into a strategy of those subclasses
it also helps when you are mixing and matching classes instead of a Cartesian number of classes, you have just the number needed to represent different objects/behavior instead of objects X behavior.
Prototype == Prototype pattern
A polymorphic version of the copy constructor
deep copy an object in hopes of avoiding lots of init-calc code to recreate the same object
Add One Piece at a Time == Builder
Use if there are too many combinations for constructors...
return self to keep calling setters
Linked Wrappers == Decorator
Create a class for each attribute, rather than for all combination of attributes
Iterator == Iterator
separate algorithm and structure traversal from data container
A Tree with Branches and Leaves == Composite
Treat individual objects and groups of those objects in a similar fashion, like trees with branch and leaf nodes
interface -> both individual and group
this lets you iterate over a mixed hierarchy of this kind smoothly
Reuse Object Parts == Flyweight
Reuse the immutable parts of objects to save memory
I Know My Options == State
An object can change its behavior by changing its internal state. At a simple level, an object knows its state and the options for getting to a new state. Specifically, its state points to different subclasses of some interface dynamically during runtime.
Proxy == Proxy :)
Exactly what it says it is... it sits in front of some class, both the class and proxy implement the same method. The proxy can limit, change, or do whatever it wants to the call. It probably implements all the same methods as the class it is acting as proxy for. no changes to the original object are needed
Push the Problem Up the Ladder == Chain of Responsibility
Several classes that can handle a specific but different case to a problem all implement an interface. Each of these handlers knows about a sibling handler it can pass the problem to if it can't handle the problem.
Language Interpreter == Interpreter
Uses the composite pattern along with a context(parsing) class to process language.
Middleware == Mediator
When objects want to interact, a mediator can encapsulate this activity if there are too many relationships between objects.
Remember States at Points in Time == Momento
Snapshots, some managing class(could store a list of states) that interacts with some state class.
I hope this helps you remember what patterns really mean.
Subscribe to:
Posts (Atom)