设计模式心得:六——策略模式
策略模式:它定义了算法家族,分别封装起来让它们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。
策略模式是封装了一个算法,而这个算法是使用对象组合的方式实现的,比如:像上一篇模板方法模式中的付款,我们可以定义几个付款类,然后根据用户的选择来决定用哪个付款类来付款,以达到在运行时切换付款方式,而不改变其他步骤的实现。
策略模式和模板方法模式很相似,它们都是定义了一个算法,都可以相互替换而不影响客户的使用;不同的是模板方法模式使用的是继承来实现不同的算法,而策略模式是使用组合的方式来实现算法的替换;模板方法模式是定义了一个结构,而策略模式往往只是一个算法。由于策略模式使用的是组合的方式,它可以很方便的在运行时切换算法。但是它只是定义了某一个算法,不像模板方法模式是定义了一个结构,所以它的适用范围不如模板方法模式那样广。当然也可以将两个模式合并起来使用会得到更好的效果。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?php
abstract class Taobao {
private $_goods;
protected $_name;
protected $_IPay;
//选择一个商品
public function __construct($goods, $name, $pay)
{
$this->_goods = $goods;
$this->_name = $name;
$pay = ucfirst($pay);
$this->_IPay = new $pay();
}
// 购物流程
public final function shopping()
{
// 确认购买
$this->buy();
// 付款
$this->pay();
// 确认收货
$this->receive();
// 评价
$this->comment();
}
public function buy()
{
echo $this->_name . '购买了商品:' . $this->_goods . '。<br />';
}
// 付款由子类来决定采用哪种付款方式
public function pay()
{
$pay = $this->_IPay->pay();
echo $this->_name . '采用了' . $pay . '付款。<br />';
}
public function receive()
{
echo $this->_name . '确认收货:' . $this->_goods . '。<br />';
}
public function comment()
{
}
}
interface IPay {
public function pay();
}
class Bank implements IPay {
public function pay()
{
return '网银';
}
}
class Alipay implements IPay {
public function pay()
{
return '支付宝';
}
}
// A购物流程
class AProcess extends Taobao {
public function comment()
{
echo $this->_name . '对卖家进行了好评。<br />';
}
}
// B购物流程
class BProcess extends Taobao {
public function comment()
{
echo $this->_name . '对买家进行了中评。<br />';
}
}
// C购物流程
class CProcess extends Taobao {
// 我未进行评价
public function comment()
{
}
}
$zspay = empty($_POST['payTypeZS']) ? 'bank' : $_POST['payTypeZS'];
$lspay = empty($_POST['payTypeLS']) ? 'bank' : $_POST['payTypeLS'];
$wwpay = empty($_POST['payTypeWW']) ? 'bank' : $_POST['payTypeWW'];
// A采用了A购物流程
$a = new AProcess('Nokia 6300', '张三', $zspay);
$a->shopping();
echo '<hr />';
// B采用了B购物流程
$b = new BProcess('流氓兔', '李四', $lspay);
$b->shopping();
echo '<hr />';
// C采用了C购物流程
$c = new CProcess('T-shirt', '王五', $wwpay);
$c->shopping();
?>
<form action="" method="post">
<select name="payTypeZS" onchange="this.form.submit()">
<option value="bank">网银方式</option>
<option value="alipay">支付宝</option>
</select>
<select name="payTypeLS" onchange="this.form.submit()">
<option value="bank">网银方式</option>
<option value="alipay">支付宝</option>
</select>
<select name="payTypeWW" onchange="this.form.submit()">
<option value="bank">网银方式</option>
<option value="alipay">支付宝</option>
</select>
</form>
// 结果
// 张三购买了商品:Nokia 6300。
// 张三采用了网银付款。
// 张三确认收货:Nokia 6300。
// 张三对卖家进行了好评。
// --------------------------------------------------------------------------------
// 李四购买了商品:流氓兔。
// 李四采用了支付宝付款。
// 李四确认收货:流氓兔。
// 李四对买家进行了中评。
// --------------------------------------------------------------------------------
// 王五购买了商品:T-shirt。
// 王五采用了支付宝付款。
// 王五确认收货:T-shirt。