一盗棵、電梯控制器
電梯在我們周邊隨處可見壮韭,電梯的控制邏輯中心是由電梯控制器實(shí)現(xiàn)的。電梯的控制邏輯纹因,即使簡單點(diǎn)設(shè)計(jì)喷屋,把狀態(tài)分成開門狀態(tài),停止?fàn)顟B(tài)和運(yùn)行狀態(tài)瞭恰,操作分成開門屯曹、關(guān)門、運(yùn)行、停止恶耽,那流程也是很復(fù)雜的密任。首先,開門狀態(tài)不能開門偷俭、運(yùn)行浪讳、停止;停止?fàn)顟B(tài)不能關(guān)門涌萤,停止淹遵;運(yùn)行狀態(tài)不能開門、關(guān)門负溪、運(yùn)行透揣。要用一個(gè)一個(gè)if…else…實(shí)現(xiàn),首先代碼混亂笙以,不易維護(hù)淌实;二是不易擴(kuò)展。至于各種設(shè)計(jì)原則什么的……
那該如何實(shí)現(xiàn)猖腕?在上邊的邏輯中拆祈,每個(gè)操作僅僅是一個(gè)操作,狀態(tài)切換與操作是分離的倘感,這也造成后來操作和狀態(tài)“相互配合”的“手忙腳亂”放坏。如果把狀態(tài)抽象成一個(gè)類,每個(gè)狀態(tài)為一個(gè)子類老玛,每個(gè)狀態(tài)實(shí)現(xiàn)什么操作淤年,不實(shí)現(xiàn)什么操作,僅僅在這個(gè)類中具體實(shí)現(xiàn)就可以了蜡豹。
下面我們實(shí)現(xiàn)這個(gè)邏輯麸粮。
先實(shí)現(xiàn)抽象的狀態(tài)類:
class LiftState:
def open(self):
pass
def close(self):
pass
def run(self):
pass
def stop(self):
pass
而后實(shí)現(xiàn)各個(gè)具體的狀態(tài)類:
class OpenState(LiftState):
def open(self):
print "OPEN:The door is opened..."
return self
def close(self):
print "OPEN:The door start to close..."
print "OPEN:The door is closed"
return StopState()
def run(self):
print "OPEN:Run Forbidden."
return self
def stop(self):
print "OPEN:Stop Forbidden."
return self
class RunState(LiftState):
def open(self):
print "RUN:Open Forbidden."
return self
def close(self):
print "RUN:Close Forbidden."
return self
def run(self):
print "RUN:The lift is running..."
return self
def stop(self):
print "RUN:The lift start to stop..."
print "RUN:The lift stopped..."
return StopState()
class StopState(LiftState):
def open(self):
print "STOP:The door is opening..."
print "STOP:The door is opened..."
return OpenState()
def close(self):
print "STOP:Close Forbidden"
return self
def run(self):
print "STOP:The lift start to run..."
return RunState()
def stop(self):
print "STOP:The lift is stopped."
return self
為在業(yè)務(wù)中調(diào)度狀態(tài)轉(zhuǎn)移,還需要將上下文進(jìn)行記錄镜廉,需要一個(gè)上下文的類弄诲。
class Context:
lift_state=""
def getState(self):
return self.lift_state
def setState(self,lift_state):
self.lift_state=lift_state
def open(self):
self.setState(self.lift_state.open())
def close(self):
self.setState(self.lift_state.close())
def run(self):
self.setState(self.lift_state.run())
def stop(self):
self.setState(self.lift_state.stop())
這樣,在進(jìn)行電梯的調(diào)度時(shí)娇唯,只需要調(diào)度Context就可以了齐遵。業(yè)務(wù)邏輯中如下所示:
if __name__=="__main__":
ctx = Context()
ctx.setState(StopState())
ctx.open()
ctx.run()
ctx.close()
ctx.run()
ctx.stop()
打印如下:
STOP:The door is opening...
STOP:The door is opened...
OPEN:Run Forbidden.
OPEN:The door start to close...
OPEN:The dorr is closed
STOP:The lift start to run...
RUN:The lift start to stop...
RUN:The lift stopped...
由邏輯中可知,電梯先在STOP狀態(tài)塔插,然后開門梗摇,開門時(shí)運(yùn)行Run,被禁止想许,然后伶授,關(guān)門断序、運(yùn)行、停止糜烹。
二逢倍、狀態(tài)模式
狀態(tài)模式的定義如下:當(dāng)一個(gè)對象內(nèi)在狀態(tài)改變時(shí)允許其改變行為,這個(gè)對象看起來像改變了其類景图。
三较雕、狀態(tài)模式的優(yōu)點(diǎn)和應(yīng)用場景
優(yōu)點(diǎn):
1、狀態(tài)模式的優(yōu)點(diǎn)是結(jié)構(gòu)清晰挚币,相比于if…else…簡約了不少亮蒋;
2、封裝性好妆毕,外部調(diào)用不必知道內(nèi)部實(shí)現(xiàn)細(xì)節(jié)慎玖。
應(yīng)用場景:
1、行為狀態(tài)改變的場景笛粘。這點(diǎn)在各種控制器中非常常見趁怔,同時(shí),邏輯結(jié)構(gòu)為狀態(tài)轉(zhuǎn)移圖的場景中都非常適用薪前。
四润努、狀態(tài)模式的缺點(diǎn)
1、在狀態(tài)比較多時(shí)示括,子類也會(huì)非常多铺浇,不便于管理。