iOS设计模式之状态模式
持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情
本文主要介绍iOS设计模中的状态模式,状态模式顾名思义就是通过改变对象的状态从而改变对象的行为。
1. 什么是状态模式
我们通过定义对象的状态从而改变对象的行为,并且你还可将该方法应用在对象上。 假如你有一个 文档
Document类。 文档可能会处于 草稿
Draft 、 审阅中
Moderation和 已发布
Published三种状态中的一种。 文档的 publish
发布方法在不同状态下的行为略有不同:
- 处于
草稿
状态时, 它会将文档转移到审阅中状态。 - 处于
审阅中
状态时, 如果当前用户是管理员, 它会公开发布文档。 - 处于
已发布
状态时, 它不会进行任何操作。
状态机通常由众多条件运算符 ( if
或 switch
) 实现, 可根据对象的当前状态选择相应的行为。 “状态” 通常只是对象中的一组成员变量值。 即使你之前从未听说过有限状态机, 你也很可能已经实现过状态模式。
智能手机的按键和开关会根据设备当前状态完成不同行为
:
- 当手机处于解锁状态时, 按下按键将执行各种功能。
- 当手机处于锁定状态时, 按下任何按键都将解锁屏幕。
- 当手机电量不足时, 按下任何按键都将显示充电页面。 状态模式建议为对象的所有可能状态新建一个类, 然后将所有状态的对应行为抽取到这些类中。
原始对象被称为上下文(context)
, 它并不会自行实现所有行为, 而是会保存一个指向表示当前状态的状态对象的引用, 且将所有与状态相关的工作委派给该对象。
状态是一种行为设计模式, 让你能在一个对象的内部状态变化时改变其行为。
2. 什么时候使用状态模式
以下这些情况可以考虑使用状态模式
- [ ] 如果对象需要根据自身当前状态进行不同行为
, 同时状态的数量非常多且与状态相关的代码会频繁变更的话, 可使用状态模式。
- [ ] 如果某个类需要根据成员变量的当前值改变自身行为
, 从而需要使用大量的条件语句
时, 可使用该模式。
- [ ] 当相似状态和基于条件的状态机转换中存在许多重复代码
时, 可使用状态模式。
3. 代码展示
```Swift import XCTest
/// The Context defines the interface of interest to clients. It also maintains /// a reference to an instance of a State subclass, which represents the current /// state of the Context. class Context {
/// A reference to the current state of the Context.
private var state: State
init(_ state: State) {
self.state = state
transitionTo(state: state)
}
/// The Context allows changing the State object at runtime.
func transitionTo(state: State) {
print("Context: Transition to " + String(describing: state))
self.state = state
self.state.update(context: self)
}
/// The Context delegates part of its behavior to the current State object.
func request1() {
state.handle1()
}
func request2() {
state.handle2()
}
}
/// The base State class declares methods that all Concrete State should /// implement and also provides a backreference to the Context object, /// associated with the State. This backreference can be used by States to /// transition the Context to another State. protocol State: class {
func update(context: Context)
func handle1()
func handle2()
}
class BaseState: State {
private(set) weak var context: Context?
func update(context: Context) {
self.context = context
}
func handle1() {}
func handle2() {}
}
/// Concrete States implement various behaviors, associated with a state of the /// Context. class ConcreteStateA: BaseState {
override func handle1() {
print("ConcreteStateA handles request1.")
print("ConcreteStateA wants to change the state of the context.\n")
context?.transitionTo(state: ConcreteStateB())
}
override func handle2() {
print("ConcreteStateA handles request2.\n")
}
}
class ConcreteStateB: BaseState {
override func handle1() {
print("ConcreteStateB handles request1.\n")
}
override func handle2() {
print("ConcreteStateB handles request2.")
print("ConcreteStateB wants to change the state of the context.\n")
context?.transitionTo(state: ConcreteStateA())
}
}
/// Let's see how it all works together. class StateConceptual: XCTestCase {
func test() {
let context = Context(ConcreteStateA())
context.request1()
context.request2()
}
}
执行结果
Swift
Context: Transition to StateConceptual.ConcreteStateA
ConcreteStateA handles request1.
ConcreteStateA wants to change the state of the context.
Context: Transition to StateConceptual.ConcreteStateB ConcreteStateB handles request2. ConcreteStateB wants to change the state of the context.
Context: Transition to StateConceptual.ConcreteStateA ```
4. 小结
我们对象存在大量状态
的时候,当前状态完成不同行为
。或者存在很多条件判断
对应不同状态,或者是相似状态和基于条件的状态机转换
。都可以采用状态模式。比如我们客户端用户有很多状态,我们获取用户不同状态从而跳转不同页面或者一些操作。
- Flutter Module 添加到iOS项目
- Flutter学习-GetX-05 生命周期
- Flutter学习-GetX-04 依赖注入
- ios Xib 使用技巧
- 底层原理-26-Block(上)
- Flutter学习之刷新组件-pull_to_refresh
- Flutter学习之原生通信BasicMessageChannel
- flutter学习之嵌入原生View - android
- iOS设计模式之状态模式
- Flutter学习之嵌入原生iOSView
- flutter学习之状态管理Provider
- iOS设计模式之代理模式
- iOS设计模式之享元模式
- iOS设计模式之访问者
- iOS设计模式之迭代器
- iOS设计模式之组合模式
- iOS设计模式之单例模式
- iOS设计模式之生成器模式
- 底层原理-12-dyld动态链接器加载流程
- iOS设计模式之抽象工厂