Design patterns notes (and Java examples)
As I've been getting back into Java programming lately, I've been taking a little time each night to read about design patterns, and make notes about each design pattern, especially as it relates to the Java programming language.
Here then are my abridged notes about the most common design patterns, including Java examples as I was able to think of them.
Creational Patterns
Factory Pattern
- (I'm not making a distinction between the Factory Pattern, Abstract Factory, and others.)
- A Factory returns an instance of an object based on the data supplied to it.
- The instance returned can be one of many classes that extend a common parent class or interface. ("Animal" as a parent class, then "Dog", "Cat", "Zebra" as child classes.)
- Create objects without exposing their instantiation logic.
- Consequences: The requestor is independent of the concrete object that is created (how that object is created, and which class is actually created).
Builder Pattern
- Separates the construction of an object from its representation so that several different representations can be created.
- Lets a client object construct a complex object by specifying only its type and content.
- Often used in creating displays with widgets.
Object Pool Pattern
- Re-use and share objects that are expensive to create (database connection, remote objects)
- Java examples: Database connection pooling.
Prototype Pattern
- Specify the general class needed, but defer specifying the exact class until execution time.
- Copying/cloning a prototype object.
- The cloned instances can then be tailored to the current needs.
- Note: There is a "deep clone" trick in Java that uses serialization. (Write current object out, then read it back in.)
Singleton Pattern
- Only one instance of a class, and a single, global point of access to that instance.
- Useful when you have one physical resource (display, comm port).
- Enforce with a private constructor.
- Java examples: javax.comm port, Runtime class.
- Consequences: Exactly one instance of the Singleton exists. Subclassing a Singleton is awkward.
Behavioral Patterns
Chain of Responsibility
- One object fires a request, other objects in a chain can respond to that request.
- Objects are added to the chain as in the usual Java Listener manner.
- The request can be handled in the chain, or not.
- Chain is usually linear, but can be more complex, as in a tree.
- Benefits: Objects are decoupled. Sender knows nothing about receivers.
- Java examples: AWT/Swing events.
Command Pattern
- Encapsulate a request in an object that has a known, public interface.
- Use objects to represent the execution of commands.
- Supports logging and undoable commands.
- Java examples: The Swing Action class?
- Main disadvantage is a proliferation of little classes.
Interpreter Pattern
- How to include language elements in a program.
Mediator Pattern
- Simplify communication between objects by keeping all objects from having to know about each other.
- Promotes loose coupling. (Its the only class that knows the details of the other classes that are communicating.)
Iterator Pattern
- Access elements of an aggregate object without exposing representation
- Java examples: Iterator in Collection classes
Memento Pattern
- Save data about an object so you can restore it later.
- Three roles: Originator, Memento, and Caretaker.
- Lets you save object state while also preserving encapsulation.
Observer Pattern
- Lets one object notify multiple other objects about a change in its state.
- One to many relationship, observable class fires an event, others observe
- Java example: TableModel, ListModel, more general Observer/Observable.
State Pattern
- Have an object that represents the state of your application.
- Switch objects to change state.
- Consequences: Create a basic State object with subclasses. Avoids if/else conditionals.
Strategy Pattern
- A family of interchangeable algorithms that do something similar.
- Provide a way to choose the appropriate one.
- They all have a common interface.
Template Pattern
- Define the skeleton of a class, implement some behavior, let subclasses implement additional behavior.
Visitor Pattern
- Adds polymorphic functions to a class non-invasively.
- Create an external class to act on data in other classes.
- Useful when you want to add a polymorphic function that can't reside in the class hierarchy.
- Probably end up subclassing objects and adding something like an accept() method.
Structural Patterns
Adapter
- Make one class interface match another to simplify programming.
- Java examples: KeyAdapter, MouseAdapter, MouseMotionAdapter, more ...
Bridge
- Separate an object's interface from its implementation so you can vary them separately.
Composite
- Create an object which is a composition of other objects.
- Java examples: DefaultMutableTreeNode (JFrame, JPanel, JComponent), JFrame, JToolBar, JTable.
Decorator
- Add responsibilities to an object dynamically.
- "Modify behavior of individual objects without having to create a new derived class." (DecoratorButton example in JDP book.)
- Also known as the "Wrapper" pattern.
Facade
- Provides an interface to a set of classes that you want your classes to use, instead of interacting with that set.
- Wrap a set of classes into a more simple interface.
- "A simplified interface to subsystems."
- Java example: JDBC.
Flyweight
- Sharing objects, typically to save space/resources.
- Each instance may not contain its own state, but store it externally.
Proxy
- A simple object that takes the place of a more complex object that may be invoked later.
- Java examples: The proxy references you create when using RMI.
Design patterns - benefits and consequences
I'm a little short on time today, so I haven't taken the time to document the benefits and consequences of each design pattern, but I will try to come back and do that at another time.
Design patterns in Java
Some of these notes and examples come from the books I've been reading, and I want to credit those books:
- Java Design Patterns, James A. Cooper
- Effective Java, Joshua Bloch
- Patterns in Java, Volume 1
- Design Patterns Smalltalk Companion
I've also written about many of these design patterns in more detail in my Java design patterns examples and tutorials on the devdaily.com website.
Recent blog posts
- Free Scala and functional programming video training courses
- Free: Introduction To Functional Programming video training course
- The #1 functional programming (and computer programming) book
- The User Story Mapping Workshop process
- Alvin Alexander, Certified Scrum Product Owner (CSPO)
- Alvin Alexander is now a Certified ScrumMaster (CSM)
- Our “Back To Then” app (for iOS and Android)
- A Docker cheat sheet
- Pushing a Scala 3 JAR/Docker file to Google Cloud Run
- Reading a CSV File Into a Spark RDD (Scala Cookbook recipe)