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學習-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設計模式之抽象工廠
- iOS設計模式之工廠方法