聊聊Swift中的设计模式---行为型(观察者模式)
theme: cyanosis
持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第28天,点击查看活动详情
前言
在面向对象的开发过程中,其实咱们或多或少的都接触过一些设计模式,可能知道或不知道其对应的名称,也不知道其具体使用场景,今天咱们就来说说几种常见的设计模式,帮助你们在开发过程中,更加得心应手。
正文
观察者模式
观察者模式是一种订阅模式, 可在被观察的对象事件发生时通知多个 “观察” 该对象的其他对象。
这个就像iOS中的observe,当被观察的对象变了,观察者就会收到通知,做出响应改变。
在现实生活中,就像刚出来的PS+订阅服务,我订阅了索尼的PS+,如果PS+游戏库中的游戏更新了,我就会收到可以下载的通知。不用重新在去搜索下载了。(ps,索尼罪大恶极)索尼就负责维护咱们这些订阅者列表,当有人不想订阅了,索尼就将这个人从订阅列表中移除。那这个人就不会收到订阅信息的更新提示了。
接下来,咱们再用一个例子说明一下。
首先,定义一个主题(Subject
),里面定义一个包含观察者(Observer
)的数组,然后分别实现将观察者结合(attach(observer: Observer)
)、分离(deattach(observer: Observer)
)和通知(notify()
)的方法
当state
改变时 就会调用notify()
方法
notify()
方法就是将observes
数组中,所有的观察者对象都执行update()
方法
``` class Subject {
private var observes: [Observer] = []
private var _state: Int = 0
var state: Int {
set {
_state = newValue
notify()
}
get {
return _state
}
}
func attach(observer: Observer) {
observes.append(observer)
}
func deattach(observer: Observer) {
guard let index = observes.firstIndex(where: {$0.id == observer.id}) else {return}
observes.remove(at: index)
}
func notify() {
observes.forEach { (obs) in
obs.update()
}
}
}
```
定义一个观察者的协议
```
protocol Observer { var id : String {get set} var subject: Subject { get set } func update() }
```
定义三个观察者的类(BinaryObserver
、OctalObserver
和HexaObserver
)都遵守观察者协议(Observer
)并实现了update()
的方法
``` class BinaryObserver: Observer { var subject: Subject var id: String
init(id: String, subject: Subject) {
self.id = id
self.subject = subject
self.subject.attach(observer: self)
}
func update() {
let val = String(subject.state, radix: 2, uppercase: true)
print("二进制: (val)")
}
}
class OctalObserver: Observer { var subject: Subject var id: String
init(id: String, subject: Subject) {
self.id = id
self.subject = subject
self.subject.attach(observer: self)
}
func update() {
let val = String(subject.state, radix: 8, uppercase: true)
print("八进制: (val)")
}
}
class HexaObserver: Observer { var subject: Subject var id: String
init(id: String, subject: Subject) {
self.id = id
self.subject = subject
self.subject.attach(observer: self)
}
func update() {
let val = String(subject.state, radix: 16, uppercase: true)
print("十六进制: (val)")
}
}
```
接下来,咱们来看看实现。
``` let subject = Subject()
HexaObserver(id: "hexa", subject: subject) OctalObserver(id: "octal", subject: subject) BinaryObserver(id: "binary", subject: subject)
print("输入5:") subject.state = 5
print("\n输入10") subject.state = 10 ```
输出结果:
``` 输入5: 十六进制: 5 八进制: 5 二进制: 101
输入10 十六进制: A 八进制: 12 二进制: 1010 ```
可以发现,每次改变subject.state
的值时,观察者都会收到改变的消息,并执行函数。
结语
观察者模式适合应用场景
- 当一个对象状态的改变需要改变其他对象, 或实际对象是事先未知的或动态变化的时, 可使用观察者模式。
- 当应用中的一些对象必须观察其他对象时, 可使用该模式。 但仅能在有限时间内或特定情况下使用。
观察者模式优缺点
优点
-
开闭原则。 你无需修改发布者代码就能引入新的订阅者类 (如果是发布者接口则可轻松引入发布者类)。
-
你可以在运行时建立对象之间的联系。
缺点
- 订阅者的通知顺序是随机的。
扩展阅读 下面还有其他模式
- 道阻且长,如何?行路难
- 聊聊Swift中的设计模式---创建型(工厂模式)
- 聊聊Swift中的设计模式---行为型(策略模式)
- 聊聊Swift中的设计模式---行为型(观察者模式)
- 聊聊Swift中的设计模式---行为型(中介者模式)(26)
- 聊聊Swift中的设计模式---行为型(命令模式)(25)
- 聊聊Swift中的设计模式---结构型(享元模式)
- 聊聊Swift中的设计模式---结构型(外观模式)
- iOS控件介绍---UIStackView 一个类似于flexbox的布局控件
- 作为iOSer,如何让自己的项目更有温度?(中)
- 作为iOSer,如何让自己的项目更有温度?(上)
- 使用RXSwift撸一个MVVM架构的Tableview
- 使用RXSwift撸一个倒计时按钮
- 如何将 opencv_contrib 中的第三方库 打包到 opencv 中,并生成iOS用的framework
- 字符数组和字符串基本掌握
- 【第2章】matlab程序设计基础
- 手写Vue2.0源码-渲染更新原理
- nginx
- 手动实现vue2.0的双向数据绑定原理
- STM32延时函数的四种方法