聊聊Swift中的设计模式---行为型(状态模式)

147 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第29天,点击查看活动详情


前言

在面向对象的开发过程中,其实咱们或多或少的都接触过一些设计模式,可能知道或不知道其对应的名称,也不知道其具体使用场景,今天咱们就来说说几种常见的设计模式,帮助你们在开发过程中,更加得心应手。

正文

状态模式

状态模式,顾名思义就是,可以允许对象内部发生变化,当变化发生后就可以改变对象的行为,看起来就像变了一个对象。

状态通常由众多条件运算符 ( if或 switch ) 实现, 可根据对象的当前状态选择相应的行为。 

在现实世界中,也有类似的例子:

比如:

当我不是会员时,看视频就会出现广告

当我是VIP会员时,就可以跳过广告

当我是SVIP时,就可以在电视上看了。


接下来咱们在看看一个例子

首先定义了个Context类,里面定义了个未授权类的状态UnauthorizedState属性,同时也定义了两个函数changeStateToAuthorizedchangeStateToUnauthorized,用于改变state的状态。

class Context : CustomDebugStringConvertible {
    private var state: State = UnauthorizedState()

    var isAuthorized: Bool {
        get {
            return state.isAuthorized(context: self)
        }
    }

    var userId: String? {
        get {
            return state.userId(context: self)
        }
    }

    func changeStateToAuthorized(userId: String) {
        state = AuthorizedState(userId: userId)
    }

    func changeStateToUnauthorized() {
        state = UnauthorizedState()
    }

    var debugDescription: String {
        return "isAuthorized: (isAuthorized), userId:(userId ?? "")"
    }
}

定义一个状态(State)的协议


protocol State {
    func isAuthorized(context: Context) -> Bool
    func userId(context: Context) -> String?
}

然后分别定义未授权的状态UnauthorizedState和授权状态(AuthorizedState),都继承自State协议。然后实现了协议的方法。


class UnauthorizedState: State {
    func isAuthorized(context: Context) -> Bool {
        false
    }
    func userId(context: Context) -> String? {
        nil
    }
}

class AuthorizedState: State {
    let userId: String

    init(userId: String) {
        self.userId = userId
    }

    func isAuthorized(context: Context) -> Bool {
        true
    }

    func userId(context: Context) -> String? {
        userId
    }
}

最后咱们来看看 如何实现:

let userContext = Context()

print(userContext)
userContext.changeStateToAuthorized(userId: "oldbird")
print(userContext)

userContext.changeStateToUnauthorized()
print(userContext)

输出:

isAuthorized: false, userId:
isAuthorized: true, userId:oldbird
isAuthorized: false, userId:

可以看到,userContext使用不用的函数,输出的值就是不同的。这就是状态模式

结语

状态模式适合应用场景

  • 如果对象需要根据自身当前状态进行不同行为, 同时状态的数量非常多且与状态相关的代码会频繁变更的话, 可使用状态模式。

  • 如果某个类需要根据成员变量的当前值改变自身行为, 从而需要使用大量的条件语句时, 可使用该模式。

  • 当相似状态和基于条件的状态机转换中存在许多重复代码时, 可使用状态模式。

状态模式优缺点

优点

  • 单一职责原则。 将与特定状态相关的代码放在单独的类中。
  •  开闭原则。 无需修改已有状态类和上下文就能引入新状态。
  •  通过消除臃肿的状态机条件语句简化上下文代码。

缺点

  • 如果状态机只有很少的几个状态, 或者很少发生改变, 那么应用该模式可能会显得小题大作。

扩展阅读 下面还有其他模式

创建型-工厂模式

创建型-建造者模式

结构型-适配器模式

结构型-桥接模式

结构型-组合模式

结构型-装饰器模式

结构型-外观模式