[toc]
## 舉個例子
**朋友聚餐, 晚八點, 交通方式不限...**
1. 隨著社會的發展、時代的進步,出行交通的方式可謂是越來越多樣
2. 除了共享單車、公交車、地鐵、快車(或出租車),也可以是自駕、電動車、平衡車,甚至都可以踏個輪滑、踩個滑板!
3. 采用什么交通方式并不重要,重要的是你能準時來共聚晚餐
## 代碼示例
```php
<?php
// 交通工具的抽象類
class IVehicle {
public function running() {
}
}
// 共享單車
class SharedBicycle extends IVehicle {
public function running() {
echo "騎共享單車(輕快便捷)";
}
}
// 快速公交
class ExpressBus extends IVehicle {
public function running() {
echo "坐快速公交(經濟綠色)";
}
}
// 快車
class Express extends IVehicle {
public function running() {
echo "打快車(快速方便)";
}
}
// 地鐵
class Subway extends IVehicle {
public function running() {
echo "坐地鐵(高效安全)";
}
}
// 參加聚餐的同學
class Classmate {
private $name;
private $vechicle;
public function __construct($name, $vechicle) {
$this->name = $name;
$this->vechicle = $vechicle;
}
public function attendTheDinner() {
echo $this->name . " ";
$this->vechicle->running();
echo " 來參加聚餐!" . PHP_EOL;
}
}
// 測試代碼
$sharedBicycle = new SharedBicycle();
$joe = new Classmate("Joe", $sharedBicycle);
$joe->attendTheDinner();
$helen = new Classmate("Helen", new Subway());
$helen->attendTheDinner();
$henry = new Classmate("Henry", new ExpressBus());
$henry->attendTheDinner();
$ruby = new Classmate("Ruby", new Express());
$ruby->attendTheDinner();
```
```
D:\soft\php72\php.exe D:\project\php_dp\index.php
Joe 騎共享單車(輕快便捷) 來參加聚餐!
Helen 坐地鐵(高效安全) 來參加聚餐!
Henry 坐快速公交(經濟綠色) 來參加聚餐!
Ruby 打快車(快速方便) 來參加聚餐!
Process finished with exit code 0
```
## 代碼說明
1. 我們可以選擇不同的出行方式去參加聚餐,可以騎共享單車,也可以坐公共汽車,亦或是踩一輛平衡車
2. 選用什么交通工具不重要,重要的是能夠實現我們的目標——準時到達聚餐的地點
3. 我們可以根據自己的實際情況進行選擇和更換不同的出行方式
4. 選擇不同的交通工具,就相當于選擇了不同的出行策略
## 什么是策略模式?
> 定義一系列算法,將每個算法都封裝起來,并且使他們之間可以相互替換。策略模式使算法可以獨立于使用它的用戶而變化。
1. 策略模式是對算法、規則的一種封裝。
2. 如上面的示例中,可以將不同的出行方式(采用的交通工具)理解成一種出行算法,
3. 將這些算法抽象出一個基類 IVehicle,并定義一系列的算法,共享單車(SharedBicycle)、快速公交(ExpressBus)、地鐵(Subway)、快車(Express)。
4. 我們可以選擇任意一種(實際場景肯定會選擇最合適的)出行方式,并且可以方便更換出行方式

## 設計要點
**策略模式中主要三個角色,在設計策略模式時要找到并區分這些角色**:
1. **上下文環境(Context)**: 起著承上啟下的封裝作用,屏蔽上層應用對策略(算法)的直接訪問,封裝可能存在的變化。
1. **策略的抽象(Strategy)**: 策略(算法)的抽象類,定義統一的接口,規定每一個子類必須實現的方法。
1. **具備的策略**: 策略的具體實現者,可以有多個不同的(算法或規則)實現。
## 優缺點
**策略模式的優點**:
1. 算法(規則)可自由地切換。
1. 避免使用多重條件判斷。
1. 方便拓展和增加新的算法(規則)。
**策略模式的缺點**:
1. 所有策略類都需要對外暴露。
## 應用場景
1. 如果一個系統里面有許多類,它們之間的區別僅在于有不同的行為,那么可以使用策略模式動態地讓一個對象在許多行為中選擇一種。
1. 一個系統需要動態地在幾種算法中選擇一種。
1. 設計程序接口時希望部分的內部實現由調用方自己實現。