go语言设计模式之状态模式(酒店房间管理状态)
本文主要说一下设计模式之状态模式,后续会有更多的模式和算法以及区块链相关的,如果你是想学习go语言或者是对设计模式或者算法感兴趣亦或是区块链开发工作者,都可以关注一下。(微信公众号:Go语言之美,csdn:Go语言之美。更多go语言知识信息等)。
相信大多数程序员乘坐电梯时,都想过电梯算法的实现,我记得我当初想的时候,脑袋一开始就是if,else if,这种方式来判断电梯的状态,从而根据状态来设置电梯的运行。一直到我看了状态模式,才明白状态模式可以完美的解决电梯的运行算法,不止是电梯的运行,还有红绿灯,网店的订单等,都可以用状态模式完美实现。今天我用go语言简单实现酒店的房间管理状态,代码其实很简单,这只是一个示例,我们需要掌握其中的模式思想,将现实状态抽象出来,用代码实现,理解了整个思路,遇到类似的项目,我们才可以游刃有余。
状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。说白了,就是这个对象的状态改变了,就要去做对应状态应该做的事情。
努力工作的gopher
状态模式结构图
我们先看一个简单的酒店房间状态的简单实现:
package main import "fmt" type RoomState interface { Handle(int) } type FreeState struct { } func (this *FreeState) Handle(num int) { fmt.Printf("%d 房间空闲,可以入住。 ", num) } type BookedState struct { } func (this *BookedState) Handle(num int) { fmt.Printf("%d 房间已经有人预定。 ", num) } type CheckedInState struct { } func (this *CheckedInState) Handle(num int) { fmt.Printf("%d 房间已经有人入住。 ", num) } type RoomContext struct { Num int // 房间号码 State RoomState } func (this *RoomContext) SetState(state RoomState) { this.State = state this.State.Handle(this.Num) } func main() { room := RoomContext{Num: 101} free := new(FreeState) booked := new(BookedState) checkedIn := new(CheckedInState) room.SetState(free) room.SetState(booked) room.SetState(checkedIn) }
代码运行结果
代码很简单,房间只有三个状态(实际上还有其他状态,清洁中等)空闲、预定和已经入住。每当这个房间状态改变了,我们就可以做对应状态应该做的事情,这里我只是打印出来对应的状态。上面代码中,首先有了一个状态的接口,这个接口是所有状态都要实现的接口,这样这个房间才可以在各个状态中变换自如。对于客户端来说,主要指定一个房间号码,然后根据实际情况就可以转换这个房间的状态。我们要特别说一下RoomContext这个结构体,这个就是一个房间的类,我们这里只是加了一个房间号码用来区分各个房间。如果我们是一个银行系统,那么这个Context类就可以是一个客户的账户,如果是一个电梯系统,那么Context就是一个电梯的类。
我相信肯定有人会说,这么简单,我只用一个判断语句就可以解决啊,而且代码简单,意思更加明了。当然,如果一个系统只有这么简单的要求,我们完全可以用一个判断语句来解决,但是事实上,我们的项目都会很复杂,例如这个酒店房间管理,如果状态从以入住变到空闲,那么我们应该怎么做?没错,我们需要打扫房间,这是如果酒店是全自动的管理,那么我们就需要在这个状态的转换过程中通知清洁阿姨来打扫房间,如果房间变成了以入住,那么我们就可能需要通知酒店的其他服务人员来做一些其他后续的事情。这样一来,我们如果还是用简单的判断语句来写,那么这个代码的维护性将会难上加难,以至于后续我们有新的需求变得无从下手,但是用了这个模式,我们可以很轻松的处理各个状态的转换,而且以后增加新的状态也不必修改已有的代码,这其实就是遵循开放-封闭原则。
更多内容持续更新中...
如果有想看的,可以私聊我或者评论,我都会为大家尽力写一些文章。设计模式写完我将会写一些区块链或者算法或者go语言的深入学习,如果想看哪个可以在文章下评论。