源码地址:https://github.com/weilanhanf/PythonDesignPatterns

说明:

策略指的就是为了达到某一目的而采取的手段或者方法。为了实现软件设计咪表,对象可能会用到多种多样的算法。这些算法甚至会经常改变。如果将这些算法都硬编码到对象中,将会使得对象本身变得臃肿不堪,而且有时候支持不同的算法也是一个性能负担。策略模式很好的实现了在运行时根据需要透明的更改对象的算法和将算法与本身对象解耦,从而避免出现上述两个问题。

因此策略模式可以定义为: 定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法可以独立于使用它的客户变化。每一个封装算法的类称之为策略(Strategy)类,策略模式提供了一种可插入式(Pluggable)算法的实现方案

策略模式的结构

策略模式包含以下3个角色: Context(环境类) Strategy(抽象策略类) ConcreteStrategy(具体策略类)

实例:

假设某司维护着一些客户资料,需要在该司有新产品上市或者举行新活动时通知客户。现通知客户的方式有两种:短信通知、邮件通知。应如何设计该系统的客户通知部分?为解决该问题,我们先构造客户类,包括客户常用的联系方式和基本信息,同时也包括要发送的内容。

class customer:
customer_name=""
snd_way=""
info=""
phone=""
email=""
def setPhone(self,phone):
self.phone=phone
def setEmail(self,mail):
self.email=mail
def getPhone(self):
return self.phone
def getEmail(self):
return self.email
def setInfo(self,info):
self.info=info
def setName(self,name):
self.customer_name=name
def setBrdWay(self,snd_way):
self.snd_way=snd_way
def sndMsg(self):
self.snd_way.send(self.info) #snd_way向客户发送信息的方式,该方式置为可设,即可根据业务来进行策略的选择。
#发送方式构建如下:
class msgSender:
dst_code=""
def setCode(self,code):
self.dst_code=code
def send(self,info):
pass class emailSender(msgSender):
def send(self,info):
print("EMAIL_ADDRESS:%s EMAIL:%s"%(self.dst_code,info)) class textSender(msgSender):
def send(self,info):
print("TEXT_CODE:%s EMAIL:%s"%(self.dst_code,info))

#业务场景中将发送方式作为策略
if __name__=="__main__":
customer_x=customer()
customer_x.setName("CUSTOMER_X")
customer_x.setPhone("")
customer_x.setEmail("customer_x@xmail.com")
customer_x.setInfo("Welcome to our new party!")
text_sender=textSender()
text_sender.setCode(customer_x.getPhone())
customer_x.setBrdWay(text_sender)
customer_x.sndMsg()
mail_sender=emailSender()
mail_sender.setCode(customer_x.getEmail())
customer_x.setBrdWay(mail_sender)
customer_x.sndMsg()

打印结果

TEXT_CODE:10023456789 EMAIL:Welcome to our new party!
EMAIL_ADDRESS:customer_x@xmail.com EMAIL:Welcome to our new party!

模式优点

提供了对开闭原则的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为 提供了管理相关的算法族的办法 提供了一种可以替换继承关系的办法 可以避免多重条件选择语句 提供了一种算法的复用机制,不同的环境类可以方便地复用策略类

模式缺点

客户端必须知道所有的策略类,并自行决定使用哪一个策略类 将造成系统产生很多具体策略类 无法同时在客户端使用多个策略类

模式适用环境

一个系统需要动态地在几种算法中选择一种 避免使用难以维护的多重条件选择语句 不希望客户端知道复杂的、与算法相关的数据结构,提高算法的保密性与安全性

另外:

仔细比较一下桥接模式和策略模式,如果把策略模式的Context设计成抽象类和实现类的方式,那么策略模式和桥接模式就可以划等号了。从类图看上去,桥接模式比策略模式多了对一种角色(抽象角色)的抽象。二者结构的高度同构,也只能让我们从使用意图上去区分两种模式:桥接模式解决抽象角色和实现角色都可以扩展的问题;而策略模式解决算法切换和扩展的问题。

python-策略模式的更多相关文章

  1. 设计模式(Python)-策略模式

    本系列文章是希望将软件项目中最常见的设计模式用通俗易懂的语言来讲解清楚,并通过Python来实现,每个设计模式都是围绕如下三个问题: 为什么?即为什么要使用这个设计模式,在使用这个模式之前存在什么样的 ...

  2. Python策略模式实现源码分享

    1.让一个对象的某个方法可以随时改变,而不用更改对象的代码 2.对于动态类型的Python语言,不需要定义接口 3.基本的实现方法:用类作为参数传递 例如: 12_eg3.py class Movea ...

  3. [Python模式]策略模式

    策略模式 定义了算法族,分别封装起来,让它们之间可以互相替换.此模式让算法的变化独立于使用算法的客户. 作为动态语言,Python实现策略模式非常容易,只要所有算法提供相同的函数即可. import ...

  4. Python 中的设计模式详解之:策略模式

    虽然设计模式与语言无关,但这并不意味着每一个模式都能在每一门语言中使用.<设计模式:可复用面向对象软件的基础>一书中有 23 个模式,其中有 16 个在动态语言中“不见了,或者简化了”. ...

  5. 【经典案例】Python详解设计模式:策略模式

    完成一项任务往往有多种方式,我们将其称之为策略. 比如,超市做活动,如果你的购物积分满1000,就可以按兑换现金抵用券10元,如果购买同一商品满10件,就可以打9折,如果如果购买的金额超过500,就可 ...

  6. python设计模式第九天【策略模式】

    1. 定义 对一系列算法进行封装,为所有算法定义一个抽象的算法接口,可以平滑的进行算法切换 2. 策略模式的UML图 3.代码实现 #!/usr/bin/env python #! _*_ codin ...

  7. Python 设计模式--策略模式

    策略模式(Strategy Pattern) 策略模式是一种与行为相关的设计模式,允许你在运行时根据指定的上下文确定程序的动作.可以在两个类中封装不同的算法,并且在程序运行时确定到底执行哪中策略. 特 ...

  8. 大话设计模式Python实现-策略模式

    策略模式(Strategy Pattern):它定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户. 下面是一个商场活动的实现 #!/usr/bin/e ...

  9. python实现策略模式

    python实现策略模式 原文地址 1.策略模式概述 策略模式:定义一系列算法,把它们一一封装起来,并且使它们之间可以相互替换.此模式让算法的变化不会影响到使用算法的客户. 电商领域有个使用“策略”模 ...

  10. 架构师修炼之设计模式 - 策略模式(Strategy) 【Python与C#实现】

    程序员,我为你祝福 愿你有一个灿烂的前程 愿你有情人终成眷属 愿你在尘世获得幸福 我只想成为架构师,走遍江湖! 目录 模式定义 模式分类 模式结构 实例(C#与Python版) 优点 缺点 使用场景 ...

随机推荐

  1. C#6.0语言规范(六) 转换

    转换能够被视为是一个特定类型的表达式.转换可能会导致给定类型的表达式被视为具有不同的类型,或者它可能导致没有类型的表达式获取类型.转换可以是隐式或显式的,这决定了是否需要显式转换.例如,从类型int到 ...

  2. HTML引入JS文件

    浏览器解析HTML文件时,先判断script 标签中是否有src属性,有则执行指定路径下的JS文件,没有则执行script标签中的js脚本. 1. HTML内嵌JS head里面添加script元素, ...

  3. WebForm - cookie赋值乱码问题

    cookie的值为中文时候,取cookie的值会出现乱码 解决办法:存取cookie时候先解码和编码 存cookie,进行编码: cookie.Value = HttpUtility.UrlEncod ...

  4. odoo开发笔记 -- 异常、错误、警告、提示、确认信息显示

    1.检查业务逻辑中的错误,终止代码执行,显示错误或警告信息: raise osv.except_osv(_('Error!'), _('Error Message.')) 示例代码: #删除当前销售单 ...

  5. 课程一(Neural Networks and Deep Learning),第二周(Basics of Neural Network programming)—— 2、编程作业常见问题与答案(Programming Assignment FAQ)

    Please note that when you are working on the programming exercise you will find comments that say &q ...

  6. OSGI动态加载删除Service bundle

    OSGi模块化框架是很早就出来的一个插件化框架,最早Eclipse用它而出名,但这些年也没有大热虽然OSGi已经发布了版本1到版本5.现在用的最多的,也是本文讲述基于的是Equinox的OSGi实现, ...

  7. 使用node和express+mongodb实现数据增删改功能

    2018即将过去,2019即将来临,前端技术不断在在更新,学的东西越来越多.我们只有不断的学习,才不能被淘汰.在前后端分离的一个时代,后端提供接口,前端调用接口,逻辑判断,每个都是独立的工作.如果自己 ...

  8. Spring Boot + Spring Cloud 实现权限管理系统 后端篇(二):数据库设计

    数据库设计 系统主要包含用户(sys_user).组织(sys_dept).角色(sys_role).菜单(sys_menu).角色组织(sys_role_dept).角色菜单(sys_role_me ...

  9. Java subList、toArray、asList 注意点

    1. ArrayList的subList 结果不可以强转成ArrayList,否则抛出ClassCastException异常,原因是subList返回的是ArrayList的内部类SubList,并 ...

  10. PowerBuilder编程新思维1:扩展(Lua)

    前言 PowerBuilder作为开发工具退出一线行列已经很久了,在2019年来谈这样一款老旧的编程工具是否有意义?诚然,PB有着太多硬伤,但还是有它的用武之地的.而且今天讲的这个“新思维”大部分内容 ...