Skip to content

Commit ac82cba

Browse files
committed
Singleton
1 parent 43776d2 commit ac82cba

1 file changed

Lines changed: 45 additions & 0 deletions

File tree

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
## 单例模式
2+
3+
### 定义
4+
5+
确保一个类只有一个实例,并为其提供一个全局访问入口
6+
7+
### 场景
8+
9+
1. 程序中的某个类对于所有客户端只有一个可用的实例
10+
2. 你需要更加严格地控制全局变量
11+
12+
### 案例
13+
14+
[单例](./Assets/DesignPatternsRevisited/SingletonPattern)
15+
16+
### 实现方式
17+
18+
1. 在类中添加一个私有静态成员变量用于保存单例实例。
19+
2. 声明一个公有静态构建方法用于获取单例实例。
20+
3. 在静态方法中实现"延迟初始化"。 该方法会在首次被调用时创建一个新对象, 并将其存储在静态成员变量中。 此后该方法每次被调用时都返回该实例。
21+
4. 将类的构造函数设为私有。 类的静态方法仍能调用构造函数, 但是其他对象不能调用。
22+
5. 检查客户端代码, 将对单例的构造函数的调用替换为对其静态构建方法的调用。
23+
24+
### 优缺点
25+
26+
**优点**
27+
28+
- 你可以保证一个类只有一个实例。
29+
- 你获得了一个指向该实例的全局访问节点。
30+
- 仅在首次请求单例对象时对其进行初始化。
31+
32+
**缺点**
33+
34+
- 违反了_单一职责原则_。 该模式同时解决了两个问题*(在一个方法中进行了创建类和提供类对象的操作)*
35+
- 单例模式可能掩盖不良设计, 比如程序各组件之间相互了解过多等。
36+
- 该模式在多线程环境下需要进行特殊处理, 避免多个线程多次创建单例对象。
37+
- 单例的客户端代码单元测试可能会比较困难, 因为许多测试框架以基于继承的方式创建模拟对象。 由于单例类的构造函数是私有的, 而且绝大部分语言无法重写静态方法, 所以你需要想出仔细考虑模拟单例的方法。 要么干脆不编写测试代码, 或者不使用单例模式。
38+
39+
### 与其他设计模式的关系
40+
41+
- **外观模式** *(GOF)*类通常可以转换为单例模式类, 因为在大部分情况下一个**外观对象** *(GOF)*就足够了。
42+
- 如果你能将对象的所有共享状态简化为一个享元对象, 那么**享元模式**就和单例类似了。 但这两个模式有两个根本性的不同。
43+
1. 只会有一个单例实体, 但是*享元*类可以有多个实体, 各实体的内在状态也可以不同。
44+
2. *单例*对象可以是可变的。 享元对象是不可变的。
45+
- **抽象工厂模式** *(GOF)***生成器模式** *(GOF)***原型模式**都可以用单例来实现。

0 commit comments

Comments
 (0)