python与网页设计的区别_Python与设计模式(三):行为型模式(上)
接前文:kant li:Python與設計模式(二):結構型模式(下)?zhuanlan.zhihu.com
行為型模式主要處理對象間的通信問題,包括責任鏈模式、命令模式、解釋器模式、迭代器模式、觀察者模式、狀態模式、策略模式、模板模式等。
1. 責任鏈模式
責任鏈模式一般用于任務的鏈式處理。前一個處理者處理后,任務傳遞給下一個處理者,直至完成。
大家常用的例子是OA系統中的審批流程,比如請假。假設3天以下的假期只需要團隊長審批,3天以上的同時需要部門經理審批,7天以上的還需要業務總監審批,那么,就形成了一條請假審批的責任鏈:主管審批之后,任務沒有完成,提交至經理,如果還沒有完成,則繼續往上級提交。
一般的代碼會為每一個審批級構建一個類,定義它的處理方法和下一個處理者:
class Director:
successor = None
def handle_vocation(self, days): pass
class Manager:
successor = Director()
def handle_vocation(self, days):
if days < 7:
pass
else:
self.successor.handle_vocation(days)
class Teamleader:
successor = Manager()
def handle_vocation(self, days):
if days < 3:
pass
else:
self.successor.handle_vocation(days)
作為例子,我們可以通過這個代碼大概理解責任鏈模式的含義。通過責任鏈模式,我們解耦了請求發起者和請求處理者之間的關系,請假的人不需要關心誰來審批的問題,只需要把假條給他的直接主管。
但我們都知道,現實中應該不會這么寫代碼。今天審批請假,明天審批出差,后天審批報銷,不同層級的人走的審批路線還不一樣,這樣的類和方法是寫不完的,缺乏靈活性。
我們看釘釘的設計,可以由行政部門根據需要,動態設計審批流程,不同崗位、不同部門、不同層級的員工對應不同的流程,這才是比較貼合實際的情形,我們一般也會這么寫。
class Process:
id = 0
name = ''
class Step:
id = 0
name = ''
process_id = 0
pre_step_id = 0
next_step_id = 0
即有一個流程對象,每個流程對象有不同的步驟,每個步驟有前置步驟和后續步驟,這里使用id來表示,其實是對應著實際中的數據庫記錄。可以每完成一個步驟,就生成下一個步驟,也可以在任務一開始就生成所有步驟。
仔細想想,這應該只是處理實際需求中的責任鏈模式,而不是在代碼的組織中體現了責任鏈模式,可供參考吧。畢竟,需要硬編碼寫死的責任鏈還是比較少的。
2. 命令模式
命令模式的目的也是解耦請求發起者和請求處理者之間的關系。方式是把請求(或者說命令)做單獨的封裝,通過請求的執行方法來調用處理者完成任務。
常用的例子是餐館點餐:不同的廚師負責不同的菜品,服務員需要根據客戶點的菜,將請求發給不同的廚師。通過命令模式,服務員不需要知道哪個廚師負責哪個菜品,相關信息保存在對應菜品(即請求,或者說命令)的信息中,調用執行方法時,將自動通知對應的廚師完成菜品。
因為請求單獨做了封裝,所以可以保存在一個隊列之類的容器中,也可以隨時撤銷。
有些不需要馬上完成的工作,打包成命令,放入某個隊列,等處理者有空的時候再執行是很合理的。比如一些服務器維護、數據庫備份命令等,我們一般設置定時任務來進行處理,有時會設置在某個預計訪問量比較少的時間段,但這個時間段并不總是可靠的,那么,就可以先放入任務隊列中。如果CPU占用率、硬盤讀寫量低于設定值,就讓命令執行,否則就放回隊列繼續等待。
import abc
class Requester:
def __init__(self):
self._commands = []
def add_command(self, command):
self._commands.append(command)
def send_commands(self):
for command in self._commands:
command.execute()
class Command(metaclass=abc.ABCMeta):
def __init__(self, receiver):
self._receiver = receiver
@abc.abstractmethod
def execute(self):
pass
class Command_1(Command):
def execute(self):
self._receiver.action()
class Receiver:
def action(self):
pass
def main():
receiver = Receiver()
command_1 = Command_1()
requester = Requester()
requester.add_command(command_1)
requester.send_commands()
if __name__ == "__main__":
main()
3. 觀察者模式
與責任鏈模式、命令模式一樣,觀察者模式也用于處理消息發送者和接收者之間的關系。
不同的是:責任鏈模式下,發送者只需要知道第一個消息接收者就行,消息在一個個接收者之間鏈式傳播;
命令模式下,消息發送者只需要了解有什么命令,至于命令要傳給誰執行,則由命令自身決定;
而在觀察者模式下,消息發送者把接收者保存在一個列表中,當自身狀態發生改變,就通知列表中的所有成員。
Python 主流 Web 框架 Django 有一個第三方包,django-observer,就提供了跟蹤模型字段變化的簡潔方式,用戶可以注冊回調函數,在字段變化時自動執行一些任務。
被觀察者通知觀察者,可以同步通知,即直接調用一些函數;也可以通過消息隊列進行異步通知,這樣,被觀察者就不用等待觀察者的反饋,直接進行自己的下一步任務。
就通知消息來說,可以將準確的變動信息直接告知接收者,即所謂的“push”模式,也可以只告知發生變動,讓消息接收者根據需要拉取信息,即所謂的“pull”模式。
Python中的觀察者模式沒什么特殊的,但是可以通過屬性設置器在類屬性變動時觸發通知動作。簡單示例如下:
class Notifier:
def __init__(self):
self._observers = set()
self._state = None
def add_observer(self, observer):
self._observers.add(observer)
def remove_boserver(self, observer):
self._observers.discard(observer)
def _notify(self):
for observer in self._observers:
observer.update(self.state)
@property
def state(self):
return self._state
@state.setter
def state(self, obj_state):
self._state = obj_state
self._notify()
4. 狀態模式
有限狀態機是現實中常見的場景:當對象處于不同狀態時,執行不同的行為;或者當對象的狀態發生變化時,執行特定的行為。
常見的例子是零食販賣機:當我們塞入零錢時,達到某些零食的價格,可能對應零食的指示燈就會變綠,在這種狀態下,我們可以正常購買,而有些零食可能價格較貴,指示燈還是紅色的,點擊購買時會給出余額不足的提示。
在代碼中,實現狀態模式,一般要關注兩點,一個是狀態變化時需要執行的動作,一個是處在不同狀態時,對象會表現出不同的行為。
簡單代碼體現如下:
class VenderMachine:
def set_state(self, state):
do_something()
self._state = state
def execute(self):
self._state.execute()
class State_A:
def execute(self): pass
class State_B:
def execute(self): pass
vender_machine = VenderMachine()
state_a = State_A()
vender_machine.set_state(state_a)
vender_machine.execute()
在Python中,很多第三方庫提供了狀態機的簡單實現,目前,GitHub 上 Star 最多的應該是 transition 模塊(https://github.com/pytransitions/transitions),有興趣可以直接參考文檔,還是挺有意思的。
未完待續……
公眾號:ReadingPython
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的python与网页设计的区别_Python与设计模式(三):行为型模式(上)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 信用卡额度真的越高越好吗 怎么获得高额度
- 下一篇: java native 接口_Java本