简单工厂模式和策略模式简介
关于简单工厂模式可以参看。
所谓的策略模式就是用来封装算法的。策略模式定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响到使用此算法的用户。
需求
现在有这样一个需求:
商场推出优惠活动,所有物品一律八折。
具体代码实现
为了后期维护,比如满 1000 才能打八折,我们使用策略模式实现。
定义一个抽象父类里面定义一个抽象方法,来具体实现价格的计算,所有收费子类继承这个抽象父类,实现这个计算方法:
CashSuper
<?php
/**
* Created by phpStorm.
* User: binwei
* Date: 2019/5/19
* Time: 20:51
*/
abstract class CashSuper
{
public abstract function acceptCash($money);
}
正常收费类:
<?php
/**
* Created by phpStorm.
* User: binwei
* Date: 2019/5/19
* Time: 20:52
*/
require_once "CashSuper.php";
class CashNormal extends CashSuper
{
public function acceptCash($money)
{
// TODO: Implement acceptCash() method.
return $money;
}
}
打折类:
<?php
/**
* Created by phpStorm.
* User: binwei
* Date: 2019/5/19
* Time: 20:53
*/
require_once "CashSuper.php";
class CashRebate extends CashSuper
{
// 打折情况,默认不打折
private $moneyRebate = 1;
/**
* CashRebate constructor.
* @param int $moneyRebate
*/
public function __construct($moneyRebate)
{
$this->moneyRebate = $moneyRebate;
}
public function acceptCash($money)
{
// TODO: Implement acceptCash() method.
return $money * $this->moneyRebate;
}
}
策略类:
<?php
/**
* Created by phpStorm.
* User: binwei
* Date: 2019/5/19
* Time: 20:57
*/
class CashContext
{
private $cashSuper;
/**
* 通过构造方法传入具体的收费策略
* CashContext constructor.
* @param $cashSuper
*/
public function __construct(CashSuper $cashSuper)
{
$this->cashSuper = $cashSuper;
}
public function getResult($money)
{
return $this->cashSuper->acceptCash($money);
}
}
具体使用:
<?php
/**
* Created by phpStorm.
* User: binwei
* Date: 2019/5/19
* Time: 21:03
*/
require_once "CashContext.php";
require_once "CashNormal.php";
require_once "CashRebate.php";
$beforeTotal = 1000; // 之前的总价
$type = "0.8";// 打八折
$cashContext = null; // strategy 对象的引用
switch ($type) {
case "1": // 不打折
$cashContext = new CashContext(new CashNormal());
break;
case "0.8": // 打八折
$cashContext = new CashContext(new CashRebate($type));
break;
}
echo "打折后的价格是: " . $cashContext->getResult($beforeTotal);
优化
现在我们在使用的时候需要去判断具体使用哪一个算法,也就是我们的 switch case,我们可以使用策略模式与简单工厂模式的结合来解决这个问题。
修改 CashContext
类:
<?php
/**
* Created by phpStorm.
* User: binwei
* Date: 2019/5/19
* Time: 20:57
*/
require_once "CashNormal.php";
require_once "CashRebate.php";
class CashContext
{
private $cashSuper;
/**
* 通过构造方法传入具体的收费策略
* CashContext constructor.
* @param $cashSuper
*/
public function __construct($type)
{
switch ($type) {
case "1": // 不打折
$this->cashSuper = new CashNormal();
break;
case "0.8": // 打八折
$this->cashSuper = new CashRebate($type);
break;
}
}
public function getResult($money)
{
return $this->cashSuper->acceptCash($money);
}
}
我们将具体实例化策略的过程放到 CashContext
的构造函数中。
使用:
<?php
/**
* Created by phpStorm.
* User: binwei
* Date: 2019/5/19
* Time: 21:03
*/
require_once "CashContext.php";
$beforeTotal = 1000; // 之前的总价
$type = "0.8";// 打八折
$cashContext = null; // strategy 对象的引用
$cashContext = new CashContext($type);
echo "打折后的价格是: " . $cashContext->getResult($beforeTotal);
结果一样,但是这让我们的使用更加简单。