设计模式 - 门面模式(Facade Pattern,也叫外观模式)

简介

场景

  1. 将系统划分为若干个子系统有利于降低系统的复杂性,但是这会增加调用者的复杂性。通过引入 Facade 可以对调用者屏蔽系统内部子系统的细节。
  2. Java 中有多个日志库,例如 log4j、logback 等。此外,还有一个著名的日志门面库 SLF4j。需要打日志时,最佳做法是去调用 SLF4j,而不是直接调用 log4j 等具体的日志库。

电商企业

电商企业有订单部门、物流部门、结算部门。

当消费者打客服电话时,只跟客服代表通话,客服代表充当 Facade,代替客户获取相关子部门的信息。

分层的系统

对于复杂系统,分层设计可以提高灵活性和可替换性。

可以用外观模式定义系统中每一层的入口,使得层与层之间不直接产生联系,降低层之间的耦合度。

模式定义

外部与一个系统中所有子系统的通信必须通过一个统一的 Facade 对象进行,为子系统中的接口提供统一的界面,使子系统更加易用。

门面模式也叫外观模式。

模式特点

门面模式包含两个角色:

  • Facade:门面
  • SubSystem:子系统

门面模式

优点

  • 统一入口,客户端不需要了解系统细节,操作简单
  • 降低了子系统与客户之间的耦合关系,子系统内部实现变化时,不影响客户端

缺点

  • 用户可以绕过 Facade 门面类直接访问子系统,无法把控
  • 不引入抽象外观类时,增加新的子系统可能需要修改外观类或客户端,违背“开闭原则”

PHP 代码示例

<?php

class Facade {
    private $a;
    private $b;
    
    public function __construct() {
        $this->a = new SystemA();
        $this->b = new SystemB();
    }
    
    function wrapOperation() {
        $this->a->funcA();
        $this->b->funcB();
    }
}

class SystemA {
    public function funcA() {
        echo "funcA".PHP_EOL;
    }
}

class SystemB {
    public function funcB() {
        echo "funcB".PHP_EOL;
    }
}

echo '<pre>';

$facade = new Facade();
$facade->wrapOperation();

输出:

funcA
funcB

posted on 2018-07-17 19:01  kikajack  阅读(282)  评论(0编辑  收藏  举报