Understanding design patterns

When building software, we often find ourselves coming across similar challenges on a regular basis. How can we avoid creating unnecessary instances of a particular class? How can we control how a class is instantiated? How might we separate the way a specific decision is made from the rest of an algorithm? These are just a few examples of the types of problems software developers regularly face and that are potentially solved through the application of common design patterns.

So, let's begin by understanding what design patterns are. Design patterns collect common vocabulary, patterns, and best practices for solving some of the common software development challenges. Common design patterns will typically include descriptions of the problem they aim to solve, the motivations behind how they solve the problem, and some guidance for when you may want to use that pattern.

As the problem area of software development is quite broad, so is the number of common design patterns. The full list of established design patterns would be very large, and beyond the scope of this chapter. However, the following list provides a subset of design patterns that you may be familiar with, either directly or indirectly:

Design patterns manifest themselves at many different levels of the software development stack. You might apply the Iterator pattern when traversing an individual set of elements, you might leverage the Command pattern to implement undo/redo functionality for a user, or you might perhaps use the abstract Factory pattern to control how entire families of elements are created within your application.

Setting out to master all common design patterns could be quite the undertaking, something best cultivated over a career. However, learning when and how to apply any pattern can help make you a more efficient developer.

In this chapter, we're going to explore several design patterns that are common to object-oriented programming languages such as Java, and see how we can apply those patterns with Kotlin.

So, let's begin to study them in the following sections.