A design pattern is an established general solution to a commonly occurring software development problem. It is also the developers' common vocabulary when discussing common problems and solutions.
Singleton design Patten
There are times when we want only one instance of a particular type of object in memory. The singleton pattern is a creational pattern focused on creating only one instance of an object in memory within an application, sharable by all classes and threads within the application. The globally available object created by the singleton pattern is referred to as a singleton.
OCPJP test a few ways to implement a singleton.
1. Minimal Singleton
The following Listing shows a minimal version of a singleton:
public class MinimalSingleton {
private MinimalSingleton() {...}
private static final MinimalSingleton INSTANCE = new MinimalSingleton();
public static MinimalSingleton getInstance() {
return INSTANCE;
}
}
The constructor is private so it can not be called outside MinimalSingleton class. Also, the private static final variable INSTANCE can not be modified once it is initialized at class loading time, thus become a singleton. This singleton is exposed in getInstance method, the callers of this class always get the same read-only object.
The class in the above listing immediately loads the instance of the class when the application starts even if the instance is not needed. There is an approach called lazy loading that allows a late loading of the instance of a singleton in memory.
2. Lazy-Loading Singleton
public class LazyLoadSingleton {
private LazyLoadSingleton() {
/* the body of the constructor here */
}
private static LazyLoadSingleton INSTANCE;
public static LazyLoadSingleton getInstance() throws Throwable {
if (INSTANCE == null) {
INSTANCE = new LazyLoadSingleton();
}
return INSTANCE;
}
}
The code in the above List is not correct in a multithreaded environment and is susceptible to returning more than one instance of the singleton if the method getInstance() is not protected by a synchronization.
3. Synchronized Singleton
public class SynchronizedSingleton {
private SynchronizedSingleton() {
/* the body of the constructor here */
}
private static SynchronizedSingleton INSTANCE;
public static synchronized SynchronizedSingleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new SynchronizedSingleton();
}
return INSTANCE ;
}
}
getInstance() method is now synchronized, which ensures that only one thread will be allowed in the method at a time.
Immutable classes
The immutable object pattern is a creational pattern based on the idea of creating objects whose state does not change after they are created and can be easily shared cross multiple classes. Since the state of an immutable object never changes, they are thread-safe.
A common strategy to make a class immutable is:
- Use a constructor to set all properties of the object.
- Make all the instance variables private and final.
- provide no setter methods.
- prevent methods from being overridden.
- never return mutable objects' reference to the class user.
final public class ImmutableRGB { final private int red; final private int green; final private int blue; final private String name; public ImmutableRGB(int red, int green, int blue, String name) { this.red = red; this.green = green; this.blue = blue; this.name = name; } public int getRGB() { return ((red << 16) | (green << 8) | blue); } public String getName() { return name; } public ImmutableRGB invert() { return new ImmutableRGB(255 - red, 255 - green, 255 - blue, "Inverse of " + name); } }