Skip to content

外观模式又称过程模式是一种结构模式,他通过向现有系统添加一个供客户端访问的接口,完成了对现有系统复杂性的隐藏。

外观模式的设计往往只涉及一个层或者一个子系统,通过为这个层或者子系统创建一个单一的访问入口从而隐藏了系统的复杂性。

这样做的好处是显而易见的:

  1. 这样的处理方式有助于实现项目的不同部分的分离。

  2. 对于客户端开发者来说无需关注细节的实现,调用代码变得非常的简洁使用起来非常的方便。

  3. 客户端的调用只在一个地方使用,避免了客户端调用不正确的复杂的系统内部方法而引起的错误,减少了系统出错的可能性。 然而这样的设计也并不是完美无缺的,外观模式的设计违反了累的开闭原则,当类的设计需要修改时会显得非常的麻烦。

外观模式的使用场景:(引自百度百科)

  1. 设计初期阶段,应该有意识的将不同层分离,层与层之间建立外观模式。

  2. 开发阶段,子系统越来越复杂,增加外观模式提供一个简单的调用接口。

  3. 维护一个大型遗留系统的时候,可能这个系统已经非常难以维护和扩展,但又包含非常重要的功能,为其开发一个外观类,以便新系统与其交互。

简单的外观模式的示例:

php
<?php
class ProductFacade
{
    private $file = '';
    private $product = [];

    public function __construct($file)
    {
        $this->file = $file;
        $this->compile();
    }

    /**
     * 类的内部处理函数
     */
    public function compile()
    {
        $lines = $this->getProductFileLines($this->file);
        foreach ($lines as $line) {
            $id = $this->getIdFromLine($line);
            $name = $this->getNameFromLine($line);
            $this->product[$id] = $this->getProductObjectFromId($id, $name);
        }
    }

    /**
     * 获取所有的产品
     * @return array
     */
    public function getProducts()
    {
        return $this->product;
    }

    /**
     * 获取指定的产品
     * @param $id
     * @return mixed
     */
    public function getProduct($id)
    {
        return $this->product[$id];
    }

    public function getProductFileLines($file)
    {
        return file($file);
    }

    public function getProductObjectFromId($id, $productName)
    {
        return new Product($id, $productName);
    }


    public function getNameFromLine($line)
    {
        if (preg_match("/.*-(.*)\s\d+/", $line, $array)) {
            return str_replace('_', ' ', $array[1]);
        }
        return '';
    }

    public function getIdFromLine($line)
    {
        if (preg_match("/^(\d(1,3))-/", $line, $array)) {
            return $array[1];
        }
        return -1;
    }

}

class Product
{
    public $id;
    public $name;

    public function __construct($id, $name)
    {
        $this->id = $id;
        $this->name = $name;
    }
}