策略模式,什么是策略模式,定义了算法族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。
下面我们就用鸭子来诠释一下策略模式,鸭子有两种行为呱呱叫和飞,但是并不是所有的鸭子都会呱呱叫和飞,所以我们把这两个赋予变化的行为提取出来。
<?php abstract class Duck{ public $flyBehavior; public $quackBehavior; public function __construct(){ } public function performFly(){ $this->flyBehavior->fly(); } public function performQuack(){ $this->quackBehavior->quack(); } public function setFlyBehavior(FlyBehavior $fb){ $this->flyBehavior = $fb; } public function setQuackBehavior(QuackBehavior $qb){ $this->quackBehavior = $qb; } public function swim(){ } abstract function display(); } interface FlyBehavior{ public function fly(); } class FlywithWings implements FlyBehavior{ public function fly(){ echo "i'm flying!\n"; } } class FlyNoWay implements FlyBehavior{ public function fly(){ echo "i can't fly.\n"; } } class FlyRocketPowered implements FlyBehavior{ public function fly(){ echo "i'm flying with a rocket!\n"; } } interface QuackBehavior{ public function quack(); } class Quack implements QuackBehavior{ public function quack(){ echo "quack!\n"; } } class MuteQuack implements QuackBehavior{ public function quack(){ echo "silence\n"; } } class MallardDuck extends Duck{ public function __construct(){ $this->quackBehavior = new Quack(); $this->flyBehavior = new FlyNoWay(); } public function display(){ echo "i'm a real mallar duck\n"; } } $duck = new MallardDuck; $duck->performFly(); $duck->setFlyBehavior(new FlyRocketPowered); $duck->performFly(); ?>
从上面的代码可以看出我们把鸭子抽象出来,而飞行行为和呱呱叫行车以接口的形式,设计的原则是多用组合,少用继承,用上面的写法,相对弹性大点,不仅将算法封装成类,更可以“在运行时动态的改变行为”,只要组合行为对象符合正确的接口标准即可。