23种设计模式-策略模式
概述
策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。
结构
策略模式主要角色如下:
- 抽象策略(Strategy)类:这是一个抽象角色,通常由一个接口或抽象类实现,此角色给出所有的具体策略类所需的接口。
- 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现或行为。
- 环境(Context)类:持有一个策略类的引用,最终给客户端调用。
实现
/**
* 第三方支付服务接口
* 抽象策略类
*/
interface Pay
{
public function getPayParams();
public function callback();
}
/**
* 具体策略类
*/
class Join implements Pay
{
public function getPayParams()
{
return '聚合支付订单参数';
}
public function callback()
{
return '执行聚合支付回调';
}
}
/**
* 具体策略类
*/
class Wechat implements Pay
{
public function getPayParams()
{
return '微信支付订单参数';
}
public function callback()
{
return '执行微信支付回调';
}
}
class PayContext
{
public function __construct(public Pay $pay)
{
}
public function getPayParams()
{
return $this->pay->getPayParams();
}
public function callback()
{
return $this->pay->callback();
}
}
// 测试
$joinPay = new PayContext(new Join());
$joinPay->getPayParams();
$joinPay->callback();
优缺点
优点
使用场景
- 一个系统需要动态的在几种算法中选择一种时,可将每个算法封装到具体的策略类中。
- 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支移入它们各自的策略类中以代替这些条件语句。
- 系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节时。
- 系统要求使用算法的客户不应该知道其操作的数据时,可使用策略模式来隐藏与算法相关的数据结构。