门面模式,也叫外观模式。不管是门面还是外观,都是我们对外的媒介,就好像我们的脸面一样。所以,这个模式最大的特点就是要表现的“好看”。怎么说呢?一堆复杂的对象调用,自己都看蒙了,特别是对老系统进行升级维护的时候。用门面来把老系统的功能调用封装起来,在外面看来就和新系统一样,这就是门面模式的用途啦!

Gof类图及解释

GoF定义:为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

GoF类图

代码实现

class SubSystemOne
{
public function MethodOne()
{
echo '子系统方法一', PHP_EOL;
}
}
class SubSystemTwo
{
public function MethodTwo()
{
echo '子系统方法二', PHP_EOL;
}
}
class SubSystemThree
{
public function MethodThree()
{
echo '子系统方法三', PHP_EOL;
}
}
class SubSystemFour
{
public function MethodFour()
{
echo '子系统方法四', PHP_EOL;
}
}

定义四个或者N多个子系统,这个没什么好说的吧,可以想象是很多子系统,而且他们之间并不一定和这四个子系统一样的相似,有可能是千差万别的。

class Facade
{ private $subStytemOne;
private $subStytemTwo;
private $subStytemThree;
private $subStytemFour;
public function __construct()
{
$this->subSystemOne = new SubSystemOne();
$this->subSystemTwo = new SubSystemTwo();
$this->subSystemThree = new SubSystemThree();
$this->subSystemFour = new SubSystemFour();
} public function MethodA()
{
$this->subSystemOne->MethodOne();
$this->subSystemTwo->MethodTwo();
}
public function MethodB()
{
$this->subSystemOne->MethodOne();
$this->subSystemTwo->MethodTwo();
$this->subSystemThree->MethodThree();
$this->subSystemFour->MethodFour();
}
}

通过门面类将这些子系统包装起来,对外提供的只是门面新定义的方法。

$facade = new Facade();
$facade->MethodA();
$facade->MethodB();

客户端的调用就非常简单了,我们不用知道具体调用了哪些子系统,只需要知道门面的这些方法干什么了就行啦!

  • 门面模式就是这么的简单,而且只要是真实的在项目中做过开发的朋友一定在不知不觉中就已经使用过这个模式了
  • 当你需要为一个复杂子系统提供一个简单的接口时,门面模式就非常适用。同时,如果客户程序与抽象类的实现部分之间存在着很大的依赖性时,也可以引入门面模式来进行解耦,提高子系统的独立性和可维护性。另外就是你需要构建一个层次结构的子系统时,门面可以充当每层子系统的入口点
  • Laravel中的门面系统相信使用过框架的人一定都用过,比如:Cache::put()。在Laravel中,门面的实现使用了一个魔术方法__callStatic()。然后让对象的方法可以实现直接使用静态方法来进行调用。是不是很神奇。有兴趣的朋友可以翻翻源码,就在/Illuminate/Support/Facades/Facade.php中。
  • 划重点:三层结构或者MVC也是门面模式的体现哦。上面说了,门面模式适合分层子系统的维护。而三层结构、MVC、MVP、MVVM这些货,本质上都是为了分层,而分层的目的,就是为了降低系统的复杂性。

光卖我们的手机可不行,向X米一样做高科技的家电企业才是我们最终的目标。不过那么多的家电产品我们可生产不过来,于是,我们决定做一个商城(Facade)让一些质量非常好的商家加入我们的阵营,将他们的产品(SubSystem)放到商城中一起卖。当然,这些商品可是经过我们慎重挑选的,绝对都是优品中的优品哦!!

完整代码:https://github.com/zhangyue0503/designpatterns-php/blob/master/19.facade/source/facade.php

实例

这回我们将短信的发送以发送的维度进行包装,将不同的短信和推送运营商的接口包装起来,在发送的时候只需要通过发送类就可以控制用不同的第三方服务进行短信或推送的发送啦,想想都很方便呢!

短信发送类图

完整源码:https://github.com/zhangyue0503/designpatterns-php/blob/master/19.facade/source/facade-push.php

<?php

class Send
{ private $aliYunService;
private $jiGuangService; private $message;
private $push; public function __construct()
{
$this->aliYunService = new AliYunService();
$this->jiGuangService = new JiGuangService(); $this->message = new MessageInfo();
$this->push = new PushInfo();
} public function PushAndSendAliYun()
{
$this->message->Send($this->aliYunService);
$this->push->Push($this->aliYunService);
} public function PushAndSendJiGuang()
{
$this->message->Send($this->jiGuangService);
$this->push->Push($this->jiGuangService);
}
} class MessageInfo
{
public function Send($service)
{
$service->Send();
}
} class PushInfo
{
public function Push($service)
{
$service->Push();
}
} class AliYunService
{
public function Send()
{
echo '发送阿里云短信!', PHP_EOL;
}
public function Push()
{
echo '推送阿里云通知!', PHP_EOL;
}
} class JiGuangService
{
public function Send()
{
echo '发送极光短信!', PHP_EOL;
}
public function Push()
{
echo '推送极光通知!', PHP_EOL;
}
} $send = new Send();
$send->PushAndSendAliYun();
$send->PushAndSendJiGuang();

