门面模式

门面(Facade)模式,也叫外观模式,英文全称是 Facade Design Pattern。在 GoF 的《设计模式》一书中,门面模式是这样定义的:

Provide a unified interface to a set of interfaces in a subsystem. Facade Pattern defines a higher-level interface that makes the subsystem easier to use.

翻译成中文就是:门面模式为子系统提供一组统一的接口,定义一组高层接口让子系统更易用。

门面模式的结构

代码实现

子系统1 SubSystemOne.php

<?php
namespace DesignPatterns\Facade;
/**
 * 子系统1
 * Class SubSystemOne
 * @package DesignPatterns\Facade
 */
class SubSystemOne
{
    public function MethodOne()
    {
        echo "子系统1的方法\n";
    }
}

子系统2 SubSystemTwo.php

<?php
namespace DesignPatterns\Facade;
/**
 * 子系统2
 * Class SubSystemTwo
 * @package DesignPatterns\Facade
 */
class SubSystemTwo
{
    public function MethodTwo()
    {
        echo"子系统2的方法\n";
    }
}

子系统3 SubSystemThree.php

<?php
namespace DesignPatterns\Facade;
/**
 * 子系统3
 * Class SubSystemThree
 * @package DesignPatterns\Facade
 */
class SubSystemThree
{
    public function MethodThree()
    {
        echo "子系统3的方法\n";
    }
}

子系统4 SubSystemFour.php

<?php
namespace DesignPatterns\Facade;
/**
 * 子系统4
 * Class SubSystemFour
 * @package DesignPatterns\Facade
 */
class SubSystemFour
{
    public function MethodFour()
    {
        echo "子系统4的方法\n";
    }
}

门面类 Facade.php

<?php
namespace DesignPatterns\Facade;
/**
 * 门面类
 * Class Facade
 * @package DesignPatterns\Facade
 */
class Facade
{
    private $systemOne;
    private $systemTwo;
    private $systemThree;
    private $systemFour;
    public function __construct()
    {
        $this->systemOne = new SubSystemOne();
        $this->systemTwo = new SubSystemTwo();
        $this->systemThree = new SubSystemThree();
        $this->systemFour = new SubSystemFour();
    }
    public function methodA()
    {
        echo "方法组A() ---\n";
        $this->systemOne->methodOne();
        $this->systemThree->methodThree();
    }
    public function methodB()
    {
        echo "方法组B() ---\n";
        $this->systemTwo->methodTwo();
        $this->systemFour->methodFour();
    }
}

运行Client.php

<?php
namespace DesignPatterns\Facade;
require __DIR__.'/../vendor/autoload.php';
class Client
{
    public function run()
    {
        $facade = new Facade();
        $facade->methodA();
        echo '<br>';
        $facade->methodB();
    }

}
$worker = new Client();
$worker->run();

运行结果:

从代码上看,如果没有门面类,客户端只能直接与子系统进行交互,子系统如果变化,很可能将会影响到客户端的调用。而子系统在不断优化重构中,可能会产生更多更小的类。这对于客户端来说似乎要记住太多的接口。使用门面模式增加门面类后,减少了客户端与子系统之间的耦合,也提高了可维护性。

门面模式的应用场景

首先,在设计初期阶段,应该要有意识的将不同的两个层分离,层与层之间建立外观Facade;其次,在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂,增加外观Facade可以提供一个简单的接口,减少它们之间的依赖;另外在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,为新系统开发一个外观Facade类,来提供设计粗糙或高度复杂的遗留代码的比较清晰简单的接口,让系统与Facade对象交互,Facade与遗留代码交互所有复杂的工作

github示例:https://github.com/yangpanyao/design-patterns/tree/master/Facade

Last modification:July 27th, 2020 at 06:32 pm