博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
策略模式
阅读量:5081 次
发布时间:2019-06-13

本文共 3398 字,大约阅读时间需要 11 分钟。

需求:银行收银系统,营业员根据客户所购买商品的单价和数量,向客户收费。其中有几种模式:原价模式、打折模式、满减模式,每一种商品在结账的时候都要选择一种模式进行对应,且模式中的值有不同。

根据需求,准备以下不同的类。

 

一、抽象策略接口

interface Strategy{    public function getResult();}

 

二、原价策略类

class Cash implements Strategy{    protected $price;    protected $amount;    public function __construct($price,$amount)    {        $this->price = $price;        $this->amount = $amount;    }    public function getResult()    {        return $this->price * $this->amount;    }}

 

三、打折策略类

class Discount implements Strategy{    protected $price;    protected $amount;    protected $rate;    public function __construct($price,$amount,$rate)    {        $this->price = $price;        $this->amount = $amount;        $this->rate = $rate;    }    public function getResult()    {        return $this->price * $this->amount * $this->rate;    }}

 

四、满减策略类

class Rebate implements Strategy{    protected $price;    protected $amount;    protected $rule;    public function __construct($price,$amount,$rule)    {        $this->price = $price;        $this->amount = $amount;        $this->rule = $rule;    }    public function getResult()    {        $money = $this->price * $this->amount;        $result = self::_minusMoney($money,$this->rule);        return $result;    }    /**     * 计算满减后的金额     * @param $money     * @param $rule     * @return mixed     */    private function _minusMoney($money,$rule)    {        $result = $money - floor($money/$rule[0]) * $rule[1];        return $result;    }}

 

五、上下文类

class Context{    private $strategy;    public function __construct(Strategy $strategy)    {        $this->strategy = $strategy;    }    public function countResult()    {        return $this->strategy->getResult();    }}

 

六、简单工厂类

class Factory{    public static function createObj($params)    {        $obj = null;        $price = $params['price'];        $amount = $params['amount'];        $discount = isset($params['discount'])?$params['discount']:1;        $rule = isset($params['rule'])?$params['rule']:[];        switch($params['type'])        {            case 1:                $obj = new Cash($price,$amount);                break;            case 2:                $obj = new Discount($price,$amount,$discount);                break;            case 3:                $obj = new Rebate($price,$amount,$rule);                break;        }        return $obj;    }}

 

七、测试代码如下:

$result = 0;$params = [    'type'=>1,    'price'=>12,    'amount'=>5];$strategy_cash = new Context(Factory::createObj($params));echo '原价商品,费用为:',$strategy_cash->countResult();$result += $strategy_cash->countResult();$params = [    'type'=>2,    'price'=>12,    'amount'=>5,    'discount'=>0.8];$strategy_discount = new Context(Factory::createObj($params));echo '打折商品,费用为:',$strategy_discount->countResult();$result += $strategy_cash->countResult();$params = [    'type'=>3,    'price'=>120,    'amount'=>5,    'rule'=>[300,40]];$strategy_rebate = new Context(Factory::createObj($params));echo '满减商品,费用为:',$strategy_rebate->countResult();$result += $strategy_cash->countResult();echo '总费用为:',$result;

 

八、UML图如下:

 

总结:

1. 策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。

2. 当不同的行为堆砌在一个类中时,就很难避免使用条件语句来选择合适的行为。将这些行为封装在一个个独立的Strategy类中,可以在使用这些行为的类中消除条件语句。

3. 策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。

转载于:https://www.cnblogs.com/gspsuccess/p/9231139.html

你可能感兴趣的文章
magento 自定义订单前缀或订单起始编号
查看>>
ACM_拼接数字
查看>>
计算机基础作业1
查看>>
Ubuntu 深度炼丹环境配置
查看>>
C#中集合ArrayList与Hashtable的使用
查看>>
从一个标准 url 里取出文件的扩展名
查看>>
map基本用法
查看>>
poj-1163 动态规划
查看>>
Golang之interface(多态,类型断言)
查看>>
Redis快速入门
查看>>
BootStrap---2.表格和按钮
查看>>
Linear Algebra lecture 2 note
查看>>
CRC计算模型
查看>>
Ajax之404,200等查询
查看>>
Aizu - 1378 Secret of Chocolate Poles (DP)
查看>>
csv HTTP简单表服务器
查看>>
OO设计的接口分隔原则
查看>>
数据库连接字符串大全 (转载)
查看>>
java类加载和对象初始化
查看>>
对于负载均衡的理解
查看>>