天津做网站的公司排行,网站菜单分类怎么做的,怎么创建网站论坛,大型集团网站建设公司接前文#xff1a;kant li#xff1a;Python与设计模式(二)#xff1a;结构型模式(下)zhuanlan.zhihu.com行为型模式主要处理对象间的通信问题#xff0c;包括责任链模式、命令模式、解释器模式、迭代器模式、观察者模式、状态模式、策略模式、模板模式等。1. 责任链模式…接前文kant liPython与设计模式(二)结构型模式(下)zhuanlan.zhihu.com行为型模式主要处理对象间的通信问题包括责任链模式、命令模式、解释器模式、迭代器模式、观察者模式、状态模式、策略模式、模板模式等。1. 责任链模式责任链模式一般用于任务的链式处理。前一个处理者处理后任务传递给下一个处理者直至完成。大家常用的例子是OA系统中的审批流程比如请假。假设3天以下的假期只需要团队长审批3天以上的同时需要部门经理审批7天以上的还需要业务总监审批那么就形成了一条请假审批的责任链主管审批之后任务没有完成提交至经理如果还没有完成则继续往上级提交。一般的代码会为每一个审批级构建一个类定义它的处理方法和下一个处理者class Director:successor Nonedef handle_vocation(self, days): passclass Manager:successor Director()def handle_vocation(self, days):if days 7:passelse:self.successor.handle_vocation(days)class Teamleader:successor Manager()def handle_vocation(self, days):if days 3:passelse:self.successor.handle_vocation(days)作为例子我们可以通过这个代码大概理解责任链模式的含义。通过责任链模式我们解耦了请求发起者和请求处理者之间的关系请假的人不需要关心谁来审批的问题只需要把假条给他的直接主管。但我们都知道现实中应该不会这么写代码。今天审批请假明天审批出差后天审批报销不同层级的人走的审批路线还不一样这样的类和方法是写不完的缺乏灵活性。我们看钉钉的设计可以由行政部门根据需要动态设计审批流程不同岗位、不同部门、不同层级的员工对应不同的流程这才是比较贴合实际的情形我们一般也会这么写。class Process:id 0name class Step:id 0name process_id 0pre_step_id 0next_step_id 0即有一个流程对象每个流程对象有不同的步骤每个步骤有前置步骤和后续步骤这里使用id来表示其实是对应着实际中的数据库记录。可以每完成一个步骤就生成下一个步骤也可以在任务一开始就生成所有步骤。仔细想想这应该只是处理实际需求中的责任链模式而不是在代码的组织中体现了责任链模式可供参考吧。毕竟需要硬编码写死的责任链还是比较少的。2. 命令模式命令模式的目的也是解耦请求发起者和请求处理者之间的关系。方式是把请求(或者说命令)做单独的封装通过请求的执行方法来调用处理者完成任务。常用的例子是餐馆点餐不同的厨师负责不同的菜品服务员需要根据客户点的菜将请求发给不同的厨师。通过命令模式服务员不需要知道哪个厨师负责哪个菜品相关信息保存在对应菜品(即请求或者说命令)的信息中调用执行方法时将自动通知对应的厨师完成菜品。因为请求单独做了封装所以可以保存在一个队列之类的容器中也可以随时撤销。有些不需要马上完成的工作打包成命令放入某个队列等处理者有空的时候再执行是很合理的。比如一些服务器维护、数据库备份命令等我们一般设置定时任务来进行处理有时会设置在某个预计访问量比较少的时间段但这个时间段并不总是可靠的那么就可以先放入任务队列中。如果CPU占用率、硬盘读写量低于设定值就让命令执行否则就放回队列继续等待。import abcclass 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(metaclassabc.ABCMeta):def __init__(self, receiver):self._receiver receiverabc.abstractmethoddef execute(self):passclass Command_1(Command):def execute(self):self._receiver.action()class Receiver:def action(self):passdef 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 Nonedef 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)propertydef state(self):return self._statestate.setterdef state(self, obj_state):self._state obj_stateself._notify()4. 状态模式有限状态机是现实中常见的场景当对象处于不同状态时执行不同的行为或者当对象的状态发生变化时执行特定的行为。常见的例子是零食贩卖机当我们塞入零钱时达到某些零食的价格可能对应零食的指示灯就会变绿在这种状态下我们可以正常购买而有些零食可能价格较贵指示灯还是红色的点击购买时会给出余额不足的提示。在代码中实现状态模式一般要关注两点一个是状态变化时需要执行的动作一个是处在不同状态时对象会表现出不同的行为。简单代码体现如下class VenderMachine:def set_state(self, state):do_something()self._state statedef execute(self):self._state.execute()class State_A:def execute(self): passclass State_B:def execute(self): passvender_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