設計模式學習筆記 - 2
寫在前面
今日特餐:策略模式
接續上一篇筆記《設計模式學習筆記 - 1》,瞭解了基本的物件導向原則,
今天要正式進入設計模式的內容,未來每一篇的前言,都會先破題內容會涵蓋哪一個或哪一些設計模式,方便日後查找或要補充的時候,可以更快速的找到對應的內容。
以下正文:
STRATEGY 策略模式
可以定義和封裝一系列的演算法,並且讓它們是可替換/對調的。這個模式可以讓你在不影響用戶端的情況下獨立改變演算法。
換句話說,將可能會需要被替換的實作內容抽離出來,多經過一個interface介面來將實做面隔離開來,簡單的例子像是資料庫連線,可能會遇到開發使用mysql,但是實際要部屬的時候,客戶指定要用postgreSQL。
在不討論語法有不同的問題的前提下,若我們是在每個使用資料庫的地方,都有留下連線資料庫的語法,這個時候就需要把整個專案中的連線方式都一一改過。
但如果我們連線資料庫是透過同一個介面,那只要替換掉實做的方式,就可以很快的完成變更。
書上的設計謎題:
有一款冒險遊戲,要離開新手村展開冒險旅程之前,需要先選擇職業(角色),每個職業會使用的武器不同,武器的使用方式也不同,職業與武器的攻擊模式可以參考下圖:
每個職業在冒險的旅程中,可能會學到不同武器的使用方式,所以在每次戰鬥的時候,都應該保留可以選擇要使用的武器,呼叫useWeapon()方法,使怪物受傷。
角色抽象類別
1
2
3
4
5
6
7
8
9
10
11
12//>
Abstract class Character
{
public function setWeapon(WeaponBehavior $weaponBehavior) {
$this->weaponBehavior = $weaponBehavior;
}
protected function fight() {
//DO SOMETHING
}
}King
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23//>
class King extends Character
{
/** @var WeaponBehavior */
private $weaponBehavior;
public function __construct() {
echo "I am the King!";
echo PHP_EOL;
}
public function setWeapon(WeaponBehavior $weaponBehavior) {
$this->weaponBehavior = $weaponBehavior;
}
public function fight() {
$useWeapon = $this->weaponBehavior->useWeapon();
echo $useWeapon['action'];
echo PHP_EOL;
echo 'Cause Damage: ' . $useWeapon['damage'];
}
}WeaponBehavior Interface
1
2
3
4
5//>
Interface WeaponBehavior
{
public function useWeapon();
}SwordBehavior infrastructure
1
2
3
4
5
6
7
8
9
10//>
class SwordBehavior implements WeaponBehavior
{
public function useWeapon() {
$action = 'Swing A Sword';
$damage = 50;
return ['action' => $action, 'damage' => $damage];
}
}測試
1
2
3
4
5
6
7
8
9
10//>
$character = new King();
$weapon = new SwordBehavior();
$character->setWeapon($weapon);
$character->fight();
# 輸出結果
# I am the King!
# Swing A Sword
# Cause Damage: 50
以上簡單用角色-國王,武器-劍來作為範例,未來冒險家要出新手村的時候,就可以有一個選擇角色的機制,去實例化各個角色;
遇到怪物的時候,就可以根據角色會使用的武器,來作為攻擊的方法。
如果要擴大一點,可能還可以延伸變成每個角色使用武器所造成的傷害會不同,還可以熟練使用武器的方式等等,就可以在現有基礎下進行擴展及延伸。
今天的筆記-策略模式到這邊告一段落,如果有謬誤的地方,歡迎email 給我指正或來信討論,謝謝!