设计模式——策略模式

策略模式是一种算法的封装,把算法本身和使用分割开来。一个抽象类,每个具体算法都是这个抽象类的具体实现,然后在context中定义一个算法类,并且赋值为传进来的算法对象,不同的算法传入不同的算法对象。各个算法之间位置相等,可以相互替换。

策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。

这个模式涉及到三个角色:

环境(Context)角色:持有一个Strategy的引用。

抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。

具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。

意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

主要解决:在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。

何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。

如何解决:将这些算法封装成一个一个的类,任意地替换。

关键代码:实现同一个接口。

应用实例:1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。2、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。

优点:1、算法可以自由切换。2、避免使用多重条件判断。3、扩展性良好。

缺点:1、策略类会增多。2、所有策略类都需要对外暴露。

使用场景:1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。2、一个系统需要动态地在几种算法中选择一种。3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。

注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。

假设现在要设计一个贩卖各类书籍的电子商务网站的购物车系统。一个最简单的情况就是把所有货品的单价乘上数量,但是实际情况肯定比这要复杂。比如,本网站可能对所有的高级会员提供每本20%的促销折扣;对中级会员提供每本10%的促销折扣;对初级会员没有折扣。

  根据描述,折扣是根据以下的几个算法中的一个进行的:

  算法一:对初级会员没有折扣。

  算法二:对中级会员提供10%的促销折扣。

  算法三:对高级会员提供20%的促销折扣。

<?php
//抽象策略-会员-Strategy
abstract class MemberStrategy{
    abstract function CalcuPrice($Price,$Number);
}

//具体策略-ConcreteStrategy
//初级会员
class PrimaryMemberStrategy extends MemberStrategy{
    function CalcuPrice($Price,$Number)
    {
        echo "PrimaryMember do not enjoy discount. So final consumption is ".$Price*$Number;
    }
}

//中级会员
class IntermediateMemberStrategy extends MemberStrategy{
    function CalcuPrice($Price,$Number)
    {
        echo "Primary Member enjoy 10% discount. So final consumption is ".$Price*$Number*0.9;
    }
}

//高级会员
class AdvancedMemberStrategy extends MemberStrategy{
    function CalcuPrice($Price,$Number)
    {
        echo "Advanced Member enjoy 20% discount. So final consumption is ".$Price*$Number*0.8;
    }
}

//价格类-Context
class Price{
    private $Member;
    function __construct(MemberStrategy $Member)
    {
        $this->Member = $Member;
    }
    function CalcuPrice($Price,$Number)
    {
        $this->Member->CalcuPrice($Price, $Number);
    }
}

//调用
$PrimaryMember = new PrimaryMemberStrategy();
$IntermediateMember = new IntermediateMemberStrategy();
$AdvancedMember = new AdvancedMemberStrategy();

//传入不同的策略对象,得到不同的结果
$Price = new Price($PrimaryMember);
$Price->CalcuPrice(68,2);

$Price = new Price($IntermediateMember);
$Price->CalcuPrice(68,2);

$Price = new Price($AdvancedMember);
$Price->CalcuPrice(68,2);

?>

    原文作者:二月十六
    原文地址: https://blog.csdn.net/sinat_28984567/article/details/79839877
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