上一篇文章中大家應該有發現,在鴨子的類別中有包含兩個方法,分別是setQuackBehavior()
和 setFlyBehavior()
,
abstract class Duck{
public FlyBehavior $flyBehavior;
public QuackBehavior $quackBehavior;
function __construct(){}
abstract public function display();
function setFlyBehavior(FlyBehavior $flyAction){
$this -> flyBehavior = $flyAction;
}
function setQuackBehavior(QuackBehavior $quackAction){
$this -> quackBehavior = $quackAction;
}
function performFly(){
$this -> flyBehavior -> fly();
}
function performQuack(){
$this -> quackBehavior -> quack();
}
function swim(){
echo "All duck float!";
}
}
因為在我們會先在建構子去定義這隻鴨子的飛行跟叫聲,考量到之後可能需要更改他們這些行為,用一個比較dynamic的方法去做,這樣也不必真的去修改到該鴨子類別的建構子,更改DuckSimulator.php
如下:
header('Content-type: text/plain');
include "./Class/Duck.php";
$mallard = new MallardDuck();
$mallard -> display();
echo "fly behavior before setting: ";
$mallard -> performFly();
$mallard -> setFlyBehavior(new FlyRocketPowered);
echo "fly behavior after setting: ";
$mallard -> performFly();
從output可以看到鴨子飛行的差異:
書中有留給大家另一個範例,我把程式碼放在github,有興趣的話可以看看喔
多多把物件之間複合,不要想著繼承 (Favor composition over inheiritance):
這個精神會貫穿這本書,而且被運用在很多種設計模式中,不過在不同的設計模式中也會有各自的缺點。
策略模式
performFly()
呼叫飛行,而飛行介面透過不同類別去實作不同內容。《深入淺出設計模式 (Head First Design Patterns) 》
物件導向程式設計:為何說composition優於inheritance?
https://tw.twincl.com/programming/*662v
策略模式
https://www.runoob.com/design-pattern/strategy-pattern.html
https://github.com/changtintin/Design-Pattern/tree/7f1a90c143945f3e6634e98fad92885a947664c5/Ch1/Duck
Disclaimer
因為讀的是原文版,所以難免會有翻譯詞不達意或是專有名詞上的差異,有錯誤的話歡迎在留言區一起交流!