继续创作,加速成长!这是我参与「日新方案 6 月更文挑战」的第25天,点击检查活动详情

本文首要介绍iOS设计模中的状况形式,状况形式望文生义就是经过改动目标的状况然后改动目标的行为。

1. 什么是状况形式

咱们经过界说目标的状况然后改动目标的行为,而且你还可将该办法应用在目标上。假如你有一个文档Document类。文档可能会处于草稿Draft、审理中Moderation和已发布Published三种状况中的一种。文档的publish发布办法在不同状况下的行为略有不同:

  • 处于草稿状况时,它会将文档转移到审理中状况。
  • 处于审理中状况时,假如当时用户是管理员,它会揭露发布文档。
  • 处于已发布状况时,它不会进行任何操作。

状况机一般由众多条件运算符(ifswitch)实现,可依据目标的当时状况选择相应的行为。“状况”一般只是目标中的一组成员变量值。即使你之前从未听说过有限状况机,你也很可能已经实现过状况形式。

智能手机的按键和开关会依据设备当时状况完结不同行为

  • 当手机处于解锁状况时,按下按键将履行各种功能。
  • 当手机处于锁定状况时,按下任何按键都将解锁屏幕。
  • 当手机电量不足时,按下任何按键都将显现充电页面。
    状况形式主张为目标的一切可能状况新建一个类,然后将一切状况的对应行为抽取到这些类中。

原始目标被称为上下文(context),它并不会自行实现一切行为,而是会保存一个指向表示当时状况的状况目标的引用,且将一切与状况相关的工作委派给该目标。

状况是一种行为设计形式,让你能在一个目标的内部状况变化时改动其行为。

2. 什么时候运用状况形式

以下这些状况可以考虑运用状况形式

  • 假如目标需求依据本身当时状况进行不同行为,一起状况的数量十分多且与状况相关的代码会频繁变更的话,可运用状况形式。
  • 假如某个类需求依据成员变量的当前值改动本身行为,然后需求运用许多的条件语句时,可运用该形式。
  • 当相似状况和根据条件的状况机转化中存在许多重复代码时,可运用状况形式。

3. 代码展现

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()
    }
}

履行成果

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. 小结

咱们目标存在许多状况的时候,当时状况完结不同行为。或许存在许多条件判断对应不同状况,或许是相似状况和根据条件的状况机转化。都可以选用状况形式。比如咱们客户端用户有许多状况,咱们获取用户不同状况然后跳转不同页面或许一些操作。