策略模式(Strategy)

意图

对象有某个行为,但是在 不同的场景 下,该行为有 不同的实现算法

就好比你去餐馆吃饭,首页你要通过菜单来选择你想吃的菜,根据你点的菜的不同,在厨房中去做不同的菜。同样是菜但是根据不同的菜名,有不同的做法。

适用性

  • 需要在不同的情况下使用不同的策略(算法),或者在未来可能还要使用新的策略
  • 对客户隐藏具体策略(算法)的具体的实现,彼此完全独立

实现方式

  1. 定义抽象策略类,通常由一个接口或抽象类实现。
  2. 具体策略类,封装了具体的算法和行为。
  3. 环境类,持有一个策略类的引用,最终给客户端调用。

缺点

  1. 客户端 必须知道所有的策略类 ,并自行选择使用哪一个策略类。
  2. 策略模式造成很多的策略类,每个具体策略类都会产生一个新类 【可使用「享元模式」来减少对象的数量】

代码示例

支付方式

这里以 支付 为例,
我们在购买商品时,经常会选择不同支付方式来付款,这就是一种策略。

UML类图

抽象策略类

PayStrategy.php

<?php
/**
* Description: 支付策略 抽象接口类
* Created by Martini
* DateTime: 2019-07-02 13:39
*/ namespace DesignPatterns\Behavioral\Strategy; interface PayStrategy
{
/**
* 支付算法
* @return mixed
* @author Martini 2019-07-02 14:15
*/
public function payAlgorithm();
}

具体策略类

Alipay.php

<?php
/**
* Description:[具体策略类(ConcreteStrategy)] 支付宝支付类
* Created by Martini
* DateTime: 2019-07-02 13:42
*/ namespace DesignPatterns\Behavioral\Strategy; class Alipay implements PayStrategy
{
public function payAlgorithm()
{
return '使用支付宝支付相关支付算法';
}
}

具体策略类

Wechatpay.php

<?php
/**
* Description: [具体策略类(ConcreteStrategy)] 微信支付类
* Created by Martini
* DateTime: 2019-07-02 13:44
*/ namespace DesignPatterns\Behavioral\Strategy; class Wechatpay implements PayStrategy
{
public function payAlgorithm()
{
return '使用微信支付相关支付算法';
}
}

环境类

PayUtils.php

<?php
/**
* Description:[环境类(Context)] 支付实用工具类
* 用一个ConcreteStrategy具体策略类对象来配置
* 维护一个对Strategy策略对象的引用. 可以定义一个接口来让Strategy访问它的数据
* Created by Martini
* DateTime: 2019-07-02 13:49
*/ namespace DesignPatterns\Behavioral\Strategy; class PayUtils
{
private $_strategy = null; public function __construct(PayStrategy $pay)
{
$this->_strategy = $pay;
} /**
* 更改支付策略
* @param PayStrategy $pay
*
* @author Martini 2019-07-02 14:01
*/
public function setPayStrategy(PayStrategy $pay)
{
$this->_strategy = $pay;
} /**
* 支付
* @return mixed
* @author Martini 2019-07-02 14:02
*/
public function pay()
{
return $this->_strategy->payAlgorithm();
}
}

测试

<?php
/**
* Description: 策略模式测试 支付策略测试用例
* Created by Martini
* DateTime: 2019-07-02 14:07
*/ namespace DesignPatterns\Behavioral\Strategy\Tests; use DesignPatterns\Behavioral\Strategy\Alipay;
use DesignPatterns\Behavioral\Strategy\PayUtils;
use DesignPatterns\Behavioral\Strategy\Wechatpay;
use PHPUnit\Framework\TestCase; class StrategyTest extends TestCase
{
public function testPay()
{
// 使用支付宝支付
$pay = new PayUtils(new Alipay());
$this->assertEquals('使用支付宝支付相关支付算法', $pay->pay()); //切换为使用微信支付
$pay->setPayStrategy(new Wechatpay());
$this->assertEquals('使用微信支付相关支付算法', $pay->pay());
}
}

