设计模式-12.状态模式

153 阅读2分钟

一句话总结

状态模式主要解决的是多种状态判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。适合多种if else的情况。

需求

程序员小明早上精神好,写代码快。中午犯困,下午打盹,晚上加班。如何用代码描述他一天的工作状态呢?

Code V1.0

典型的面向过程编码来实现

static var hour = 0
static var workFinished = false

static func main() {
    hour = 9
    writeProgram()
    hour = 12
    writeProgram()
    hour = 13
    writeProgram()
    hour = 14
    writeProgram()
    hour = 17
    writeProgram()

    workFinished = true
    writeProgram()

    hour = 19
    writeProgram()
    hour = 22
    writeProgram()

}

static func writeProgram() {
    if hour < 12 {
        print("当前时间 \(hour) 点, 上午工作,精神百倍")
    } else if hour < 13 {
        print("当前时间 \(hour) 点, 吃午饭,犯困")
    } else if hour < 17 {
        print("当前时间 \(hour) 点, 下午状态还行,继续努力")
    } else {
        if workFinished {
            print("当前时间 \(hour) 点, 下班回家")
        } else {
            if hour < 21 {
                print("当前时间 \(hour) 点, 加班,困")
            } else {
                print("当前时间 \(hour) 点, 不行了,睡着了")
            }
        }
    }
}

Code V2.0

用面向对象实现,可以看到还是有很多if else的情况,不便于维护

static func main() {
    let work = Work()
    work.hour = 9
    work.writeProgram()
    work.hour = 12
    work.writeProgram()
    work.hour = 13
    work.writeProgram()
    work.hour = 14
    work.writeProgram()
    work.hour = 17
    work.writeProgram()

    work.workFinished = true
    work.writeProgram()

    work.hour = 19
    work.writeProgram()
    work.hour = 22
    work.writeProgram()
}

class Work {
    var hour = 0
    var workFinished = false

    func writeProgram() {
        if hour < 12 {
            print("当前时间 \(hour) 点, 上午工作,精神百倍")
        } else if hour < 13 {
            print("当前时间 \(hour) 点, 吃午饭,犯困")
        } else if hour < 17 {
            print("当前时间 \(hour) 点, 下午状态还行,继续努力")
        } else {
            if workFinished {
                print("当前时间 \(hour) 点, 下班回家")
            } else {
                if hour < 21 {
                    print("当前时间 \(hour) 点, 加班,困")
                } else {
                    print("当前时间 \(hour) 点, 不行了,睡着了")
                }
            }
        }
    }
}

状态模式

protocol State {
    func handle(context: Context)
}

class ConcreteStateA: State {
    func handle(context: Context) {
        context.state = ConcreteStateB()
    }
}

class ConcreteStateB: State {
    func handle(context: Context) {
        context.state = ConcreteStateA()
    }
}

class Context {
    var state: State {
        willSet {
            print(newValue)
        }
    }

    init(state: State) {
        self.state = state
    }

    func request() {
        state.handle(context: self)
    }
}

class main3: NSObject {
    static func main() {
        let c = Context(state: ConcreteStateA())

        c.request()
        c.request()
    }
}

Code V3.0

用状态模式实现这个需求。状态模式可以很好的将多种if else 的代码,分解成不同的状态类,写出便于维护、扩展的代码。

protocol State {
    func writeProgram(work: Work)
}

class Work {
    var currentState: State = ForenoonState()
    var hour: Float = 0
    var workFinished = false
    
    func writeProgram() {
        currentState.writeProgram(work: self)
    }
}

class ForenoonState: State {
    func writeProgram(work: Work) {
        if work.hour < 12 {
            print("当前时间 \(work.hour) 点, 上午工作,精神百倍")
        } else {
            work.currentState = NoonState()
            work.writeProgram()
        }
    }
}

class NoonState: State {
    func writeProgram(work: Work) {
        if work.hour < 13 {
            print("当前时间 \(work.hour) 点, 吃午饭,犯困")
        } else {
            work.currentState = AfternoonState()
            work.writeProgram()
        }
    }
}

class AfternoonState: State {
    func writeProgram(work: Work) {
        if work.hour < 17 {
            print("当前时间 \(work.hour) 点, 下午状态还行,继续努力")
        } else {
            work.currentState = EveningState()
            work.writeProgram()
        }
    }
}

class EveningState: State {
    func writeProgram(work: Work) {
        if work.workFinished {
            print("当前时间 \(work.hour) 点, 下班回家")
        } else {
            if work.hour < 21 {
                print("当前时间 \(work.hour) 点, 加班,困")
            } else {
                work.currentState = SleepState()
                work.writeProgram()
            }
        }
    }
}

class SleepState: State {
    func writeProgram(work: Work) {
        print("当前时间 \(work.hour) 点, 不行了,睡着了")
    }
}

static func main() {
    let work = Work()
    work.hour = 9
    work.writeProgram()
    work.hour = 12
    work.writeProgram()
    work.hour = 13
    work.writeProgram()
    work.hour = 14
    work.writeProgram()
    work.hour = 17
    work.writeProgram()

    work.workFinished = true
    work.writeProgram()

    work.hour = 19
    work.writeProgram()
    work.hour = 22
    work.writeProgram()
}