1 策略模式简介 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

2 模式组成 1)抽象策略角色(Strategy):

策略类,通常由一个接口或者抽象类实现。

2)具体策略角色(ConcreteStrategy):

包装了相关的算法和行为。

3)环境角色(Context):

持有一个策略类的引用,最终给客户端调用。

3 模式核心思想 策略模式是一种定义一些列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类的耦合。命令模式的算法是相互独立的,每个命令做的工作是不同的。而策略模式却是在做同一种工作。

4 模式架构图

5 程序架构

1) 抽象策略(Strategy)

// 定义接口,定义了要实现的策略算法interface IStrategy{ // 算法方法 public function doFunction();}

2) 具体策略(ConcreteStrategy)

// 具体A策略class ConcreteStrategyA implements IStrategy{ public function doFunction(){ echo '算法A实现'; }}// 具体B策略class ConcreteStrategyB implements IStrategy{ public function doFunction(){ echo '算法B实现'; }}// 具体C策略class ConcreteStrategyC implements IStrategy{ public function doFunction(){ echo '算法C实现'; }}

3)环境类(Context)

// 环境类,维护一个Strategy应用class Context{ // 策略 private $_strategy = null; public function __construct(IStrategy $strategy){ $this->_strategy = $strategy; } public function doWork(){ return $this->_strategy->doFunction(); }}

4)客户端(Client)

// 客户端类class Client{ public function main($data){ // A策略 $context = new Context(new ConcreteStrategyA()); $context->doWork(); // B策略 $context = new Context(new ConcreteStrategyB()); $context->doWork(); // C策略 $context = new Context(new ConcreteStrategyC()); $context->doWork(); }}

6 项目应用

6.1 需求说明 实现一个商场收银系统,商品可以有正常收费,打折收费,返利收费等模式(来之《大话设计模式》)

6.2 需求分析 按照需求,可以将收费操作设计成为一个接口算法,正常收费,打折收费,返利收费都继承这个接口,实现不同的策略算法。然后设计一个环境类,去维护策略的实例。

6.3 设计架构图

6.4 程序源码下载 http://download.csdn.net/detail/clevercode/8700009

6.5 程序说明

1)strategy.php

_moneyRebate = $rebate; } /** * 返回正常金额 * * @param double $money 金额 * @return double 金额 */ public function acceptCash($money){ return $this->_moneyRebate * $money; }}// 返利策略class ReturnStrategy implements ICashStrategy{ // 返利条件 private $_moneyCondition = null; // 返利多少 private $_moneyReturn = null; /** * 构造函数 * * @param double $moneyCondition 返利条件 * @return double $moneyReturn 返利多少 * @return void */ public function __construct($moneyCondition, $moneyReturn){ $this->_moneyCondition = $moneyCondition; $this->_moneyReturn = $moneyReturn; } /** * 返回正常金额 * * @param double $money 金额 * @return double 金额 */ public function acceptCash($money){ if (!isset($this->_moneyCondition) || !isset($this->_moneyReturn) || $this->_moneyCondition == 0) { return $money; } return $money - floor($money / $this->_moneyCondition) * $this->_moneyReturn; }}

2) strategyPattern.php

setCashStrategy($type); } /** * 设置策略(简单工厂与策略模式混合使用) * * @param string $type 类型 * @return void */ public function setCashStrategy($type){ $cs = null; switch ($type) { // 正常策略 case 'normal' : $cs = new NormalStrategy(); break; // 打折策略 case 'rebate8' : $cs = new RebateStrategy(0.8); break; // 返利策略 case 'return300to100' : $cs = new ReturnStrategy(300, 100); break; } $this->_strategy = $cs; } /** * 获取结果 * * @param double $money 金额 * @return double */ public function getResult($money){ return $this->_strategy->acceptCash($money); } /** * 获取结果 * * @param string $type 类型 * @param int $num 数量 * @param double $price 单价 * @return double */ public function getResultAll($type, $num, $price){ $this->setCashStrategy($type); return $this->getResult($num * $price); }}/* * 客户端类 * 让客户端和业务逻辑尽可能的分离,降低客户端和业务逻辑算法的耦合, * 使业务逻辑的算法更具有可移植性 */class Client{ public function main(){ $total = 0; $cashContext = new CashContext(); // 购买数量 $numA = 10; // 单价 $priceA = 100; // 策略模式获取结果 $totalA = $cashContext->getResultAll('normal', $numA, $priceA); $this->display('A', 'normal', $numA, $priceA, $totalA); // 购买数量 $numB = 5; // 单价 $priceB = 100; // 打折策略获取结果 $totalB = $cashContext->getResultAll('rebate8', $numB, $priceB); $this->display('B', 'rebate8', $numB, $priceB, $totalB); // 购买数量 $numC = 10; // 单价 $priceC = 100; // 返利策略获取结果 $totalC = $cashContext->getResultAll('return300to100', $numC, $priceC); $this->display('C', 'return300to100', $numC, $priceC, $totalC); } /** * 打印 * * @param string $name 商品名 * @param string $type 类型 * @param int $num 数量 * @param double $price 单价 * @return double */ public function display($name, $type, $num, $price, $total){ echo date('Y-m-d H:i:s') . ",$name,[$type],num:$num,price:$price,total:$total\r\n"; }}/** * 程序入口 */function start(){ $client = new Client(); $client->main();}start();?>

3)在strategy.php与strategyPattern.php中。如果需要扩展多的策略,只需要继承收费接口实现更多的类,这里与简单工厂模式结合使用。是程序更清晰。

7 总结

7.1 优点: 1、 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码。

2、 策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或行为变得不可能。

3、 使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。

7.2 缺点: 1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。

2、 策略模式造成很多的策略类,每个具体策略类都会产生一个新类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。

版权声明:

1)原创作品,出自"CleverCode的博客",转载时请务必注明以下原创地址,否则追究版权法律责任。

