GoF Design Patterns in Dart
Back in the ’90s, a group of four authors released a book that became standard reading for any self-respecting software developer, the Gang of Four’s Design Patterns book. Along with Fred Brooks’s Mythical Man-Month, Don Knuth’s The Art of Computer Programming series, these books are still fundamental to our profession and I still recommend them for assigned reading for any software developer who hasn’t read them. Your books shelf is not complete without them!
These books not only have helped to build the foundations of modern software development, and development processes but, have also developed the language and design methodologies we use. So if you have not read them, you haven’t completed your basic education in Computer Science.
Who are they Anyway?
The Gang of Four (GoF) are the four authors of “Design Patterns: Elements of Reusable Object-Oriented Software” published in 1994 by Pearson Education: Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides.
What is a Design Pattern?
Design patterns are repeatable solutions to commonly occurring problems in software design.
Why Design Patterns?
A civil engineer, Christopher Alexander is the one who coined the term design patterns while working on designing buildings and towns. He noticed that there were common design problems and certain design constructs that could be used to solve those classes of recurring problems. He documented and published his experiences. At least one of the GoF authors was aware of Christopher’s work and felt the phrase “design pattern” also fit their work as well.
Are Design Patterns Still Relevant?
The short answer: YES! The long answer: YES! YES! YES!
These patterns are important for many reasons. First, as a programmer, they give you another set of tools in your toolbox to choose from. Have you ever noticed a young boy building a treehouse has only one hammer that he uses for everything! But when he grows into a man and becomes a professional, he has several hammers. Framing hammers for driving framing and box nails. Finnish hammers for driving small nails right to the surface of molding without damaging the surface. Roofing hammers for splitting and shimming and nailing shake, etc… The same is true for the mechanic. As a boy, he has only a few tools. But as he matures he acquires specialty tools meant for very specific jobs. Wrenches of odd shapes so they fit into tight spaces, etc. These patterns are the tools in the professional software developer’s toolbelt. Indeed many of these patterns have worked their way into the languages we use today as integral language features.
How Many Patterns Are There?
The GoF book included 23 patterns split into 3 categories as follows:
Criational patterns provide ways to instantiate single objects or groups of related objects. There are five such patterns:
- Abstract Factory: The abstract factory pattern is used to provide a client with a set of related or dependent objects. The “family” of objects created by the factory is determined at run-time.
- Builder: The builder pattern is used to create complex objects with constituent parts that must be created in the same order or using a specific algorithm. An external class controls the construction algorithm.
- Factory Method: The factory pattern is used to replace class constructors, abstracting the process of object creation so that the type of object created can be determined at run-time.
- Prototype: The prototype pattern is used to instantiate a new object by copying all of the properties of an existing object. This practice is useful when the constructor of a new object is inefficient.
- Singleton: The singleton pattern ensures that only one object of a particular class is ever created. All further references to objects of the singleton class refer to the same underlying object instance.
Structural patterns define relationships between classes.
- Adapter: The adapter pattern is used to provide a link between two otherwise incompatible types by wrapping the “adapted” with a class that supports the interface required by the client.
- Bridge: The bridge pattern is used to separate the abstract elements of a class from the implementation details, providing a means of replacing the implementation without modifying the abstraction.
- Composite: The composite pattern is used to create hierarchical, recursive tree structures of related objects where any element of the structure may be accessed and utilized in a standard manner.
- Decorator: The decorator pattern is used to alter or extend the functionality of objects at run-time by wrapping them in a decorator class. This provides an alternative to using inheritance to modify behavior.
- Facade: The facade pattern defines a simplified interface to a more complex subsystem.
- Flyweight: The flyweight pattern is used to reduce memory and resource usage for complex models containing large collections of similar objects.
- Proxy: The proxy pattern provides a surrogate or placeholder object, which references an underlying object. The proxy provides the same interface as the underlying class, adding a level of indirection.
Behavioural patterns define the manners in which classes and objects communicate.
- Chain of Responsibility: This pattern is used to process varied requests, each of which may be dealt with by a different handler.
- Command: The command pattern is used to express a call to be made and all its parameters in a command object, which may then be executed immediately or held for later execution.
- Interpreter: The interpreter pattern is used to define the grammar for instructions that form part of a language or notation while allowing the grammar to be easily extended.
- Iterator: The iterator pattern is used to provide a standard interface for traversing a collection of items in an aggregate object without the need to understand its internal structure.
- Mediator: The mediator pattern is used to reduce coupling between classes that must communicate with each other. Instead of communicating directly, the classes send messages via a mediator object and thus do not require intimate knowledge of each other.
- Momento: The moment pattern is used to capture the current state of an object and store it away so that it may be restored at a later time.
- Observer: The observer pattern is used to allow an object to publish changes to its state. Other objects may subscribe to be notified of these changes. In more recent years this has become known as pub/sub.
- State: The state pattern is used to alter the behaviour of an object as its internal state changes. The pattern allows the class of an object to apparently change at run-time.
- Strategy: The strategy pattern is used to create an interchangeable family of algorithms from which the required process is chosen at run-timer.
- Template Method: The template method pattern is used to define the basic steps of an algorithm and allow the implementation of the individual steps to be changed.
- Visitor: The visitor pattern is used to separate a relatively complex set of structured data classes from the functionality that may be performed upon the data that they hold.
Ok, now that we’ve seen the list of patterns, it’s time to actually learn them. This may seem like a daunting task at first. I wouldn’t sit down and try to learn them all at once. Instead, learn a few each month and try to write some applications to use them. If you memorize them it won’t be long before you forget them all. But if you use them, you’ll recall them much longer and when you see a circumstance where a pattern can help, you may not recall the name but you will know where to look to find the name and details of the pattern. After doing this a few times you’ll begin to learn the patterns that are helpful in your area and forget the others.
I’m going to start off with the easiest pattern to understand. That for most people is the singleton pattern. So, either click the link here or on the link in the list, and let’s get started.