策略模式,什麼是策略模式,定義了算法族,分別封裝起來,讓他們之間可以相互替換,此模式讓算法的變化獨立於使用算法的客戶。
下面我們就用鴨子來诠釋一下策略模式,鴨子有兩種行為呱呱叫和飛,但是並不是所有的鴨子都會呱呱叫和飛,所以我們把這兩個賦予變化的行為提取出來。
<?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(); ?>
從上面的代碼可以看出我們把鴨子抽象出來,而飛行行為和呱呱叫行車以接口的形式,設計的原則是多用組合,少用繼承,用上面的寫法,相對彈性大點,不僅將算法封裝成類,更可以“在運行時動態的改變行為”,只要組合行為對象符合正確的接口標准即可。