Software Design Patterns
Currently adding documentation. Please check back often!
Contents in this section
- Classic Design Patterns (GoF)
- Microservices Design Patterns
- Conceptual Design Patterns
Additional Resources
In software engineering, a design pattern is a general repeatable solution to a commonly occurring problem in software design. It is most useful to think of design patterns as a "short-hand" means of describing a possible solution. Design Patterns aren't intended to be directives and they certainly aren't the only way to solve a particular type of problem, they are more akin to guidance as to how similar problems are solved. A design pattern isn't a finished design that can be transformed directly into code. It is a description or template for how to solve a problem that can be used in many different situations.
An analogy that I often use when talking about Design Patterns with developers and business leaders is that they are very similar to a roadmap (think Google Maps). The map will show any number of ways to get from where you are to where you want to be; however, it will also provide a recommended way to travel there. A design pattern is the recommended route. Just as with nearly any map application, you can choose to go off the beaten path and solve problems your own way. However, the solution described by the design pattern also takes into account numerous things that the developer may not even be aware of - just as a map application takes into account accidents, traffic, and so on. Software design patterns include considerations such as scalability, resiliancy, portability, ease of understanding, etc. In general, the pattern is the how this sort of problem is typically solved and any veering away from it should have a pretty strong reason for doing so.
Design patterns can speed up the development process by providing tested, proven development approaches. Effective software design requires considering issues that may not become visible until later in the implementation. Reusing design patterns helps to prevent subtle issues that can cause major problems and improves code readability for coders and architects familiar with the patterns. From a practical perspective, many developers only understand how to apply certain software design techniques to certain problems, particularly until they become more eperienced. These techniques are difficult to apply to a broader range of problems. Design patterns provide general solutions, documented in a format that doesn't require specifics tied to a particular problem or language.
In addition, patterns allow developers to communicate using well-known, well understood names for software interactions. Common design patterns can be improved over time, making them more robust than ad-hoc designs. In most cases, they have been countless times and have been proven to be effective and efficient.
Types of Design Patterns
Design Patterns exist all around us in software development and in business. While a quick search on the interent can return hundreds of variations and types of design patterns; for the purposes of this discussion, let's break them down into 3 basic categories - based on their usage.
CLASSIC DESIGN PATTERNS - The Gang of Four (GoF)
Here are the "classic" design patterns as described by the Gang of Four (GoF). Their work describes the fundamental patterns that are encountered in traditional Object-Oriented programming. Mostly likely, when you hear about design patterns in conversation, these are what are being referred to. Design Patterns: Elements of Reusable Object-Oriented Software is the first and probably the most famous book about the Design pattern. It was first published in 1995, but thankfully those design patterns are still valid and in common use today, the only outdated thing in this book may be the original Smalltalk programming language, used in some examples.
As in their classic book, I break the patterns down into simple categories: Creational, Structural, and Behavioral - only here, I use samples in a number of languages in more common use today. The pages here represent a summary of their fantasic work; but, provide enough detail to begin using them in your everyday work.
MICROSERVICES DESIGN PATTERNS
The main characteristics of microservices include: functional decomposition or domain-driven design, well-defined interfaces, explicitly published interface, single responsibility principle, and potentially polyglot. Each service is fully autonomous and full-stack. Thus changing a service implementation has no impact to other services as they communicate using well-defined interfaces. There are several advantages of such an application, but its not a free lunch and requires a significant effort.
But lets say you understand the required effort, or at least some pieces of it, that is required to build such an application and willing to take a jump. What do you do? What is your approach for architecting such applications? Are there any design patterns on how these microservices work with each other? Look no further, you will find them here!
Obviously, classic design patterns can be used within the context of microservices; however, the very nature of how microservices interact with each other pose challenges. The patterns described here focus on those interactions and provide proven solutions that you can leverage.
IMPLEMENTATION DESIGN PATTERNS
While the other sections for design patterns are well established and documented in the real world, it will occur to you as it did to me that there are a number of things and decisions that we make every day in the engineering world that fall in to the concept of a design pattern - e.g. a solid solution to a specific set of problem conditions. As engineers, architects, and leaders there are certain ways in which we solve problems, repeatedly in the same way. We do this beacuse it works. We do this beacuse we understand the consequences of our designs and we can anticipate where and when it makes sense to use it.
In this section, you will find (no doubt continually expanding) collection of "patterns" that you might find useful in your work. I know that they are an excellent reference for junior engineers, and like the other design pattern sections, provide a useful short hand way of describing solutions to common issues. Some of these patterns may be trivial to implement depending on your choice of programming language or environment. Others may not be necessary at all in some environments such as in the cloud.