The concept of a pattern is simple to define. A pattern is something that you did in the past, was successful, and can be applied to multiple situations. Patterns capture experiences in software development that have been proven to work again and again, and thus provide a solution to specific problems. They are not invented: they arise from practical experience.
When many programmers are trying to solve similar problems, they arrive again and again at a solution that works best. Such a solution is later distilled into a solution template, something that we programmers then use to approach similar problems in the future. Such solution templates are often called patterns.
Good patterns are problem and language agnostic. In other words, they apply to C++ and Delphi, and to Haskell and Smalltalk. In practice, as it turns out, lots of patterns are at least partially specific to a particular environment. Lots of them, for example, work best with object-oriented programming (OOP) languages and do not work with functional languages.
In programming, patterns serve a dual role. Besides being a template for problem solving, they also provide a common vocabulary that programmers around the world can use to discuss problems. It is much simpler to say, for example, that we will use an observer pattern to notify subsystems of state changes than it is to talk at length about how that part will be implemented. Using patterns as a base for discussion therefore forces us to talk about implementation concepts, and not about the detailed implementation specifics.
It is important to note that patterns provide only a template for a solution and not a detailed recipe. You will still have to take care of the code and make sure that the pattern implementation makes sense and works well with the rest of the program.
Programming patterns can be split into three groups that cover different abstraction levels. At the very top, we talk about architectural patterns. They deal with program organization as a whole, with a wide, top-down view, but they do not deal with implementation. For example, the famous Model-View-ViewModel approach is an architectural pattern that deals with a user interface-business logic split.
Architectural patterns are not a topic of this book, but still I'll dedicate some space to them in Chapter 11, Other Kinds of Patterns.
A bit lower down the abstraction scale are design patterns. They describe the run—time behavior of a program. When we use design patterns, we are trying to solve a specific problem in code, but we don't want to go fully to the code level. Design patterns will be the topic of the first ten chapters.
Patterns that work fully on the code level are called idioms. Idioms are usually language specific and provide templates for commonly encountered coding problems. For example, a standard way of creating/destroying objects in Delphi is an idiom, as is iterating over an enumerable container with the for..in
construct.
Idioms are not the topic of this book. I will, however, mention the most important Delphi idioms, while talking about their specific implementation for some of the patterns.