[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. 我们可以选择任意一种(实际场景肯定会选择最合适的)出行方式,并且可以方便更换出行方式
![](https://box.kancloud.cn/f0c25e25bcfbe1879e85cfb52b4535e9_504x293.png)
## 设计要点
**策略模式中主要三个角色,在设计策略模式时要找到并区分这些角色**:
1. **上下文环境(Context)**: 起着承上启下的封装作用,屏蔽上层应用对策略(算法)的直接访问,封装可能存在的变化。
1. **策略的抽象(Strategy)**: 策略(算法)的抽象类,定义统一的接口,规定每一个子类必须实现的方法。
1. **具备的策略**: 策略的具体实现者,可以有多个不同的(算法或规则)实现。
## 优缺点
**策略模式的优点**:
1. 算法(规则)可自由地切换。
1. 避免使用多重条件判断。
1. 方便拓展和增加新的算法(规则)。
**策略模式的缺点**:
1. 所有策略类都需要对外暴露。
## 应用场景
1. 如果一个系统里面有许多类,它们之间的区别仅在于有不同的行为,那么可以使用策略模式动态地让一个对象在许多行为中选择一种。
1. 一个系统需要动态地在几种算法中选择一种。
1. 设计程序接口时希望部分的内部实现由调用方自己实现。