设计模式 行为型 - 策略模式 Strategy
策略模式(Strategy)
意图
对象有某个行为,但是在 不同的场景 下,该行为有 不同的实现算法。
就好比你去餐馆吃饭,首页你要通过菜单来选择你想吃的菜,根据你点的菜的不同,在厨房中去做不同的菜。同样是菜但是根据不同的菜名,有不同的做法。
适用性
- 需要在不同的情况下使用不同的策略(算法),或者在未来可能还要使用新的策略
- 对客户隐藏具体策略(算法)的具体的实现,彼此完全独立
实现方式
- 定义抽象策略类,通常由一个接口或抽象类实现。
- 具体策略类,封装了具体的算法和行为。
- 环境类,持有一个策略类的引用,最终给客户端调用。
缺点
- 客户端 必须知道所有的策略类 ,并自行选择使用哪一个策略类。
- 策略模式造成很多的策略类,每个具体策略类都会产生一个新类 【可使用「享元模式」来减少对象的数量】
代码示例
支付方式
这里以 支付 为例,
我们在购买商品时,经常会选择不同支付方式来付款,这就是一种策略。
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的更多相关文章
- 【转】设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成 ...
- 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也经常遇到类似的情况,实现某一个功能有多种算法或者策略,我们能够依据环境或者条件的不同选择不同的算法或者策略来完毕 ...
- JavaScript设计模式 Item 7 --策略模式Strategy
1.策略模式的定义 何为策略?比如我们要去某个地方旅游,可以根据具体的实际情况来选择出行的线路. 如果没有时间但是不在乎钱,可以选择坐飞机. 如果没有钱,可以选择坐大巴或者火车. 如果再穷一点,可以选 ...
- 设计模式系列之策略模式(Strategy Pattern)
意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换. 主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护. 何时使用:一个系统有许多许多类,而区分它 ...
- 《JAVA设计模式》之策略模式(Strategy)
在阎宏博士的<JAVA与模式>一书中开头是这样描述策略(Strategy)模式的: 策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它 ...
- 《Head First 设计模式》[01] 策略模式
<Head First 设计模式>(点击查看详情) 1.写在前面的话 之前在列书单的时候,看网友对于设计模式的推荐里说,设计模式的书类别都大同小异,于是自己就选择了Head First系列 ...
- 策略模式 Strategy 政策Policy 行为型 设计模式(二十五)
策略模式 Strategy 与策略相关的常见词汇有:营销策略.折扣策略.教学策略.记忆策略.学习策略.... “策略”意味着分情况讨论,而不是一概而论 面对不同年龄段的人,面对不同的商品,必然将会 ...
- [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型)
[.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模 ...
- JAVA设计模式之策略模式 - Strategy
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式. 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 ...
随机推荐
- zz致力于变革未来的智能技术
有 R-CNN SPPNet Fast R-CNN Faster R-CNN ... 的论文翻译 现在已经不能访问了... [私人整理]空间金字塔池化网络SPPNet详解 SPP-Net是出自 ...
- 一种css效果:标题带色块,React+Less
.title { display: inline-block; font-size: 15px; font-weight: bold; position: relative; padding: 5px ...
- docker的一些常用操作
镜像:一个打包好的应用,还有应用运行的系统.资源.配置等容器:镜像的实例,一个镜像可以有一个或多个实例(容器)对docker容器的变更时写到容器的文件系统的,而不是写到docker镜像中的,可以用一个 ...
- CF1217E Sum Queries? (线段树)
完了,前几天才说 edu 的 DEF 都不会,现在打脸了吧 qwq 其实在刚说完这句话 1min 就会了 D,3min 就会了 E 发现,对于大小 \(\ge 3\) 的不平衡集合,它至少有一个大小为 ...
- 应用层协议:HTTP
1. HTTP定义 HyperText Transfer Protocol,超文本传输协议,是一个基于请求与响应,无状态的,应用层的协议,常基于TCP/IP协议传输数据,互联网上应用最为广泛的一种网络 ...
- golang中判断两个slice是否相等
在golang中我们可以轻松地通过==来判断两个数组(array)是否相等,但遗憾的是slice并没有相关的运算符,当需要判断两个slice是否相等时我们只能另寻捷径了. slice相等的定义 我们选 ...
- Golang(十二)TLS 相关知识(三)理解并模拟简单代理
0. 前言 前面的介绍我们理解了数字签名等知识,同时学习了 OpenSSL 生成私钥和证书并验证 之前提过我们基于 BitTorrent 协议开发了一个 docker 镜像分发加速插件 中间涉及到了配 ...
- Centos.安装Goaccess1.2
下载 wget http://tar.goaccess.io/goaccess-1.2.tar.gz 解压 tar -xzvf goaccess-1.2.tar.gz 安装支持库GeoIP-devel ...
- Springboot启动一直卡在{dataSource-1} inited
Springboot启动一直卡在{dataSource-1} inited 错误原因: 暂时未知,猜测是因为设置端点的问题 解决办法: 去除所有断点: 然后再次启动就好了. 如果还有错: 那么重新导入 ...
- Python【每日一问】38
问: 基础题: 设计一个经营杠杆系数函数DOL,它包含三个参数,S为营业收入,C为变动成本总额,F为固定成本的总额. 已知2018年的S为20,C为11,F为3,求2019年的经营杠杆系数. 提高题: ...