设计模式之 State 状态模式:Swift 实现

State Mode: 状态模式

对象收到信息,对应状态发生变化,这是软件中常见的一种运作方式。对象我们将状态作为一个独立的对象,主对象的不同状态切换只需要切换状态对象即可。

The state mode enable the class to change its behavior when its inner state changed. The StateContext only do the switch work, and the detail work is done by State object. The context manage the statements in a high level, it can switch some different state when we need. The context inject a reference to the concrete state object to enable the state to delegate the detail work.

状态模式中,当对象的状态改变时,对象的行为随着改变。状态上下文类只执行状态切换工作,具体的工作细节交给状态对象去执行。上下文对象在一个较高的层次管理着自身的状态,它可以在我们有需要的时候切换不同的状态。上下文对象注入了一个自己的引用给状态对象,使得状态对象可以代理在切换状态时候的细节工作。

状态模式在线程状态切换中的应用

// Abstract state
class State {
    var context: Context?
    var name: String = ""
    init(context: Context?) {
        self.context = context
    }
    
}

// Concrete state
class NewState: State {
    override init(context: Context?) {
        super.init(context: context)
        self.name = "New"
    }
    func start() {
        print("Call start")
        if self.name == "New" {
            context?.setState(state: RunnableState(context: context))
        } else {
            print("Can't go to runnable")
        }
    }
}

// Concrete state
class RunnableState: State {
    override init(context: Context?) {
        super.init(context: context)
        self.name = "Runnable"
    }
    func getCpu() {
        if self.name == "Runnable" {
            context?.setState(state: RunningState(context: context))
        } else {
            print("Can't go to running")
        }
    }
}

// Concrete state
class RunningState: State {
    override init(context: Context?) {
        super.init(context: context)
        self.name = "Running"
    }
    
    func suspend() {
        if self.name == "Running" {
            context?.setState(state: BlockState(context: context))
        }
    }
    
    func stop() {
        if self.name == "Running" {
            context?.setState(state: DeadState(context: context))
        }
    }
    
}

// Concrete state
class  BlockState: State {
    override init(context: Context?) {
        super.init(context: context)
        self.name = "Block"
    }
    
    func resume() {
        if name == "Block" {
            context?.setState(state: RunnableState(context: context))
        }
    }
}

// Concrete state
class DeadState: State {
    override init(context: Context?) {
        super.init(context: context)
        self.name = "Dead"
    }
    
    
}

// Thread Context
class Context {
    private var state: State?
    init() {
        self.state = NewState(context: self)
    }
    
    func setState(state: State) {
        self.state = state
    }
    
    func getState() -> State? {
        return self.state
    }
    
    func start() {
        if let s = self.state as? NewState {
            s.start()
        }
    }
    
    func suspend() {
        if let s = self.state as?  RunningState {
            s.suspend()
        }
    }
    
    
    func resume() {
        if let s = self.state as? BlockState {
            s.resume()
        }
    }
    
    func getCpu() {
        if let s = self.state as? RunnableState {
            s.getCpu()  // It will switch to the running state.
        }
    }
    func  stop() {
        if let s = self.state as? RunningState {
            s.stop()
        }
    }
    
    
}

let context = Context()
context.start()   // It will be runnable then.
context.getCpu()  // It will be running then.
context.suspend() // It will be blocked then.
context.resume()  // It will be runnable then.
context.getCpu()  // It will be running then.
context.stop()    // It will be dead then.

以上代码中,不同状态类都遵守 State 协议,context 对象具备一个 state,调用 context 的方法可以使得 context 在不同状态之间切换。State 协议持有 Context 类型引用,具体状态对象可以调用 context 对象进行具体的操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值