阅读 184

ios-状态模式

  • 状态模式使用场景

  • 一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。

  • 代码中包含大量与对象状态有关的条件语句:一个操作中含有庞大的多分支的条件(if else(或switch case)语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常 , 有多个操作包含这一相同的条件结构。 State模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。

  • 一台电视机

    • 打开状态
      • 向上切换频道
      • 向下切换频道
      • 向上调节音量
      • 向下调节音量
    • 关闭状态
      • 无法向上切换频道
      • 无法向下切换频道
      • 无法向上调节音量
      • 无法向下调节音量
  • 定义一个协议赋予四个功能

import Foundation

//角色一: 抽象的状态
protocol StateProtocol {
    
    func channelUp()
    
    func channelDown()
    
    func volumeUp()
    
    func volumeDown()
    
}
复制代码
  • 定义开机状态实现4个功能
import Foundation

//角色二:具体的状态
class OnState: StateProtocol {
    
    func channelUp() {
        print("向上切换频道")
    }
    
    func channelDown() {
        print("向下切换频道")
    }
    
    func volumeUp() {
        print("音量调高")
    }
    
    func volumeDown() {
        print("音量调低")
    }
}

复制代码
  • 定义关机状态实现4个功能
import Foundation

//角色二:具体的状态
class OffState: StateProtocol {
    func channelUp() {
        print("关机状态,不能切换频道")
    }
    
    func channelDown() {
        print("关机状态,不能切换频道")
    }
    
    func volumeUp() {
        print("关机状态,不能调整音量")
    }
    
    func volumeDown() {
        print("关机状态,不能调整音量")
    }
}

复制代码
  • 定义一台电视机创建时默认状态为关机状态
import Foundation

//角色三:状态上下文
class Context {
    
    var state: StateProtocol
    
    init() {
        self.state = OffState()
    }
    
    func channelUp() {
        self.state.channelUp()
    }
    
    func channelDown() {
        self.state.channelDown()
    }
    
    func volumeUp() {
        self.state.volumeUp()
    }
    
    func volumeDown() {
        self.state.volumeDown()
    }
}

复制代码
  • 调用
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        let context = Context()
        context.channelUp()
        
        
        context.state = OnState()  //切换状态
        context.channelUp()
        
    }
}
复制代码
  • 结果

image.png

image.png

  • 功能就能不需要很复杂的if-else来判断状态再来调用方法了
  • 切换不同状态后来实现对应的方法
文章分类
iOS
文章标签