设计模式 行为型 - 策略模式 Strategy的更多相关文章

  1. 【转】设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

    设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成 ...

  2. 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

    设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也经常遇到类似的情况,实现某一个功能有多种算法或者策略,我们能够依据环境或者条件的不同选择不同的算法或者策略来完毕 ...

  3. JavaScript设计模式 Item 7 --策略模式Strategy

    1.策略模式的定义 何为策略?比如我们要去某个地方旅游,可以根据具体的实际情况来选择出行的线路. 如果没有时间但是不在乎钱,可以选择坐飞机. 如果没有钱,可以选择坐大巴或者火车. 如果再穷一点,可以选 ...

  4. 设计模式系列之策略模式(Strategy Pattern)

    意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换. 主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护. 何时使用:一个系统有许多许多类,而区分它 ...

  5. 《JAVA设计模式》之策略模式(Strategy)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述策略(Strategy)模式的: 策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它 ...

  6. 《Head First 设计模式》[01] 策略模式

    <Head First 设计模式>(点击查看详情) 1.写在前面的话 之前在列书单的时候,看网友对于设计模式的推荐里说,设计模式的书类别都大同小异,于是自己就选择了Head First系列 ...

  7. 策略模式 Strategy 政策Policy 行为型 设计模式(二十五)

    策略模式 Strategy   与策略相关的常见词汇有:营销策略.折扣策略.教学策略.记忆策略.学习策略.... “策略”意味着分情况讨论,而不是一概而论 面对不同年龄段的人,面对不同的商品,必然将会 ...

  8. [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型)

    [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模 ...

  9. JAVA设计模式之策略模式 - Strategy

    在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式. 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 ...

随机推荐

  1. MySQL内连接、左连接、右连接的使用以及区别

    首先先建两个表,student表和score表 select * from student; student表数据如下: select * from score; score表数据如下:    可以看 ...

  2. HttpRuntime应用程序运行时

    System.Web.HttpRuntime类是整个Asp.net服务器处理的入口. 这个类提供了一系列的静态属性,反映web应用程序域的设置信息,而且每个web应用程序域中存在一个System.We ...

  3. 从网络服务生成Apex类

    使用WSDL2Apex从网络服务生成Apex类 如果某个网络服务被定义在WSDL文件中,而Salesforce必须使用SOAP和网络服务进行通信,则这种情况在某些时候会为开发者带来很多麻烦.为了简化S ...

  4. win7 64位平台编译的程序在XP 32位平台无法运行的解决方法

    win7 64位平台编译的程序在XP 32位平台无法运行的解决方法 vs2010的开发环境,制作了一个DLL库.但DLL在XP 32位平台一直无法使用.解决方法如下: 右键项目,属性->配置属性 ...

  5. 7.16 NOIP模拟测试4 礼物+通讯+奇袭

    T1 礼物 题目大意:n个物品,每次有pi的概率买到,可以重复买,也可以什么都没买到,但算一次购买,问把所有东西都买到的期望次数.对于10%的数据,N = 1;对于30%的数据,N ≤ 5;对于100 ...

  6. Linux性能优化实战学习笔记:第四十五讲

    一.上节回顾 专栏更新至今,四大基础模块的最后一个模块——网络篇,我们就已经学完了.很开心你还没有掉队,仍然在积极学习思考和实践操作,热情地留言和互动.还有不少同学分享了在实际生产环境中,碰到各种性能 ...

  7. [LeetCode] 880. Decoded String at Index 在位置坐标处解码字符串

    An encoded string S is given.  To find and write the decoded string to a tape, the encoded string is ...

  8. java 获取用户输入

    import java.util.Scanner; public class Sample { public static void main(String[] args) { int num; Sc ...

  9. 2018-2019-2 20162329 《网络对抗技术》Exp9: Web安全基础

    目录 Exp9: Web安全基础 一.基础知识 1.SQL注入攻击 2.XSS跨站脚本攻击 3.CSRF跨站请求伪造 二.SQL注入 1. 命令注入 2. 数字注入 3. 日志欺骗 三.XSS攻击 1 ...

  10. 在Azure DevOps Server (TFS)中实现VUE项目的自动打包

    概述 Vue.js(读音 /vjuː/, 类似于 view)是一个构建数据驱动的 web 界面的渐进式框架.由于它在数据绑定.页面展示和使用简单方面有很大的优势,逐渐被越来越多的前端开发团队使用.本文 ...