0% found this document useful (0 votes)
71 views37 pages

Lab13 Intro and Singleton

The document discusses the Singleton design pattern. It begins by defining what design patterns are and why they are useful. It then explains the Singleton pattern specifically - ensuring a class only has one instance and providing a global access point. Examples are given of when to use a Singleton, including for logging, caching, and accessing external resources. Implementation techniques are covered, such as lazy initialization, differences from static variables, and threading considerations like simple locking, double-checked locking, and eager initialization.

Uploaded by

Jinwoo Song
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
71 views37 pages

Lab13 Intro and Singleton

The document discusses the Singleton design pattern. It begins by defining what design patterns are and why they are useful. It then explains the Singleton pattern specifically - ensuring a class only has one instance and providing a global access point. Examples are given of when to use a Singleton, including for logging, caching, and accessing external resources. Implementation techniques are covered, such as lazy initialization, differences from static variables, and threading considerations like simple locking, double-checked locking, and eager initialization.

Uploaded by

Jinwoo Song
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 37

Object Oriented Programming

Lab 13
Contents
• Introduction to Design Patterns
– What is a Design Pattern
– Why Study Design Patterns
– The Gang of Four

• The Singleton Pattern


– Logger Example
– Lazy instantiation
– Singleton vs. Static Variables
– Threading: Simple, Double-Checked, Eager Initialization

2
What is a Design Pattern
• A problem that someone has already solved
• A model or design to use as a guide

• More formally: “A proven solution to a common problem in a


specific context”

• Real World Examples


– Blueprint for a house
– Manufacturing

3
Why Study Design Patterns?
• Provides software developers a toolkit for handling problems that
have already been solved

• Provides a vocabulary that can be used amongst software


developers
– The Pattern Name itself helps establish a vocabulary

• Helps you think about how to solve a software problem

4
The Gang of Four
• “Design Patterns: Elements of Reusable Object-Oriented Software”
by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides

• Defines a Catalog of different design patterns

• Three different types


– Creational: “Creating objects in a manner suitable for the situation”
– Structural: “Ease the design by identifying a simple way to realize
relationship between entities
– Behavioral: “Common communication patterns between objects”

5
The Gang of Four: Pattern Catalog
Creational Behavioral
Abstract Factory Chain of Responsibility
Builder Command
Factory Method Interpreter
Prototype Iterator
Singleton Mediator
Memento
Structural Observer
Adapter State
Bridge Strategy
Composite Template Method
Decorator Visitor
Façade
Flyweight
Proxy

6
How Design Patterns Solve Design
• Finding Appropriate Objects
• Determine Object Granularity
• Specify Object Interfaces
• Specifying Object Implementations
– Programming to an interface, not an implementation
• Encourage Reusability
– Inheritance vs. Composition
• Support Extensibility
– Frameworks

7
Reality
• Problems with design early on
– It is sometimes very hard to “see” a design pattern
– Not all requirements are known
– A design that is applicable early on becomes obsolete
– “Paralysis by Analysis”

• Due to these realities, refactoring is inevitable!

8
Common Pitfall
• “I just learned about Design Pattern XYZ, Let’s use it!”

• Reality: If you are going to use a Design Pattern, you should have
a reason to do so

• The software requirements should really drive why you are going
to use (or not use) a Design Pattern

9
Example: Logger
• What is wrong with this code?

public class Logger {

public Logger() {}

public void LogMessage() {


//Open File “log.txt”
//Write Message
//Close File
}
}

10
Example: Logger (Contd)
• Since there is an external Shared Resource (“log.txt”), we want to
closely control how we communicate with it

• We shouldn’t create an object of the Logger class every time we


want to access this Shared Resource. Is there any reason for that?

• We need ONE

11
Singleton
• GoF Definition: “The Singleton Pattern ensures a class has only
one instance, and provides a global point of access to it.”

• Best Uses
– Logging
– Caches
– Registry Settings
– Access External Resources
• Printer
• Device Driver
• Database

12
Logger – as a Singleton
public class Logger
{
private Logger() {}

private static Logger uniqueInstance;

public static Logger getInstance()


{
if(uniqueInstance == null)
uniqueInstance = new Logger();

return uniqueInstance;
}
}

13
Lazy Instantiation
• Objects are only created, when it is needed

• Helps control that we’ve created the Singleton just once

• If it is resource intensive to set up, we want to do it once

14
Singleton vs. Static Variables
• What if we had not created a Singleton for the Logger class?

• Let’s pretend the Logger() constructor did a lot of setup


• In our main program file, we had this code:

public static Logger MyGlobalLogger = new Logger();

