#Thinking in Patterns
##1: The pattern concept
###What is a pattern?
Initially, you can think of a pattern as an especially clever and insightful way of solving a particular class of problems.
###Pattern taxonomy
After some pondering, I’ve come up with a sort of hierarchy describing a succession of different types of categories:java
###The singleton
Possibly the simplest design pattern is the singleton, which is a way to provide one and only one object of a particular type. This is used in the Java libraries, but here’s a more direct example:app
//: c01:SingletonPattern.java // The Singleton design pattern: you can // never instantiate more than one. // Since this isn't inherited from a Cloneable // base class and cloneability isn't added, // making it final prevents cloneability from // being added through inheritance: final class Singleton { private static Singleton s = new Singleton(47); private int i; private Singleton(int x) { i = x; } public static Singleton getReference() { return s; } public int getValue() { return i; } public void setValue(int x) { i = x; } } public class SingletonPattern { public static void main(String[] args) { Singleton s = Singleton.getReference(); System.out.println(s.getValue()); Singleton s2 = Singleton.getReference(); s2.setValue(9); System.out.println(s.getValue()); try { // Can't do this: compile-time error. // Singleton s3 = (Singleton)s2.clone(); } catch(Exception e) { e.printStackTrace(System.err); } } } ///:~
The key to creating a singleton is to prevent the client programmer from having any way to create an object except the ways you provide. You must make all constructors private, and you must create at least one constructor to prevent the compiler from synthesizing a default constructor for you (which it will create as 「friendly」).
At this point, you decide how you’re going to create your object. Here, it’s created statically, but you can also wait until the client programmer asks for one and create it on demand. In any case, the object should be stored privately. You provide access through public methods. Here, getReference( ) produces the reference to the Singleton object. The rest of the interface (getValue( ) and setValue( )) is the regular class interface.
Java also allows the creation of objects through cloning. In this example, making the class final prevents cloning. Since Singleton is inherited directly from Object, the clone( ) method remains protected so it cannot be used (doing so produces a compile-time error). However, if you’re inheriting from a class hierarchy that has already overridden clone( ) as public and implemented Cloneable, the way to prevent cloning is to override clone( ) and throw a CloneNotSupportedException as described in Appendix A. (You could also override clone( ) and simply return this, but that would be deceiving since the client programmer would think they were cloning the object, but would instead still be dealing with the original.)
Note that you aren’t restricted to creating only one object. This is also a technique to create a limited pool of objects. In that situation, however, you can be confronted with the problem of sharing objects in the pool. If this is an issue, you can create a solution involving a check-out and check-in of the shared objects.ide
###Classifying patterns
The Design Patterns book discusses 23 different patterns, classified under three purposes (all of which revolve around the particular aspect that can vary). The three purposes are:
* 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 book you’ll see examples of Factory Method and Prototype. ui
###Exercisesthis