单例模式

概述

保证一个类、只有一个实例存在,同时提供能对该实例加以访问的全局访问方法。

三个要点:
一是某个类只能有一个实例;
二是它必须自行创建这个实例;
三是它必须自行向整个系统提供这个实例。

模式中的角色和职责

Singleton(单例):在单例类的内部实现只生成一个实例,同时它提供一个静态的getInstance()工厂方法,让客户可以访问它的唯一实例;为了防止在外部对其实例化,将其构造函数设计为私有;在单例类内部定义了一个Singleton类型的静态对象,作为外部共享的唯一实例。

单例模式的使用步骤:
a)   构造函数私有化。
b)   提供一个全局的静态方法(全局访问点)来获取单例对象。
c)   在类中定义一个静态指针,指向本类的变量的静态变量指针  。

单例模式的案例

 1 #include  <iostream> 
 2 using  namespace  std; 
 3 /*  
 4    懒汉模式 
 5 */ 
 6 class  Singelton 
 7 { 
 8 public: 
 9     /* 
10        对外提供一个全局的静态⽅方法 
11      */ 
12     static  Singelton  *  getInstance()  { 
13         /* 
14            懒汉式:  在调⽤用全局静态⽅方法,获取单例的时候, 
15            再进⾏行创建。懒汉式的单例创建在程序的执⾏行中进⾏行。 
16          */ 
17         if  (instance  ==  NULL)  { 
18             instance  =  new  Singelton; 
19         } 
20         m_count++; 
21         return  instance; 
22     } 
23     int  getCount()  { 
24         return  m_count; 
25     } 
26 private: 
27     /* 
28        构造函数私有化 
29      */ 
30     Singelton()  { 
31         instance  =  NULL; 
32         m_count  =  0; 
33         cout  <<  "构造函数  singelton()  执⾏行"  <<  endl; 
34     } 
35     /* 
36        在类中定义一个静态指针,指向本类的变量的静态变量指针 
37      */ 
38     static  Singelton  *instance; 
39     static  int  m_count; 
40 }; 
41 /* 
42    对静态变量的初始化,要放在类的外部, 
43    即,放在全局位置上。 
44  */ 
45 Singelton  *  Singelton::instance  =  NULL; 
46 int  Singelton::m_count  =  0; 
47 /*  
48    饿汉模式 
49 */ 
50 class  Singelton2  { 
51 public: 
52     static  Singelton2*  getInstance()  { 
53         m_count++; 
54         return  instance; 
55     } 
56     int  getCount()  { 
57         return  m_count; 
58     } 
59 private: 
60     Singelton2()  { 
61         instance  =  NULL; 
62         m_count  =  0; 
63     } 
64     static  Singelton2  *  instance; 
65     static  int  m_count; 
66 }; 
67 /* 
68    饿汉式的不是在全局静态⽅方法中创建, 
69    ⽽而是不管你创不创建实例,我在声明的 
70    时候就创建出来, 
71    饿汉式的单例,是在编译的时候就已经创建好了。 
72  */ 
73 Singelton2  *  Singelton2::instance  =  new  Singelton2; 
74 int  Singelton2::m_count  =  0; 
75 int  main(void) 
76 { 
77     Singelton  *  singer  =  Singelton::getInstance(); 
78     cout  <<  singer-­‐>getCount()  <<  endl; 
79     Singelton  *  singer2  =  Singelton::getInstance(); 
80     cout  <<  singer2-­‐>getCount()  <<  endl; 
81     if  (singer  ==  singer2)  { 
82         cout  <<  "二者是同⼀一个实例"  <<  endl; 
83     } 
84     else  { 
85         cout  <<  "二者不是同⼀一个实例"  <<  endl; 
86     } 
87     cout  <<  "-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐   以下  是  饿汉式  -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐"  <<  endl; 
88     Singelton2  *  singer3  =  Singelton2::getInstance(); 
89     cout  <<  singer3-­‐>getCount()  <<  endl; 
90     Singelton2  *  singer4  =  Singelton2::getInstance(); 
91     cout  <<  singer4-­‐>getCount()  <<  endl; 
92     if  (singer3  ==  singer4)  { 
93         cout  <<  "二者是同⼀一个实例"  <<  endl; 
94     } 
95     else  { 
96         cout  <<  "二者不是同⼀一个实例"  <<  endl; 
97     } 
98     return  0; 
99 } 

单例模式的优缺点

优点:
(1) 单例模式提供了对唯一实例的受控访问。
(2) 节约系统资源。由于在系统内存中只存在一个对象。
缺点:
(1) 扩展略难。单例模式中没有抽象层。
(2) 单例类的职责过重。

适用场景 

(1)  系统只需要一个实例对象,如系统要求提供一个唯一的序列号生成器或资源管理器,或者需要考虑资源消耗太大而只允许创建一个对象。 

(2)  客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。

 

一个网站:https://refactoringguru.cn/design-patterns/singleton

posted @ 2019-05-21 00:07  鲸小鱼-  阅读(155)  评论(0编辑  收藏  举报