• All of the Logger setup will occur regardless if we ever need to


log or not

15
Threading
public class Singleton
{ What would happen if two
private Singleton() {} different threads accessed
this line at the same time?

private static Singleton uniqueInstance;


public static Singleton getInstance()
{
if(uniqueInstance == null)
uniqueInstance = new Singleton();

return uniqueInstance;
}
}

16
Threading (Contd)
private Singleton() {} private Singleton() {}

private static Singleton uniqueInstance; private static Singleton uniqueInstance;

public static Singleton getInstance() public static Singleton getInstance()


{ {
if(uniqueInstance == null) { if(uniqueInstance == null) {
uniqueInstance = new Singleton(); uniqueInstance = new Singleton();
} }
return uniqueInstance; return uniqueInstance;
} }
... ...

Thread 1 Thread 2

17
Option #1: Simple Locking 1
public class Singleton
{
private Singleton() {}
private static Singleton uniqueInstance;
public static synchronized Singleton getInstance()
{
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}

18
Contd
public class Singleton
{
private Singleton() {}
private static Singleton uniqueInstance;
public static Singleton getInstance()
{
if(uniqueInstance == null) {
synchronized(Singleton.class) {
if (uniqueInstance == null)
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
} 19
Option #2: DCL (Double-Checked Locking)
public class Singleton
{
private Singleton() {}
private volatile static Singleton uniqueInstance;
public static Singleton getInstance()
{
if (uniqueInstance == null) { //single checked
synchronized(Singleton.class) {
if(uniqueInstance == null) //double checked
uniqueInstance = new Singleton();
}
}
return uniqueInstance;
}
}

20
volatile Variable

• Used to mark a Java variable as


“being stored in main memory”

• Every read/write of a volatile variable


is directly from/to main memory, not
from/to the cache

• Guarantees visibility of changes to


variables across threads

21
Option #3: “Eager” Initialization
public class Singleton
{
private Singleton() {}

private static Singleton uniqueInstance = new Singleton()

public static Singleton getInstance()


Runtime guarantees
{ that this is thread-safe
return uniqueInstance;
}
} 1. Instance is created the first time any
member of the class is referenced.
2. Good to use if the application always
creates; and if little overhead to create.

22
Self-Test (1)
• 초콜릿 공장
– commit message : “Project13”
– 당일 밤 12시까지 제출
• 초콜릿 공장의 최신형 초콜릿 보일러를 제어하기 위한 클래스가 있다.
해당 클래스는 원활한 초콜릿 보일러 가동을 위해 세심한 주의를 기울
여 작성되었다.
• 그럼에도 해당 클래스의 인스턴스가 2개 이상 생성되는 순간 여러 가지
문제가 발생할 수 있다.
• 다음 클래스를 인스턴스를 2개 이상 생성할 수 없도록 Singleton 클래
스로 변경해야 한다.

23
Self-Test (1) (Contd)

24
Self-Test (1) (Contd)

25
Self-Test (1) (Contd)

• Singleton 패턴이 적용되지 않은 코드는 한 객체가 이미 수행한 동작을


다른 객체가 그대로 수행하는 것을 볼 수 있다.
• Singleton 패턴이 적용된 코드는 한 객체가 이미 수행한 동작을 다른
객체가 수행하지 않는 것을 볼 수 있다.

26
Self-Test (2)
• Self-Test (1)에서 작성했던 Singleton 디자인 패턴을 적용한 초콜릿
보일러가 멀티쓰레딩 최적화 적용 시 문제가 발생할 수 있음을 확인했
다.
• 멀티쓰레딩 최적화를 적용해도 문제가 발생하지 않도록 초콜릿 보일러
클래스를 다음과 같은 DCL 방식으로 수정할 것

27
Prototype (범위 X)
• The Prototype Pattern allows you to make new instances by
copying existing instances

• A key aspect of this pattern is that the client code can make new
instances without knowing which specific class is being
instantiated.

• In Java this typically means using the clone() method, or de-


serialization when you need deep copies

28
Prototype benefits
• Hides the complexities of making new instances from the client

• Provides the option for the client to generate objects whose type
is not known

• In some circumstances, copying an object can be more efficient


than creating a new object

29
Prototype Uses and Drawbacks
• Prototype should be considered when a system must create new
objects of many types in a complex class hierarchy

• A drawback to using the Prototype is that making a copy of an


object can sometimes be complicated

30
Prototype (contd)

31
Clone

32
Factory Method (범위 X)

33
Factory Method (contd)

34
Factory Method (contd)

35
Factory Method (contd)

36
Factory Method (contd)

37

You might also like