2)原创地址:(转载务必注明该地址)。

3)欢迎大家关注我博客更多的精彩内容:。

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

php项目收银系统,(三)设计模式之PHP项目应用(策略模式:商场收银系统)相关推荐

  1. 设计模式之策略模式在地铁票价系统中的应用

    引言 设计模式是面向对象编程的一个非常精彩的部分.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性,它能帮助我们将应用组织成容易了解,容易维护,具有弹性的架构.本文通过一个简单的案 ...

  2. Java设计模式(十二) 策略模式

    策略模式介绍 策略模式定义 策略模式(Strategy Pattern),将各种算法封装到具体的类中,作为一个抽象策略类的子类,使得它们可以互换.客户端可以自行决定使用哪种算法. 策略模式类图 策略模 ...

  3. 设计模式随笔系列:鸭子-策略模式(Strategy)[原]

    原文地址为: 设计模式随笔系列:鸭子-策略模式(Strategy)[原] 鸭子-策略模式(Strategy) 前言 万事开头难,最近对这句话体会深刻!这篇文章是这个系列正式开始介绍设计模式的第一篇,所 ...

  4. Java设计模式之行为型:策略模式

    一.背景: 在开发中经常遇到这种情况,实现某个功能有多种算法策略,我们可以根据不同环境或者条件选择不同的算法策略来完成该功能,比如查找.排序等,一种常用方式是硬编码在一个类中,如需要提供多种查找算法, ...

  5. 设计模式学习(一)——策略模式

    2019独角兽企业重金招聘Python工程师标准>>> 前段时间买了一本书<Head First设计模式>,看了第一章后才对设计模式的概念有少许了解:它其实是开发过程中很 ...

  6. 设计模式随笔系列:鸭子-策略模式(Strategy)

    鸭子-策略模式(Strategy) 前言 万事开头难,最近对这句话体会深刻!这篇文章是这个系列正式开始介绍设计模式的第一篇,所以肩负着确定这个系列风格的历史重任,它在我脑袋里默默地酝酿了好多天,却只搜 ...

  7. 设计模式_第二篇_策略模式

    本文是我通过学习<Head First 设计模式>而写. 作为我要描述的第一个模式,首先要说什么是设计模式,然后,用一个实例,并对这个实例不断的改进,引出策略模式. 与其空泛地给出一堆描述 ...

  8. 设计模式Java语言实现之策略模式

    策略模式: 前言: 作者:韩数 Github:github.com/hanshuaikan- 时间:2019-01-26 JDK版本:1.8 定义: 定义一系列的算法,把它们一个个封装起来,并且使它们 ...

  9. java中策略设计模式_Java中的设计模式(五):策略模式

    策略设计模式是行为设计模式之一.当我们为特定任务使用多个算法时,使用策略模式,客户端决定在运行时使用的实际实现. 策略模式的最佳示例之一是Collections.sort()采用Comparator参 ...

  10. Java两种设计模式_23种设计模式(11)java策略模式

    23种设计模式第四篇:java策略模式 定义:定义一组算法,将每个算法都封装起来,并且使他们之间可以互换. 类型:行为类模式 类图: 策略模式是对算法的封装,把一系列的算法分别封装到对应的类中,并且这 ...

最新文章

  1. 创建python2与python3虚拟环境失败的原因
  2. win linux 远程桌面连接,Windows 连接 Ubuntu 16.04 远程桌面
  3. 转贴:Hyper-V的几款免费管理工具
  4. linux内核模块常见问题
  5. 自定义jQuery插件
  6. mysql udf安全_打造全功能MYSQL入侵UDF
  7. 杭州c语言,杭州c语言的学习内容
  8. 【转】宝贝,我要出嫁了……
  9. Entity Framework Plus
  10. NanoHttpd android客户端作为服务器使用
  11. 10x 程序员工作法 - 划重点 | “自动化”主题的重点内容回顾汇总
  12. 颠覆传统股票证券市场的可能是ICO代币(TOKEN)
  13. android动图状态延迟获取到,android实现牛顿摆
  14. 读李智慧的《大型网站技术架构—核心原理与案例分析》有感
  15. Pycon 2017: Python可视化库大全
  16. checkpoints are occurring too frequently
  17. 闲置交易,二手交易,二手商城,同城交易,社交商城类APP源码
  18. ps一点等于多少厘米_在ps中1厘米是多少像素
  19. c++:警告:warning: catching polymorphic type ‘class std::exception’ by value
  20. 机械臂速成小指南(零):指南主要内容及分析方法

热门文章

  1. 手机触摸屏有电阻屏和电容屏,有什么区别?
  2. Radius认证协议(一)
  3. 特征选择之互信息(mutual information)算法思想及其python代码实现
  4. 信号与系统matlab实践实验二,信号与系统matlab实验课后习题答案
  5. linux 监听 ipv6,zabbix 监控 ipv6
  6. flash 游戏开发工作总结(1)--开发准备:FB的配置
  7. 在线编辑Word——插入公式
  8. Python图像匹配
  9. 概述无线传感网的MAC协议
  10. CTPN论文翻译——中英文对照