[toc]
## 举个例子
> 新生入学, 不知所措? 学长迎新, 一条龙服务
> 不熟悉学校? 找到学长, 照样把事儿办了
> 也可以理解成对接
## 代码示例
```php
<?php
// 入学报到
class Register {
public function phpRegister($name) {
echo "活动中心:" . $name . "同学报到成功!" . PHP_EOL;
}
}
// 缴费
class Payment {
public function pay($name, $money) {
echo "缴费中心:" . "收到" . $name . "同学" . strval($money) . "元付款,缴费成功!" . PHP_EOL;
}
}
// 宿舍管理中心(生活中心)
class DormitoryManagementCenter {
public function provideLivingGoods($name) {
echo "生活中心:" . $name . "同学的生活用品已发放。" . PHP_EOL;
}
}
// 宿舍
class Dormitory {
public function meetRoommate($name) {
echo "宿 舍:" . "大家好!这是刚来的" . $name . "同学,是你们未来需要共度四年的室友!相互认识一下……" . PHP_EOL;
}
}
// 迎新志愿者
class Volunteer {
protected $name;
protected $register;
protected $payment;
protected $lifeCenter;
protected $dormintory;
public function __construct($name) {
$this->name = $name;
$this->register = new Register();
$this->payment = new Payment();
$this->lifeCenter = new DormitoryManagementCenter();
$this->dormintory = new Dormitory();
}
public function welcomeFreshmen($name) {
echo "你好," . $name . "同学! 我是新生报到的志愿者" . $this->name . ",我将带你完成整个报到流程。" . PHP_EOL;
$this->register->phpRegister($name);
$this->payment->pay($name, 10000);
$this->lifeCenter->provideLivingGoods($name);
$this->dormintory->meetRoommate($name);
}
}
// 测试
$volunteer = new Volunteer("Frank");
$volunteer->welcomeFreshmen("Tony");
```
```
D:\soft\php72\php.exe D:\project\php_dp\index.php
你好,Tony同学! 我是新生报到的志愿者Frank,我将带你完成整个报到流程。
活动中心:Tony同学报到成功!
缴费中心:收到Tony同学10000元付款,缴费成功!
生活中心:Tony同学的生活用品已发放。
宿 舍:大家好!这是刚来的Tony同学,是你们未来需要共度四年的室友!相互认识一下……
Process finished with exit code 0
```
## 代码说明
1. 迎新志愿者陪同并帮助入学新生完成报到登记、缴纳学费、领日用品、入住宿舍等一系列的报到流程。
2. 新生不用知道具体的报到流程,不用去寻找各个场地;只要跟着志愿者走,到指定的地点,根据志愿者的指导,完成指定的任务即可。
3. 志愿者虽然不是直接提供这些报到服务,但也相当于间接提供了报到登记、缴纳学费、领日用品、入住宿舍等一条龙的服务,帮新生减轻了不少麻烦和负担。
4. 在这里志愿者就相当于一个对接人,将复杂的业务通过一个对接人来提供一整套统一的(一条龙式的)服务,让用户不用关心内部复杂的运行机制。
## 什么是外观模式?
> 为子系统中的一组接口提供一个一致的界面称为外观模式
> 外观模式定义了一个高层接口,这个接口使得这一子系统更容易使用。
> 外观模式的核心思想:用一个简单的接口来封装一个复杂的系统,使这个系统更容易使用。
![](https://box.kancloud.cn/5e596f1b833a8591f6efbabee63d3905_486x510.png)
## 设计要点
1. **外观角色(Facade)**: 为子系统封装统一的对外接口,如同子系统的一个门面。这个类一般不负责具体的业务逻辑,只是一个委托类,具体的业务逻辑由子系统完成。
1. **子系统(SubSystem)**: 由多个类组成的具有某一特定功能的子系统。可以是第三方库,也可以是自己的基础库,还可能是一个子服务,为整个系统提供特定的功能或服务。
## 优缺点
**优点**:
1. 实现了子系统与客户端之间的松耦合关系,这使得子系统的变化不会影响到调用它的客户端。
1. 简化了客户端对子系统的使用难度,客户端(用户)无须关心子系统的具体实现方式,而只需要和外观进行交互即可。
1. 为不同的用户提供了统一的调用接口,方便了系统的管理和维护。
**缺点**:
1. 因为统一了调用的接口,降低了系统功能的灵活性。
## 应用场景
1. 当要为一个复杂子系统提供一个简单接口时;
1. 客户程序与多个子系统之间存在很大的依赖性,引入外观类将子系统与客户以及其他子系统解耦,可以提高子系统的独立性和可移植性;
1. 在层次化结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。