08、PHP 设计模式-外观模式

外观模式

外观模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。

模式结构

外观模式包含如下角色:

  • Facade: 外观角色
  • SubSystem:子系统角色

结构图

 

PHP代码实现

<?php

// 子系统1
class Subsystem1 {
    public function operation1(): string {
        return "Subsystem1: Ready!\n";
    }

    // ...

    public function operationN(): string {
        return "Subsystem1: Go!\n";
    }
}

// 子系统2
class Subsystem2 {
    public function operation1(): string {
        return "Subsystem2: Get ready!\n";
    }

    // ...

    public function operationZ(): string {
        return "Subsystem2: Fire!\n";
    }
}

// 外观类
class Facade {
    protected $subsystem1;
    protected $subsystem2;

    // 外观类需要知道所有子系统的类和方法,从而能将客户端的请求代理给相应的子系统对象
    public function __construct(Subsystem1 $subsystem1 = null, Subsystem2 $subsystem2 = null) {
        $this->subsystem1 = $subsystem1 ?: new Subsystem1;
        $this->subsystem2 = $subsystem2 ?: new Subsystem2;
    }

    // 外观方法提供了简单的接口给外部使用,并委托调用子系统的方法
    public function operation(): string {
        $result = "Facade initializes subsystems:\n";
        $result .= $this->subsystem1->operation1();
        $result .= $this->subsystem2->operation1();
        $result .= "Facade orders subsystems to perform the action:\n";
        $result .= $this->subsystem1->operationN();
        $result .= $this->subsystem2->operationZ();
        return $result;
    }
}

// 客户端代码与复杂的子系统对象直接交互要依赖于很多不同的对象。
// 外观类提供一个简单的接口到复杂的子系统逻辑。
function clientCode(Facade $facade) {
    // ...
    echo $facade->operation();
    // ...
}

// 子系统可以直接通过外观类接口与客户端代码交互。
$subsystem1 = new Subsystem1();
$subsystem2 = new Subsystem2();
$facade = new Facade($subsystem1, $subsystem2);
clientCode($facade);