zoukankan      html  css  js  c++  java
  • PHP设计模式之策略模式

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

    举例:超市促销活动,分别有原价,5折,满300减50,使用策略模式……

    通过抽象方法形式

    <?php
    /**
     * 抽象活动算法类
     */
    namespace strategy;
    
    abstract class StrategyAbstract
    {
        /**
         * 具体活动算法方法
         * @return mixed
         */
        public abstract function doAction($money);
    }
    <?php
    /**
     * 满减算法产品类
     */
    namespace strategy;
    
    class ManJianStrategy extends StrategyAbstract
    {
        public function doAction($money)
        {
            echo '满减算法:原价'. $money .'元';
        }
    }
    <?php
    /**
     * 打折算法产品类
     */
    namespace strategy;
    
    class DaZheStrategy extends StrategyAbstract
    {
        /**
         * 具体算法实现
         * @param $money
         * @return mixed|void
         */
        public function doAction($money)
        {
            echo '打折算法:原价'. $money .'元';
        }
    }
    <?php
    /**
     * 策略工厂类
     */
    namespace strategy;
    
    class StrategyFind
    {
        private $strategy_mode;
    
        /**
         * 初始时,传入具体的策略对象
         * @param $mode
         */
        public function __construct($mode)
        {
            $this->strategy_mode = $mode;
        }
    
        /**
         * 执行打折算法
         * @param $money
         */
        public function get($money)
        {
            $this->strategy_mode->doAction($money);
        }
    }
    <?php
    //入口文件
    namespace strategy;
    
    include '../autoload.php';
    // 满减折算
    $mode1 = new StrategyFind(new ManJianStrategy());
    $mode1->get(100);
    
    echo '<br>';
    
    // 满减活动
    $mode2= new StrategyFind(new DaZheStrategy());
    $mode2->get(100);

    策略模式就是使用封装一个公共抽象算法,每个算法(比如,打折算法,满减算法)实现这个接口,然后搞个策略工厂类来调用这些算法。

    举例2: 假如有一个电商网站系统,针对男性女性用户要各自跳转到不同的商品类目,并且所有的广告位展示不同的广告。在传统的代码中,都是在系统中加入各种if else的判断,硬编码的方式。如果有一天增加了一种用户,就需要改写代码。使用策略模式,如果新增加一种用户类型,只需要增加一种策略就可以。其他所有的地方只需要使用不同的策略就可以。 


    首先声明策略的接口文件,约定了策略的包含的行为。然后,定义各个具体的策略实现类。

    通过封装接口形式 

    UserStrategy.php 文件
    
    <?php
    /*
     * 声明策略文件的接口,约定策略包含的行为。
     */
    interface UserStrategy
    {
        function showAd();
        function showCategory();
    }
    FemaleUser.php 女性用户女装
    
    <?php
    
    class FemaleUser implements UserStrategy
    {
        function showAd(){
            echo "2016冬季女装";
        }
        function showCategory(){
            echo "女装";
        }
    }
    MaleUser.php  电子产品类
    <?php
    
    class MaleUser implements UserStrategy
    {
        function showAd(){
            echo "IPhone6s";
        }
        function showCategory(){
            echo "电子产品";
        }
    }
    Page.php//入口文件执行
    <?php
    
    class Page
    {
        protected $strategy;
        function index(){
            echo "AD";
            $this->strategy->showAd();
            echo "<br>";
            echo "Category";
            $this->strategy->showCategory();
            echo "<br>";
        }
        function setStrategy(UserStrategy $strategy){
            $this->strategy=$strategy;
        }
    }
    
    $page = new Page();
    if(isset($_GET['male'])){
        $strategy = new MaleUser();
    }else {
        $strategy = new FemaleUser();
    }
    $page->setStrategy($strategy);
    $page->index();

    通过以上方式,可以发现,在不同用户登录时显示不同的内容,但是解决了在显示时的硬编码的问题。如果要增加一种策略,只需要增加一种策略实现类,然后在入口文件中执行判断,传入这个类即可。实现了解耦,实现依赖倒置和控制反转
    通过接口的方式,使得类和类之间不直接依赖。在使用该类的时候,才动态的传入该接口的一个实现类。如果要替换某个类,只需要提供一个实现了该接口的实现类,通过修改一行代码即可完成替换。

  • 相关阅读:
    最长不下降子序列 从O(n)到O(nlogn)
    【NOIP1999】【洛谷P1020】导弹拦截
    【NOI2001】【洛谷P2024】食物链
    【2017中国大学生程序设计竞赛
    【2017中国大学生程序设计竞赛
    【NOIP】【洛谷P1029】最大公约数和最小公倍数问题
    【NOIP2009】【洛谷P1072】Hankson 的趣味题
    C++模板(2)
    Java中跳出循环的方法
    localeCompare() 方法实现中文的拼音排序
  • 原文地址:https://www.cnblogs.com/cutcop/p/13207751.html
Copyright © 2011-2022 走看看