php-门面模式实现
概述
门面模式(外观模式)(Facade Pattern):外部与子系统的通信必须通过一个统一的门面对象进行。为子系统提供了一个一直的对象接口,门面模式定义了一个高层接口,这个接口使得子系统使用起来更加方便。
这里我们还是以摩托制造厂为例,现在有一个业务场景,我们需要针对踏板摩托车开通线上个人定制业务。我们希望客户可以定制自己的摩托车,从付款到生产制造以及交付一条龙服务。
模式结构
- MotorcycleProduce-摩托组装抽象类:建立摩托组装标准工艺
- MotocycleProduct -摩托车产品本身
- MotorcycleScooter-踏板摩托车组装
- Director-安排生产线开始组装摩托
- Order-订单类
- Pay-支付类
- MotorFace-摩托门面
UML图例
代码实例
<?php
namespace Facade;
//抽象类-定义生产摩托车流水线标准 Target 目标类
interface MotorcycleProduce
{
//发动机方法
public function addEngine();
//车身方法
public function addBody();
//车轮方法
public function addWhell();
//获取摩托
public function getMotor();
//自定义部分
public function addOther(string $other);
}
//摩托车产品本身
class MotocycleProduct{
private $motor = [
"engine"=>"",
"body"=>"",
"whell"=>"",
"bodyColor"=>"blue",
"other"=>""
];
//新增发动机零部件
public function addEngine($engine){
$this->motor["engine"] = $engine;
}
public function addBody($body){
$this->motor["body"] = $body;
}
public function addWhell($whell){
$this->motor["whell"] = $whell;
}
public function addOther($other){
$this->motor["other"] = $other;
}
//获取完整摩托对象
public function getMotor(){
return $this->motor;
}
}
class MotorcycleScooter implements MotorcycleProduce
{
private $motor;
public function __construct()
{
$this->motor = new MotocycleProduct();
}
function addEngine()
{
$this->motor->addEngine("踏板摩托-发动机已装好");
}
function addBody()
{
$this->motor->addBody("踏板摩托-车身已装好");
}
function addWhell()
{
$this->motor->addWhell("踏板摩托-车轮已装好");
}
function addOther($other){
$this->motor->addOther($other);
}
function getMotor()
{
return $this->motor->getMotor();
}
}
//安排生产线开始组装摩托
class Director{
public function assemble(MotorcycleProduce $motorcycleProduce,$other){
$motorcycleProduce->addEngine();
$motorcycleProduce->addBody();
$motorcycleProduce->addWhell();
$motorcycleProduce->addOther($other);
}
}
class Order{
public function run(){
echo "已下单<br>";
}
}
class Pay{
public function run(){
echo "已支付<br>";
}
}
class MotorFace{
protected $order;
protected $pay;
protected $motorScooter;
protected $director;
public function __construct()
{
$this->order = new Order;
$this->pay = new Pay;
$this->motorScooter = new MotorcycleScooter;
$this->director = new Director();
}
public function buy($other){
$this->order->run();
$this->pay->run();
$this->director->assemble($this->motorScooter,$other);
}
public function getMotor(){
return $this->motorScooter->getMotor();
}
}
$motorFace = new MotorFace;
$motorFace->buy("麻烦帮我把排气管改一下,声音特别炸裂的那种,我去炸街,正所谓。鬼火一响,黄金万两");
$motor = $motorFace->getMotor();
var_dump($motor);
模式分析
根据“单一职责原则”,在软件中将一个系统划分为若干的子系统有利于降低整个系统的复杂性,而门面模式则是为多个子系统提供一个简单而单一的入口
门面模式也是“迪米特法原则”的体现,通过引入一个新的门面类可以降低原有系统的复杂度,同时降低客户类与字类的耦合度。
门面模式提高了客户端调用的便捷性,客户无需关心系统的工作细节,通过门面角色即可调用相关的功能
优缺点
门面模式的优点
- 对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易。通过引入门面模式,客户代码将变得很简单,与之关联的对象也很少。
- 实现了子系统与客户之间的松耦合关系,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整门面类即可。
- 降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到门面对象。
- 只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类。
门面模式的缺点
- 不能限制客户使用子系统类,如果对客户调用子系统类做太多的限制则会减少可变形和灵活性
- 不引入抽象门面类的情况下,增加新的子系统可能需要修改门面模式或客户端的代码,违背了“开闭原则”
适用环境
在以下情况下可以使用门面模式:
- 为一个复杂的子系统提供一个简单的接口,该接口可以满足大多数的用户需求,而且用户也可以越过门面模式直接访问子系统。
- 在层次结构中,可以使用门面模式定义系统中的每一层入口,层与层之间不直接产生联系。而通过门面模式建立联系。降低耦合度。
- 客户程序与多个子系统之间存在于很大的依赖性。引入门面模式将子系统与客户及其他子类解耦,可以提供各层以及子系统独立性和可移植性。
关注微信公众号(yuantanphp) | |
---|---|
回复关键字 设计模式 可获取以下材料 《设计模式:可复用面向对象软件的基础》pdf版. php设计模式23种实例实现php源码 | ![]() |