设计模式笔记及Swift上的实现之五『SINGLETON(单例)』

单例是书中最后一个创建型模式。单例这个设计模式相信大家再熟悉不过了。但单例也是最容易被滥用的设计模式。我们可以通过重新理解单例的意图,来帮助我们在后续的开发中决定是否该使用这中模式。

意图

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

动机

对一些类来说,只有一个实例是很重要的。例如我们 iOS 开发中经常做的提示框。我们希望这种提示框出现一个之后,在消失之前不会出现第二个,这时单例是最好的选择。

适用性

  • 类只能有一个实例,而客户可以从一个已知的访问点访问它。
  • 这个唯一的实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能适用一个扩展的实例。

结构

参与者

  • Singleton

—— 定义一个 Instance 操作,允许客户访问它的唯一实例。
—— 可能负责创建它自己的唯一方法。

协作

  • 客户只能通过 Singleton 的 Instance 操作访问一个 Singleton 的实例。

效果

  • 对唯一实例的受控访问
  • 缩小名空间(避免存储唯一实例的全局变量污染名空间)
  • 允许对操作和表达的精化
  • 允许可变数目的实例(允许一个 Singleton 类有多个实例)
  • 比类操作更灵活

实现

  • 保证一个唯一的实例
  • 创建 Singleton 的子类

代码示例

Swift 上单例的实现,其实很简单。我们只需要使用 static 就可以创建一个全局的实例了,不行像 OC 那样使用 dispatch_once 来保证线程安全。
我们使用 fileprivate 来修饰我们的构造函数。这确保没有其他创建实例的手段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct MazeFactory {
static let interface = MazeFactory()
fileprivate init() {
}
func makeMaze() {
print("This is Maze.")
}
}
MazeFactory.interface.makeMaze()

打印结果

1
This is Maze.

总结

单例模式使用起来很简单,而单例也可以配合很多模式一起使用。

附:Playground 代码

欢迎讨论、批评、指错。