Bài giảng Lập trình hướng đối tượng - Tuần 9: Mẫu thiết kế Singleton - Nguyễn Khắc Huy

Mẫu thiết kế Singleton  
Nguyễn Khắc Huy  
BMCNPM – ĐHKHTN TPHCM  
10/2018  
1
Thành phần tĩnh  
□ Member variables  
class PhanSo {  
int tuSo;  
int mauSo;  
public:  
PhanSo(int tu, int mau)  
}
PhanSo::PhanSo(int tu, int mau) {  
this->tuSo = tu;  
this->mauSo = mau;  
}
void main() {  
PhanSo a(1,2); // what do have have?  
PhanSo b(3,5); // what do have have?  
2}  
Thành phần tĩnh  
□ Static variable  
class PhanSo {  
int tuSo;  
void main() {  
PhanSo a(1, 2); // ??  
PhanSo b(3, 5); // ??  
int mauSo;  
int count = 0;  
public:  
}
PhanSo(int tu, int mau);  
}
PhanSo::PhanSo(int tu, int mau) {  
this->tuSo = tu;  
this->mauSo = mau;  
count++;  
}
3
Thành phần tĩnh  
□ Static variable  
class PhanSo {  
PhanSo::count = 0;  
void main() {  
int tuSo;  
int mauSo;  
PhanSo a(1, 2); // ??  
static int count;  
PhanSo b(3, 5); // ??  
}
public:  
}
PhanSo(int tu, int mau, int count);  
PhanSo::PhanSo(int tu, int mau) {  
this->tuSo = tu;  
this->mauSo = mau;  
count++;  
}
4
Mẫu thiết kế là gì?  
□ Design pattern  
5
Sometimes it is important to have only  
one instance of a class  
□ One printer spooler (though many printers)  
□ One file system  
□ One window manager  
The challenge:  
o Ensure that a certain class has only one  
instance  
o Provide global access to it  
6
Question:  
How can you prevent any  
instances of a class from  
being created?  
7
Question:  
How can you prevent any  
instances of a class from  
being created?  
1. Don’t write it…  
2. ?  
8
Moving towards a solution…  
1. Restrict the ability to construct  
more than one instance of a  
Singleton class  
2. Make the class responsible for  
keeping track of its one and onl
instance  
3. Provide a global (static) access  
method  
9
Solution 1: Eager Instantiation  
using static initialization  
public class Singleton {  
private static Singleton uniqueInstance = new Singleton();  
// private constructor cannot be called;  
// no instances can be created.  
private Singleton() {  
}
// return the same instance to all callers of this method  
public static Singleton getInstance() {  
return uniqueInstance;  
}
}
10  
Important Concepts  
1. Why is the constructor private?  
Any client that tries to instantiate the Singleton class  
directly will get an error at compile time.  
ü This ensures that nobody other than the Singleton class and  
instantiate the object of this class.  
2. How can you access the single instance of the  
Singleton class?  
getInstance() is a static method. We can use the  
class name to reference the method.  
ü Singleton.getInstance()  
ü This is how we can provide global access to the single instance  
of the Singleton class.  
11  
Eager instantiation has pros and  
cons  
□ Static initialization is guaranteed to be thread-safe  
□ Global/static objects are created whether they are used  
or not, as soon as the application is loaded.  
□ Creating a Singleton object can be resource intensive  
and you may not want to create it until you need it.  
□ We might not have all the information to create an  
object at static initialization time.  
o Example: the kind of file/database/resource that you are  
connecting to is usually not known at startup  
12  
Solution 2: A Lazy Singleton  
public class Singleton {  
private static Singleton uniqueInstance = null;  
static variable to hold the single instance of the class.  
private Singleton() {  
// construction code goes here.  
}
Only this class can instantiate itself.  
public static Singleton getInstance() {  
if (uniqueInstance == null) {  
uniqueInstance = new Singleton();  
Provides a way to instantiate the class and also provides global access to it.  
}
return uniqueInstance;  
}
}
13  
Lazy initialization  
The Singletonclass on the previous slide  
uses lazy initialization  
oThe uniqueInstanceis not created and  
stored in the getInstance()method until it  
is first accessed.  
public class Singleton {  
private static Singleton uniqueInstance = null;  
. . .  
public static Singleton getInstance() {  
if (uniqueInstance == null) {  
uniqueInstance = new Singleton();  
}
return uniqueInstance;  
}
. . .  
}
14  
Lazy Singletons can have  
issues with Multithreading  
Thread1  
Thread2  
Value of  
uniqueInstance  
Singleton.getInstance()  
null  
null  
Singleton.getInstance()  
if (uniqueInstance == null){  
null  
if (uniqueInstance == null) {  
null  
uniqueInstance = new  
Singleton()  
Object 1  
return uniqueInstance;  
Object 1  
Object 2  
uniqueInstance = new  
Singleton()  
return uniqueInstance;  
Object 2  
15  
Another alternative for lazy initialization  
public class Singleton {  
private static volatile Singleton uniqueInstance =  
null;  
private Singleton() {  
// construction code goes here.  
}
public static synchronized Singleton getInstance(){  
if (uniqueInstance == null) {  
uniqueInstance = new Singleton();  
}
return uniqueInstance;  
}
}
Using the Java keyword synchronized forces every thread to wait  
its turn before it can enter the method. This prevents two threads  
from entering the method at the same time.  
16  
The Cost of Synchronization  
□ Synchronization is expensive. Synchronized methods  
can take 100 times longer to execute than  
unsynchronized methods  
o This can affect performance of your program if getInstance()  
is called frequently  
□ Synchronization is relevant only the first time though the  
method, so why force repeated usage?  
o Once we have set the uniqueInstance to an appropriate  
instance, then there is no need to further synchronize the  
method.  
17  
Lazy Initialization Solution 2:  
Double Checked Locking  
public class Singleton {  
private volatile static Singleton uniqueInstance = null;  
volatile ensures that the JVM always has an up-to-date value  
of uniqueInstance  
private Singleton() {  
// construction code goes here.  
}
Enter a synchronized  
block only when there  
public static Singleton getInstance() {is no instance.  
if (uniqueInstance == null) {  
synchronized (Singleton.class) {  
if (uniqueInstance == null) {  
uniqueInstance = new Singleton();  
}
}
We need to  
return uniqueInstance;  
synchronize only the  
first time through.  
}
}
18  
Double-checked locking solves  
multithreading problems  
Thread1  
Thread2  
Value of  
uniqueInstance  
Singleton.getInstance()  
null  
null  
Singleton.getInstance()  
if (uniqueInstance == null)  
null  
if (uniqueInstance == null)  
null  
synchronized (Singleton.class) {  
if (uniqueInstance == null)  
uniqueInstance = new  
Singleton()  
Object 1  
}
return uniqueInstance;  
Object 1  
Object 1  
synchronized (Singleton.class) {  
If (uniqueInstance == null)  
// will evaluate to false!!!  
return uniqueInstance;  
Object 1  
The Cost of Double-checked  
locking  
Code is more complex  
o Additional complexity = decreased  
maintainability  
o Is it worth it?  
20  
Tải về để xem bản đầy đủ
pdf 24 trang myanh 25660 Free
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Lập trình hướng đối tượng - Tuần 9: Mẫu thiết kế Singleton - Nguyễn Khắc Huy", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

File đính kèm:

  • pdfbai_giang_lap_trinh_huong_doi_tuong_tuan_9_mau_thiet_ke_sing.pdf