单例是书中最后一个创建型模式。单例这个设计模式相信大家再熟悉不过了。但单例也是最容易被滥用的设计模式。我们可以通过重新理解单例的意图,来帮助我们在后续的开发中决定是否该使用这中模式。
意图
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
动机
对一些类来说,只有一个实例是很重要的。例如我们 iOS 开发中经常做的提示框。我们希望这种提示框出现一个之后,在消失之前不会出现第二个,这时单例是最好的选择。
适用性
- 类只能有一个实例,而客户可以从一个已知的访问点访问它。
- 这个唯一的实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能适用一个扩展的实例。
结构
参与者
- Singleton
—— 定义一个 Instance 操作,允许客户访问它的唯一实例。
—— 可能负责创建它自己的唯一方法。
协作
- 客户只能通过 Singleton 的 Instance 操作访问一个 Singleton 的实例。
效果
- 对唯一实例的受控访问
- 缩小名空间(避免存储唯一实例的全局变量污染名空间)
- 允许对操作和表达的精化
- 允许可变数目的实例(允许一个 Singleton 类有多个实例)
- 比类操作更灵活
实现
- 保证一个唯一的实例
- 创建 Singleton 的子类
代码示例
Swift 上单例的实现,其实很简单。我们只需要使用 static
就可以创建一个全局的实例了,不行像 OC 那样使用 dispatch_once
来保证线程安全。
我们使用 fileprivate
来修饰我们的构造函数。这确保没有其他创建实例的手段。
struct MazeFactory {
static let interface = MazeFactory()
fileprivate init() {
}
func makeMaze() {
print("This is Maze.")
}
}
MazeFactory.interface.makeMaze()
打印结果
This is Maze.
总结
单例模式使用起来很简单,而单例也可以配合很多模式一起使用。
欢迎讨论、批评、指错。