The self-referencing in step 3 may sound implausible, but as we explained in Chapter 5, it works because there is only a static data dependency on the template argument in the Singleton template. In other words, the code for the class Singleton
It’s interesting how intricate implementing such a simple pattern as Singleton can be. We haven’t even addressed issues of thread safety, and yet many pages have elapsed since the beginning of this section. The last thing we wish to say about Singleton is that it should be used sparingly. True Singleton objects arise rarely, and the last thing a Singleton should be used for is to replace a global variable.[120]
Classifying patterns
1.Creational: how an object can be created. This often involves isolating the details of object creation so your code isn’t dependent on what types of objects there are and thus doesn’t have to be changed when you add a new type of object. The aforementioned Singleton is classified as a creational pattern, and later in this chapter you’ll see examples of Factory Method.
2.Structural: designing objects to satisfy particular project constraints. These affect the way objects are connected with other objects to ensure that changes in the system don’t require changes to those connections.
3.Behavioral: objects that handle particular types of actions within a program. These encapsulate processes that you want to perform, such as interpreting a language, fulfilling a request, moving through a sequence (as in an iterator), or implementing an algorithm. This chapter contains examples of the Observer and the Visitor patterns.
Features, idioms, patterns
Work is continuing beyond what is in the GoF book, of course; hence, there are more patterns and a more refined process on defining design patterns in general.[121] This is important because it is not easy to identify new patterns or to properly describe them. There is some confusion in the popular literature on what a design pattern is, for example. Patterns are not trivial nor are they typically represented by features that are built into a programming language. Constructors and destructors, for example, could be called the "guaranteed initialization and cleanup design pattern." These are important and essential constructs, but they’re routine language constructs and are not rich enough to be considered a design pattern.
Another non-example comes from various forms of aggregation. Aggregation is a completely fundamental principle in object-oriented programming: you make objects out of other objects. Yet sometimes this idea is erroneously classified as a pattern. This is unfortunate because it pollutes the idea of the design pattern and suggests that anything that surprises you the first time you see it should be made into a design pattern.
Yet another misguided example is found in the Java language; the designers of the JavaBeans specification decided to refer to the simple "get/set" naming convention as a design pattern (for example, getInfo( ) returns an Info property and setInfo( ) changes it). This is just a commonplace naming convention and in no way constitutes a design pattern.
Building complex objects
The class that will be created in the next example models a bicycle that can have a choice of parts, according to its type (mountain bike, touring bike, or racing bike). This is called the Builder design pattern. A builder class is associated with each flavor of bicycle, each of which implements the interface specified in the abstract class BicycleBuilder. A separate class, BicycleTechnician, uses a concrete BicycleBuilder object to construct a Bicycle object.
//: C10:Bicycle.h
// Defines classes to build bicycles
// Illustrates the Builder Design Pattern
#ifndef BICYCLE_H
#define BICYCLE_H
#include
#include
#include
class BicyclePart {
public: