设计模式之策略模式的Python实现
1. 策略模式解决的是什么问题
策略模式解决的应用场景是这样的: 在业务场景中,需要用到多个算法,并且每个算法的参数是需要调整的。那么当不同的行为堆砌到同一个类中时,我们很难避免使用条件语句来选择合适的行为。我们需要解决的是把算法封装起来,达到算法的变化不会影响到使用算法的客户的效果。实际上就是把算法模块给完全独立出来,并且易于配置、修改和扩展,实现“开闭”原则。
通俗来讲就是针对一个问题而定义出一个解决的模板,这个模板就是具体的策略,每个策略都是按照这个模板来的。这种情况下我们有新的策略时就可以直接按照模板来写,而不会影响之前已经定义好的策略。只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。
2. 什么是策略模式
策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与算法使用类之间的耦合。
策略模式的Strategy类层次为Context定义了一系列可供重用的算法或者行为。继承有助于提取出这些算法中的公共功能。
策略模式的另一个优点:简化了单元测试。每个算法都有自己的类,是可以做自己的接口单独测试。
策略模式指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
3. 策略模式的具体实现
#!/usr/bin/python3
# -*- coding: utf-8 -*- class CashStrategy(object):
def __init__(self):
pass def charge(self):
pass class CashNormal(CashStrategy):
def charge(self,money):
return money class CashRebate(CashStrategy):
def __init__(self, rebate):
self.rebaterate = rebate def charge(self, money):
return money * self.rebaterate class CashReturn(CashStrategy):
def __init__(self, return_standard, return_money):
self.return_standard = return_standard
self.return_money = return_money def charge(self, money):
if money >= self.return_standard:
return money - self.return_money
else:
return money class CashContext(object):
def __init__(self, charge_type, *charge_parameters):
self.charge_type = charge_type
if charge_type == 'Normal':
self.current_strategy = CashNormal()
if charge_type == 'Rebate':
self.current_strategy = CashRebate(charge_parameters[0])
if charge_type == 'Return':
self.current_strategy = CashReturn(charge_parameters[0],charge_parameters[1]) def charge_money(self,money):
#print(self.charge_parameters)
return self.current_strategy.charge(money) if __name__ == "__main__":
charge_cash_1 = CashContext('Rebate',0.8)
print('Rebate: ',charge_cash_1.charge_money(200))
charge_cash_2 = CashContext('Normal')
print('Normal: ',charge_cash_2.charge_money(200))
charge_cash_3 = CashContext('Return',200,100)
print('Return: ',charge_cash_3.charge_money(200))
Rebate: 160.0
Normal:  200
Return:  100
4. 策略模式与工厂模式的异同
相同点:
实际上,我们发现策略模式和工厂模式是很像的。本质实现上都是子类覆盖父类,利用了语言的继承特性。
工厂模式中,每个要实现的类,可以对应到策略模式中每个具体的Strategy。
而工厂模式中的Factory,又可以对应到策略模式中的Context类。因为都在里面进行了对不同情况的处理(判断要实现哪个类,判断要采取哪种策略)
不同点:
用途不一样 
工厂是创建型模式,它的作用就是创建对象; 
策略是行为型模式,它的作用是让一个对象在许多行为中选择一种行为;
关注点不一样 
一个关注对象创建 
一个关注行为的封装
简单工厂模式只是解决了对象的创建问题,工厂需要包括所有的产品对象的创建,如果产品对象形式经常变化,就需要经常改动工厂,以致代码重新编译。所以策略模式就诞生了,策略模式---它定义了算法家族,分别封装起来,而不是像简单产品模式一样定义所有的产品类,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户,使客户拥有相同的访问过程。
所以我认为除了概念上的侧重点不同(用途,关注点),两者最明显的差异就是:策略模式中,不同的模式之间可以相互替换,不会影响到使用算法的客户。而工厂模式中,各个类不能相互替换。
参考链接:
1. 《大话设计模式》
2. 工厂模式与策略模式之区别 https://blog.csdn.net/gaibian0823/article/details/27842443
设计模式之策略模式的Python实现的更多相关文章
- python设计模式之策略模式
		
每次看到项目中存在大量的if else代码时,都会心生一丝不安全感. 特别是产品给的需求需要添加或者更改一种if条件时,生怕会因为自己的疏忽而使代码天崩地裂,哈哈,本文的目的就是来解决这种不安全感的, ...
 - 设计模式:策略模式(Strategy)
		
定 义:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化, 不会影响到使用算法的客户. 示例:商场收银系统,实现正常收费.满300返100.打8折.......等不同收费 ...
 - PHP设计模式之策略模式
		
前提: 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查 找.排序等,一种常用的方法是硬编码(Hard Cod ...
 - JavaScript设计模式之策略模式(学习笔记)
		
在网上搜索“为什么MVC不是一种设计模式呢?”其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composite).所以我今天选 ...
 - 乐在其中设计模式(C#) - 策略模式(Strategy Pattern)
		
原文:乐在其中设计模式(C#) - 策略模式(Strategy Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 策略模式(Strategy Pattern) 作者:webabc ...
 - JavaScript设计模式之策略模式
		
所谓"条条道路通罗马",在现实中,为达到某种目的往往不是只有一种方法.比如挣钱养家:可以做点小生意,可以打分工,甚至还可以是偷.抢.赌等等各种手段.在程序语言设计中,也会遇到这种类 ...
 - 【设计模式】【应用】使用模板方法设计模式、策略模式 处理DAO中的增删改查
		
原文:使用模板方法设计模式.策略模式 处理DAO中的增删改查 关于模板模式和策略模式参考前面的文章. 分析 在dao中,我们经常要做增删改查操作,如果每个对每个业务对象的操作都写一遍,代码量非常庞大. ...
 - [design-patterns]设计模式之一策略模式
		
设计模式 从今天开始开启设计模式专栏,我会系统的分析和总结每一个设计模式以及应用场景.那么首先,什么是设计模式呢,作为一个软件开发人员,程序人人都会写,但是写出一款逻辑清晰,扩展性强,可维护的程序就不 ...
 - 设计模式入门,策略模式,c++代码实现
		
// test01.cpp : Defines the entry point for the console application.////第一章,设计模式入门,策略模式#include &quo ...
 
随机推荐
- JS中的执行环境和作用域
			
window 是最大最外围的执行环境,然后每个函数都有自己的执行环境.JS代码是从上到下执行的,单纯的用语言描述可能会有点绕,而且不大直观.我们看着代码来 console.log('global be ...
 - iOS程序猿如何快速掌握 PHP,化身"全栈攻城狮"?
			
这是一篇以 iOS 开发人员的视角写给广大iOS 程序猿的 PHP 入门指南.在这篇文章里我努力去发掘 objectiv-c 与 php 之间的共性,来帮助有一定 iOS 开发经验的攻城狮来快速上手一 ...
 - 【树链剖分  ODT】cf1137F. Matches Are Not a Child's Play
			
孔爷的杂题系列:LCT清新题/ODT模板题 题目大意 定义一颗无根树的燃烧序列为:每次选取编号最小的叶子节点形成的序列. 要求支持操作:查询一个点$u$在燃烧序列中的排名:将一个点的编号变成最大 $n ...
 - nodejs 发送邮件(阿里云)
			
1.下载 模块 2. 编辑文件 var nodemailer = require('nodemailer'); var sendEmail = function(emailinfo,callbac ...
 - datatable设置动态宽度,超过一定长度出现滚动条
			
获得宽度:var tableAutoWidth = $('.dataTable_wrapper').width();if (tableAutoWidth < 1200) { tableAutoW ...
 - 关于IT人的一些消遣区
			
https://www.csdn.net/http://www.51cto.com/http://bestcbooks.com/http://www.jobbole.com/http://www.co ...
 - python-含参函数
			
#!/usr/local/bin/python3 # -*- coding:utf-8 -*- ''' #----------函数位置参数和关键字参数---------- def test(x,y): ...
 - 笔记-scrapy-深入学习-sheduler
			
笔记-scrapy-深入学习-sheduler 1. scheduler.py source code:scrapy/core/scheduler.py: 1.1. 初始化的开始 在分 ...
 - vue命令集合
			
创建vuecli脚手架:npm install -g @vue/cli拉取2的版本:npm install -g @vue/cli-init 创建webpack:npm i webpack@3.12. ...
 - phpstorm调试配置 Xdebug
			
这已经楼主第二次因为phpstorm的调试配置折腾了几个小时,这次一定要记下来!!! 以Xdebug chrome浏览器为例 一:安装 JetBrains IDE Support 二:安装 Xdebu ...