说明

  • 依然还是熟悉的配方熟悉的味道。在这里,可以想象我们的第三方服务类都是较老的接口,或者已经是很复杂的接口了。这时,使用外观模式一来是可以与新系统配合,二来也能降低复杂度
  • 但是要注意的,外观类本身可能成为复杂度的来源,不过幸好我们可以遵从单一职责的原则,一个外观类就做一件事就好啦

下期看点

外观模式其实并没有太多可说的,因为它确实非常简单而且无处不在。不要被Laravel花哨的Facade类所欺骗,它并没有那么的复杂。下回我们学习到的依然是一个非常简单而且在不知不觉中就会用到的模式:模板方法模式

关注公众号:【硬核项目经理】获取最新文章

添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料

知乎、公众号、抖音、头条搜索【硬核项目经理】

B站ID:482780532

PHP设计模式之门面模式的更多相关文章

  1. python 设计模式之门面模式

    facade:建筑物的表面 门面模式是一个软件工程设计模式,主要用于面向对象编程. 一个门面可以看作是为大段代码提供简单接口的对象,就像类库.   门面模式被归入建筑设计模式.门面模式隐藏系统内部的细 ...

  2. 设计模式_Facade_门面模式

    形象例子: 我有一个专业的Nikon相机,我就喜欢自己手动调光圈.快门,这样照出来的照片才专业,但MM可不懂这些,教了半天也不会.幸好相机有Facade设计模式,把相机调整到自动档,只要对准目标按快门 ...

  3. JavaScript设计模式(6)-门面模式

    门面模式 门面模式(Facade Pattern):他隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口.这种类型的设计模式属于结构性模式.为子系统中的一组接口提供了一个统一的访问接口,这个接 ...

  4. python设计模式之门面模式

    一.结构型设计模式 门面模式与单例模式,工厂模式不同,它是一种结构型模式. 结构型模式描述如何将对象和类组合成更大的结构 结构型模式是一种能够简化设计工作的模式,它能找出更简单的方法来认识或表示实体之 ...

  5. java设计模式之门面模式以及在java中作用

    门面模式在Tomcat中有多处使用,在Request和Response对象封装,从ApplicationContext到ServletContext封装中都用到了这种设计模式. 一个系统可以有几个门面 ...

  6. 【php设计模式】门面模式

    门面模式又叫外观模式,用来隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性. 这种模式涉及到一个单一的类 ...

  7. JAVA设计模式之门面模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述门面(Facade)模式的: 门面模式是对象的结构模式,外部与一个子系统的通信必须通过一个统一的门面对象进行.门面模式提供一个高层次的接口 ...

  8. JS设计模式——10.门面模式

    门面模式 这是一种组织性的模式,它可以用来修改类和对象的接口,使其更便于使用.它可以让程序员过得更轻松,使他们的代码变得更容易管理. 门面模式有两个作用: 简化类的接口 消除与使用她的客户代码之间的耦 ...

  9. JAVA设计模式之门面模式(外观模式)

    医院的例子 现代的软件系统都是比较复杂的,设计师处理复杂系统的一个常见方法便是将其“分而治之”,把一个系统划分为几个较小的子系统.如果把医院作为一个子系统,按照部门职能,这个系统可以划分为挂号.门诊. ...

  10. JavaScript设计模式-12.门面模式

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

随机推荐

  1. 数字化转型:敏捷和DevOps如何降低风险,提高速度

    进行数字化转型就意味着团队需要应对经常发生冲突的挑战--例如,要应对在复杂的相互依赖环境中快速变化的需求.对软件开发人员来说,这是一个熟悉的困境. 如果使用传统的瀑布方法来应对这些挑战,就会发现,在线 ...

  2. 【力扣leetcode】-787. K站中转内最便宜的航班

    题目描述: 有 n 个城市通过一些航班连接.给你一个数组 flights ,其中 flights[i] = [fromi, toi, pricei] ,表示该航班都从城市 fromi 开始,以价格 p ...

  3. 题解 P3158 [CQOI2011]放棋子

    题解 本题是一个 \(DP\) 加 容斥,容斥的式子很好推,重点是如何想到和如何推出 \(DP\) 部分的式子. 因为不同种颜色的棋子不能放在同一行或同一列,所以不同种的棋子是相对独立的. 据此,我们 ...

  4. ThreadPoolExecutor(线程池)的参数

    构造函数 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit u ...

  5. 动态数据库PI、edna insql、infoplus简单了解

    一.动态数据库概念 动态数据库(DDL)是做为共享函数库的可执行文件.动态数据库提供了一种方法,使进程可以调用不属于其可执行代码的函数.说白了就是一个.dll可执行文件,其中有可执行代码,进程可以调用 ...

  6. wpf 获得exe的运行路径

    System.Reflection.Assembly.GetEntryAssembly().Location

  7. ajax传字符串时出现乱码问题的解决

    字符乱码的解决: 第一种在@RequestMapping中添加 @RequestMapping(value="queryAllToTree",method=RequestMetho ...

  8. uwp 之多媒体开发

    xml code ----------------------------------------------------- <Page x:Class="MyApp.MainPage ...

  9. php Abstract 抽象类 与 Interface的

    一.Abstract Class 与 Interface 的构造 抽象类 Abstract Class <?php abstract class A { abstract public func ...

  10. servlet通过响应头Content-Disposition实现文件下载效果

    package day08; import java.io.File; import java.io.FileInputStream; import java.io.IOException; impo ...