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