Pattren 3
Pattren 3
Sometimes it’s important for some classes to have exactly one instance
Singleton Design Pattern“Ensure a class only has one instance, and provide a global point of
access to it.”
A particular class should have only one instance. We will use only that instance whenever we are
in need.
WHERE TO USE?
The perfect example on when to use a singleton class is a logger implementation in which all the
resource write in the same log file and is thread safe. Other examples:
database connections and shared network resources;
whenever the application needs to read a file from the server. Only in this case the object of the
application will be able to access the files stored on the server.
config files;
The singleton pattern can be used with Abstract Factory, Builder, and Prototype design patterns to
have a unique object
Participant: Singleton
defines an Instance operation that lets clients access its unique instance.
EXAMPLE: LOGGER
We shouldn’t have to create the Logger class every time we public void LogMessage()
want to access this Shared Resource. Is there any reason to? {
//Open File "log.txt"
//Write Message
We need ONE.
//Close File
}
}
LOGGER – AS A SINGLETON Lazy Instantiation
Objects are only created when it is needed
public class Logger Helps control that we’ve created the Singleton just once.
{
private Logger(){}
if (uniqueInstance == null)
uniqueInstance = new Logger();
return uniqueInstance;
} Note the
} parameterless
constructor
THREADING What would happen if two
public class Singleton different threads accessed
this line at the same time?
{
private Singleton() {}
if (uniqueInstance == null)
uniqueInstance = new Singleton();
return uniqueInstance;
}
}
OPTION #1: SIMPLE LOCKING
return uniqueInstance;
}}
OPTION #2 – DOUBLE-CHECKED LOCKING
public class Singleton
{
private Singleton() {}
Suppose you are a member of a football team, and in a tournament your team is
going to play against another team.
As per the rules of the game, the captain of each side must go for a toss to decide
which side will get the ball first.
So, if your team does not have a captain, you need to elect someone as a captain
first. And at the same time, your team cannot have more than one captain.
In this example, we have MakeCaptain class which can be used to get a captain
object and it has a private constructor private, so that we cannot instantiate in
normal fashion.
When we attempt to create an instance of the class, we are checking whether we
already have one available copy. If we do not have any such copy, we’ll create it;
otherwise, we’ll simply reuse the existing copy.
OUTPUT:
IMPLEMENTATION
In the preceding example, we wrote a class with a method that creates a new instance of the class if one does not
exist.
Do note:
The constructor of the class is made private so that there is no other way to instantiate the class
The accessor function for obtaining the reference to the singleton object is defined public and static
This example is known as Lazy Initialization – which means that it restricts the instance creation until it is requested
for the first time.
PORS & CONS
Pros:
the singleton class is instantiated only once in the life cycle of the app;
you can use it as many times needed;
the singleton class cannot be extended and if it is implemented correctly i.e. the get method should be
synchronized and static,
it is thread safe;
Cons:
problems during testing. (when the singleton class accesses a shared resource and the execution of the tests is
important);
PROTOTYPE DESIGN PATTERN
Prototype is a creational design pattern that allows cloning objects, even complex
ones, without coupling to their specific classes.
All prototype classes should have a common interface that makes it possible to
copy objects even if their concrete classes are unknown.
Prototype objects can produce full copies since objects of the same class can
access each other’s private fields.
WHERE TO USE
When a system needs to be independent of how its objects are created, composed, and
represented.
When instances of a class can have one of only a few different combinations of state. It may be more
convenient to install a corresponding number of prototypes and clone them rather than instantiating the
class manually, each time with the appropriate state.
Prototype
declares an interface or abstract class for cloning itself.
ConcretePrototype
implements an operation for cloning itself.
Client
creates a new object by asking a prototype to clone itself.
Cloneable is an interface that is used to create the exact copy of an object. It exists in java. lang package. A class must
implement the Cloneable interface if we want to create the clone of the class object. The clone() method of the Object
class is used to create the clone of the object.
EXAMPLE
a smartphone company produces thousands of mobiles with the same hardware and software.
But with different model (color), the price could change.
We have:
– Basic prototype: SmartPhone abstract class with clone() method.
– Concrete prototypes: Samsung and Apple implement the clone() method.
IMPLEMENT JAVA PROTOTYPE PATTERN
CLASS DIAGRAM
@Override
public String toString() {
return "SmartPhone [model=" + getModel() + ", price=" +
getPrice() + "]";
}
}
Create subclass with clone() method Apple.java
Samsung.java
public class Samsung extends SmartPhone { public class Apple extends SmartPhone {
System.out.println(note10);
System.out.println(iphoneX);
Result: note10Gold.setAdditionalPrice(50);
System.out.println(note10Gold);
SmartPhone [model=Note10, price=700]
SmartPhone [model=iPhoneX, price=900] SmartPhone iphoneX128 = iphoneX.clone();
=== Products for VIPs === iphoneX128.setAdditionalPrice(100);
SmartPhone [model=Note10, price=750] System.out.println(iphoneX128);
SmartPhone [model=iPhoneX, price=1000]
}}
PROS & CONS OF USING PROTOTYPE PATTERN
Pros
Reusability: In case we want to create an instance of a class with many default values, or in same
complicated processes, Prototype Pattern is useful. We can focus on other activities instead.
Reducing initialization: We can create new instances at a cheaper cost.
Simple copy process: We only need to call clone() method, it is simple and easy-reading.
Cons
Each subclass have to implement clone() method or alternative copy methods.
Building clone for existing class may be complicated. For example, implementing Cloneable interface
can constrain all subclasses/implementation to implement clone() method (some class may not
need).
QUESTIONS!