Chapter 1, Introduction to patterns, introduces the concept of patterns. We'll see why patterns are useful and how they should be used in programming. The book will explore the difference between design principles, patterns, and idioms. It will present a hierarchical overview of design patterns, talk a bit about anti-patterns, and finish with a description of some important design principles.
Chapter 2, Singleton, Dependency Injection, Lazy Initialization, and Object Pool, covers four patterns from the creational group. The chapter will firstly look into the singleton pattern, which makes sure that a class has only one instance. Next in line, the dependency injection pattern makes program architecture more flexible and appropriate for unit testing. In the second half, the chapter explores two optimization patterns. The lazy initialization pattern saves time and resources, while the object pool pattern speeds up creation of objects.
Chapter 3, Factory Method, Abstract Factory, Prototype, and Builder, examines four more creational patterns. The factory method pattern simplifies creation of dependent objects. The concept can be extended into the abstract factory pattern, which functions as a factory of factories. The prototype pattern is used to create copies of objects. Last in this group, the builder pattern separates instructions for creating an object from its representation.
Chapter 4, Composite, Flyweight, Marker Interface, and Bridge, covers four patterns from the structural group. The composite pattern allows client code to treat simple and complex objects the same. The flyweight pattern can be used to minimize memory usage by introducing data sharing between objects. The marker interface allows us to unleash a new level of programming power by introducing metaprogramming. The bridge pattern helps us separate an abstract interface from its implementation.
Chapter 5, Adapter, Proxy, Decorator, and Facade, explores four more structural patterns. The adapter pattern helps in adapting old code to new use cases. The proxy pattern wraps an objects and exposes an identical interface to facilitate caching, remoting, and access control, among other things. The decorator pattern specifies how the functionality of existing objects can be expanded, while the facade pattern shows us how to create a simplified view of a complex system.
Chapter 6, Nullable Object, Template Method, Command, and State, covers four patterns from the behavioral group. The null object pattern can reduce the need for frequent if statements in the code. The template method pattern helps with creating adaptable algorithms. The command pattern shows how we can treat actions as objects. It is a basis for Delphi actions. The state pattern allows an object to change its behavior on demand and is useful when we are writing state machines.
Chapter 7, Iterator, Visitor, Observer, and Memento, examines four more behavioral patterns. The iterator pattern allows us to effectively access data structures in a structure-independent way. This pattern is the basis of Delphi's for..in construct. The visitor pattern allows us to extend classes in accordance with the Open/Closed design principle. To write loosely coupled programs that react to changes in the business model, we can use the observer pattern. When we need to store the state of a complex object, the memento pattern comes to help.
Chapter 8, Lock Patterns, is entirely dedicated to data protection in a multithreaded world, and covers five concurrency patterns. The lock pattern enables the code to share data between threads and is basis for other patterns from this chapter. The lock striping pattern specifies how we can optimize locking when accessing a granular structure, such as an array. The double-checked locking pattern optimizes creation of shared resources, while the optimistic locking pattern speeds up this process even more. The readers-writer lock is a special version of the locking mechanism designed for situations where a shared resource is mostly read from, and only rarely written to.
Chapter 9, Thread Pool, Messaging, Future, and Pipeline, finishes the overview of design patterns by exploring four more concurrency patterns. As a specialized version of the object pool pattern, the thread pool pattern speeds up thread creation. The messaging pattern can be used to remove shared data access completely, and by doing so, can simplify and speed up the program. The future pattern specifies how we can integrate parallel execution of calculations into existing code. This chapter ends with a discussion of the pipeline pattern, which is a practical application of messaging designed to speed up tasks that are hard to parallelize with other approaches.
Chapter 10, Designing Delphi Programs, steps away from the design patterns and talks about concepts that are important for Delphi programmers. In this chapter, you will learn about event-driven programming and how the Delphi's event system can be extended with multicast events. We will explore the actions mechanism, which serves as a nice example of the command pattern. After that, the chapter will spend some time looking into the LiveBindings mechanism, an implementation of the observer pattern. In the second half of this chapter, we'll see how we can use form inheritance to create forms in an object-oriented way, and how we can use frames to create forms by compositions. At the end, we'll look into data modules; that is, tools that can be used to implement the table module enterprise pattern.
Chapter 11, Other Kinds of Patterns, wraps up the book by exploring patterns in three areas. The first part of the chapter deals with the exceptions and introduces exception patterns; that is, a set of recommendations that will help you write better code. After that, a short treatise of debugging patterns tries to bring some order to the messy world of code debugging. To end the book, a short exploration of functional programming is used to explain how this kind of programming paradigm can be used in Delphi.