php 策略模式
策略模式定义了一族相同类型的算法,算法之间独立封装,并且可以互换代替。
这些算法是同一类型问题的多种处理方式,他们具体行为有差别。
每一个算法、或说每一种处理方式称为一个策略。
在应用中,就可以根据环境的不同,选择不同的策略来处理问题。
以数组输出为例。
数组的输出有序列化输出、JSON字符串输出和数组格式输出等方式。
每种输出方式都可以独立封装起来,作为一个策略。
应用时,如要把数组保存到数据库中,可以用序列化方式输出。
要提供给APP作接口,可以用JSON字符串输出。
其他程序调用,则直接输出数组格式。
1 问题
在没有设计模式的情况,我们用一个类集中处理数组输出,如下:
/**
* 根据给定类型,将数组转换后输出
*/
class Output
{
public function render($array, $type = '')
{
if ($type === 'serialize') {
return serialize($array);
} elseif ($type === 'json') {
return json_encode($array);
} else {
return $array;
}
}
}
客户端直接使用这个类来处理数组,就能达到效果:
/**
* 客户端代码
*/
$test = ['a', 'b', 'c'];
// 实例化输出类
$output = new Output();
// 直接返回数组
$data = $output->render($test, 'array');
// 返回JSON字符串
$data = $output->render($test, 'json');
这种方法的优点是简单、快捷,在小方案中使用非常合适。
但是,如果是一个复杂方案,包括大量的处理逻辑需要封装,或者处理方式变动较大,则就显得混乱。
当需要添加一种算法,就必须修改Output
类,影响原有代码,可扩展性差。
如果输出方式很多,if-else
或switch-case
语句也会很多,代码混乱难以维护。
2 解决
那如何用策略模式解决这个问题呢?
策略模式将各种方案分离开来,让操作者根据具体的需求,动态地选择不同的策略方案。
2.1 策略类
首先,定义一系列的策略类,它们独立封装,并且遵循统一的接口。
/**
* 策略接口
*/
interface OutputStrategy
{
public function render($array);
}
/**
* 策略类1:返回序列化字符串
*/
class SerializeStrategy implements OutputStrategy
{
public function render($array)
{
return serialize($array);
}
}
/**
* 策略类2:返回JSON编码后的字符串
*/
class JsonStrategy implements OutputStrategy
{
public function render($array)
{
return json_encode($array);
}
}
/**
* 策略类3:直接返回数组
*/
class ArrayStrategy implements OutputStrategy
{
public function render($array)
{
return $array;
}
}
以后的维护过程中,以上代码都不需修改了。
如果需要增加输出方式,重新建一个类就可以了。
(根据FIG-PSR规范,一个类就是一个独立的PHP文件。)
2.2 环境类
环境角色用来管理策略,实现不同策略的切换功能。
同样,一旦写好,环境角色类以后也不需要修改了。
/**
* 环境角色类
*/
class Output
{
private $outputStrategy;
// 传入的参数必须是策略接口的子类或子类的实例
public function __construct(OutputStrategy $outputStrategy)
{
$this->outputStrategy = $outputStrategy;
}
public function renderOutput($array)
{
return $this->outputStrategy->render($array);
}
}
2.3 客户端代码
在客户端中,策略模式通过给予不同的具体策略,来获取不同的结果。
/**
* 客户端代码
*/
$test = ['a', 'b', 'c'];
// 需要返回数组
$output = new Output(new ArrayStrategy());
$data = $output->renderOutput($test);
// 需要返回JSON
$output = new Output(new JsonStrategy());
$data = $output->renderOutput($test);
对于较为复杂的业务逻辑显得更为直观,扩展也更为方便。
3 特点
策略模式主要用来分离算法,根据相同的行为抽象来做不同的具体策略实现。
策略模式结构清晰明了、使用简单直观。并且耦合度相对而言较低,扩展方便。同时操作封装也更为彻底,数据更为安全。
当然策略模式也有缺点,就是随着策略的增加,子类也会变得繁多。
但缺点并不会影响系统运行,所以在复杂业务中应该考虑使用。
策略模式UML图:
原文地址:https://www.cnblogs.com/-mrl/p/13282543.html
- 手游热更新方案xLua开源:Unity3D下Lua编程解决方案
- 如何为Keras中的深度学习模型建立Checkpoint
- Dubbo 源码解析 —— Zookeeper 创建节点
- 熔断器 Hystrix 源码解析 —— 断路器 HystrixCircuitBreaker
- 源码级别解读 mybatis 插件
- 在WebKit中并行加载外部脚本译:
- 100行代码,搞定http监控框架
- 【腾讯反病毒实验室】深度剖析APT28最新作品
- [译]clearfix改良及overflow:hidden详解
- 深入解析CSS样式层叠权重值
- [译]CSS边框实现“无图化”设计
- 自适应的多列图文混排改进
- [译]Laravel 5.0 之运行环境及环境变量
- 90行代码,搞定日志监控框架
- php概述
- php教程
- php环境搭建
- PHP书写格式
- php变量
- php常量
- PHP注释
- php数组
- php字符串 string
- PHP整型 integer
- PHP浮点型 float
- php布尔型
- php数据类型之数组
- php数据类型之对象
- php数据类型之null
- php数据类型之间的转换
- php运算符
- php表达式
- PHP循环控制
- PHP流程控制
- php函数
- php全局变量
- PHP魔术变量
- php命名空间
- php 日期
- PHP包含文件
- php文件
- PHP 文件上传
- php Cookies
- php Sessions
- php email
- php安全email
- php错误处理
- PHP异常处理
- php过滤器
- PHP 高级过滤器
- php json
- php 表单
- PHP MySQL 简介
- PHP 连接 MySQL
- php创建数据库
- php 创建表
- php mysq 插入数据
- PHP MySQL 插入多条数据
- PHP MySQL 预处理语句
- php mysql 读取数据
- php mysql where
- PHP MySQL Order By
- PHP MySQL Update
- PHP MySQL Delete
- php ODBC
- python实现线性回归之岭回归
- 操作系统实验之存储管理
- MySQL EXPLAIN 的使用
- mybatis文件映射之关联查询初探(一)
- python实现线性回归之弹性网回归
- 【原创】python倒排索引之查找包含某主题或单词的文件
- python实现逻辑回归
- Linux文件管理参考
- CloudBase Framework丨第一个 Deno 部署工具是如何打造的?
- 关于null通过+" ",String.ValueOf转换为字符串的问题!!!
- Java实现尺取法
- 【自然语言处理】利用朴素贝叶斯进行新闻分类(自己处理数据)
- mybatis文件映射之select操作返回Map
- shm进程间通信失败了!!!
- Vue3.0 beta源码学习笔记(二)