设计模式之策略模式PHP实现

1、策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

2、例子类图概览:

  

 

3、假设我们需要实现一款鸭子游戏,鸭子们在河里一遍游泳戏水,一遍呱呱叫。鸭子的种类很多,实际生活中的鸭子、模型鸭、火箭鸭等等,有些鸭子会飞会叫,有些鸭子既不会飞也不会叫。这时候如果我们光用类的继承来实现,就是导致部分不会飞的鸭子也拥有了会飞的方法,这种bug,我们可以通过类与接口组合模式实现。当我们想要在程序运行过程中动态修改鸭子的行为,这时候就可以使用策略模式实现,具体实现代码如下:

1)首先我们需要一个鸭子抽象基类:Duck.php

<?php
/**
 * 鸭子基础类
 * Class Duck
 */

abstract class Duck{
    public $flyBehavior; //飞行行为接口实现对象
    public $quackBehavior; //呱呱叫行为接口实现对象

    /**
     * 让鸭子飞
     */
    public function performFly(){
        $this->flyBehavior->fly();
    }

    /**
     * 让鸭子叫
     */
    public function performQuack(){
        $this->quackBehavior->quack();
    }

    /**
     * 设置鸭子的飞行行为
     * @param FlyBehavior $flyBehavior
     */
    public function setFlyBehavior(FlyBehavior $flyBehavior){
        $this->flyBehavior = $flyBehavior;
    }

    /**
     * 设置鸭子的呱呱叫行为
     * @param QuackBehavior $quackBehavior
     */
    public function setQuackBehavior(QuackBehavior $quackBehavior){
        $this->quackBehavior = $quackBehavior;
    }
}

2)鸭子飞行行为接口:FlyBehavior.php

<?php

/**
 * 飞行接口
 * Interface FlyBehavior
 */
interface FlyBehavior{
    public function fly();
}

3)鸭子飞行行为具体实现类:FlyNoWay.php,FlyWithWings.php,FlyWithRocket.php

<?php

/**
 * 不会飞行为实现
 * Class FlyNoWay
 */
class FlyNoWay implements  FlyBehavior{
    public function fly()
    {
       echo 'I can not fly\n';
    }
}
<?php

/**
 * 用翅膀飞行为实现
 * Class FlyWithWings
 */
class FlyWithWings implements FlyBehavior{
    public function  fly()
    {
        echo 'I can fly with wings\n';
    }
}
<?php

/**
 * 用火箭飞行为实现
 * Class FlyWithRocket
 */
class FlyWithRocket implements FlyBehavior{
    public function  fly()
    {
        echo 'I can fly with rocket\n';
    }
}

4)鸭子呱呱叫行为接口:QuackBehavior.php

<?php

/**
 * 鸭叫接口
 * Interface QuackBehavior
 */
interface QuackBehavior{
    public function quack();
}

5)鸭子呱呱叫行为具体实现类:MuteQuack.php  Quack.php

<?php

/**
 * 鸭不会叫实现
 * Class MuteQuack
 */
class MuteQuack implements QuackBehavior{
    public function quack()
    {
        echo 'I can not quack\n';
    }
}
<?php

/**
 * 鸭会叫
 * Class Quack
 */
class Quack implements QuackBehavior {
    public function quack()
    {
        echo "I can quack\n";
    }
}

6)模型鸭类:ModelDuck.php

<?php

/**
 * 模型鸭类 不会飞不会叫
 * Class ModelDuck
 */
class ModelDuck extends Duck{
    public function __construct()
    {
        $this->flyBehavior = new FlyNoWay();
        $this->quackBehavior = new MuteQuack();
    }
}

7)真是鸭子类:RealDuck.php

<?php

/**
 * 真正的鸭子实现 会飞会叫
 * Class RealDuck
 */
class RealDuck extends Duck{
    public function __construct()
    {
        $this->quackBehavior = new Quack();
        $this->flyBehavior = new FlyWithWings();
    }
}

8)代码调用实现:main.php

<?php
//模型鸭不会飞不会叫输出
$modelDuck = new ModelDuck();
$modelDuck->performFly();
$modelDuck->performQuack();

//真实的鸭子会飞会叫输出
$realDuck = new RealDuck();
$realDuck->performFly();
$realDuck->performQuack();

//动态切换鸭子行为
$realDuck->setFlyBehavior(new FlyWithRocket());
$realDuck->performFly();

9)最终输出:

"I can not fly"
"I can not quack"
"I can fly with wings"
"I can quack"
"I can fly with rocket"

 

posted @ 2019-05-12 18:01  cfYu  阅读(295)  评论(0编辑  收藏  举报