PHP设计模式 - 门面模式(Facade)通俗易懂 / 友好示例代码_php facade-程序员宅基地

技术标签: php  外观模式  + PHP  设计模式  

前言

门面模式(Facade)又称外观模式,用于为子系统中的一组接口提供一个一致的界面。门面模式定义了一个高层接口,这个接口使得子系统更加容易使用:引入门面角色之后,用户只需要直接与门面角色交互,用户与子系统之间的复杂关系由门面角色来实现,从而降低了系统的耦合度。

打个比方,比如我们要在淘宝买东西,我基本上只需要鼠标点一些按钮就完成了。

但是实际上网站的后台是 很多个子系统一起去完成 你购买商品的任务的,比如网站系统,购物车系统,订单系统,用户中心系统,支付系统。

这些系统 对外通过了统一的接口,让你在网站上点按钮就可以完成买东西的需求。这就是门面模式。我的理解起这个名称的人关注的是由多个接口不统一的子系统对外提供统一的接口,好像形成了一个界面或者门面一样。
在这里插入图片描述

能做什么?

  • 为一些复杂的子系统提供一组接口。
  • 提高子系统的独立性。
  • 在层次化结构中,可以使用门面模式定义系统的每一层的接口。

有什么优势?

  • 它对客户屏蔽了子系统组件,因而减少了客户处理的对象的数目并使得子系统使用起来更加方便。
  • 实现了子系统与客户之间的松耦合关系。
  • 如果应用需要,它并不限制它们使用子系统类。因此可以在系统易用性与能用性之间加以选择。

实例(通俗易懂)

下面模拟一个 "用户操作设备" ,你一看就能恍然大悟!

说了这么多理论,你可能感到迷惑,想千遍,不如做一遍!

复制粘贴,跑起来!

<?php

/**
 * 门面设计模式(Facade)
 * 看不懂你打我!
 */
 
class Camera 
{
    
 
    /**
     * 打开录像机
     */
    public function turnOn()
    {
    
        echo "打开录像机" . '<br/>';
    }
 
    /**
     * 关闭录像机
     */
    public function turnOff()
    {
    
        echo "关闭录像机" . '<br/>';
    }
 
}

class Light
{
    
 
    /**
     * 开灯
     */
    public function turnOn()
    {
    
        echo "开灯" . '<br/>';
    }
 
    /**
     * 关灯
     */
    public function turnOff()
    {
    
        echo "关灯" . '<br/>';
    }
 
    /**
     * 换灯泡
     */
    public function changeBulb()
    {
    
        echo "换灯泡" . '<br/>';
    }

}
 
class Sensor 
{
    
 
    /**
     * 启动感应器
     */
    public function activate()
    {
    
        echo "启动感应器" . '<br/>';
    }
 
    /**
     * 关闭感应器
     */
    public function deactivate()
    {
    
        echo "关闭感应器" . '<br/>';
    }
 
    /**
     * 触发感应器
     */
    public function trigger()
    {
    
        echo "触发感应器" . '<br/>';
    }

}

class Alarm {
    
 
    /**
     * 启动警报器
     */
    public function activate()
    {
    
        echo "启动报警器" . '<br/>';
    }
 
    /**
     * 关闭警报器
     */
    public function deactivate()
    {
    
        echo "关闭报警器" . '<br/>';
    }
 
    /**
     * 拉响警报器
     */
    public function ring()
    {
    
        echo "拉响报警器" . '<br/>';
    }
 
    /**
     * 停掉警报器
     */
    public function stopRing()
    {
    
        echo "停掉报警器" . '<br/>';
    }

}
 
/**
 * 门面类(Facade)
 * 负责将"分散"的功能提供统一接口
 */
class Facade
{
    
 
    /* 录像机 */
    private $_camera;
 
    /* 灯 */
    private $_light;
 
    /* 感应器 */
    private $_sensor;
 
    /* 警报器 */
    private $_alarm;
    
    public function __construct()
    {
    
        $this->_camera = new Camera();
        $this->_light = new Light();
        $this->_sensor = new Sensor();
        $this->_alarm = new Alarm();
    }
    
    /**
     * 启动接口: (打开录像机/开灯/启动感应器/启动报警器)
     * @return void
     */
    public function activate()
    {
    
        // 打开录像机
        $this->_camera -> turnOn();
        // 开灯
        $this->_light -> turnOn();
        // 启动感应器
        $this->_sensor -> activate();
        // 启动报警器
        $this->_alarm -> activate();
        // 分隔符(方便观察)
        echo '<hr>';
    }

    /**
     * 关闭接口: (关闭录像机/关灯/关闭感应器/关闭报警器)
     * @return void
     */
    public function deactivate()
    {
    
        // 关闭录像机
        $this->_camera -> turnOff();
        // 关灯
        $this->_light -> turnOff();
        // 关闭感应器
        $this->_sensor -> deactivate();
        // 关闭报警器
        $this->_alarm -> deactivate();
        // 分隔符(方便观察)
        echo '<hr>';
    }

    /**
     * 其他功能接口: (换灯泡/触发感应器/拉响警报器/停掉警报器)
     * @return void
     */
    public function otherFunction()
    {
    
        // 换灯泡
        $this->_light -> changeBulb();
        // 触发感应器
        $this->_sensor -> trigger();
        // 拉响警报器
        $this->_alarm -> ring();
        // 停掉警报器
        $this->_alarm -> stopRing();
        // 分隔符(方便观察)
        echo '<hr>';
    }
}
 
 
/**
 * 客户端(由用户触发接口功能)
 */
class Client
{
    
 
    private static $_security;
    
    /**
     * 主程序(Main program)
     * @return void
     */
    public static function main()
    {
       
        // 实例化门面类(Facade)
        self::$_security = new Facade();

        /**
         * 用户操作(operation)
         * @activate(): 开启操作
         * @deactivate(): 关闭操作
         * @otherFunction(): 其他操作
         */
        self::$_security -> activate();
        self::$_security -> deactivate();
        self::$_security -> otherFunction();
    }
}

/**
 * console main();
 */
Client::main();

?>

客户端结果:
在这里插入图片描述
说白了,就是将复杂的功能统一使用一个接口管理起来!

写在后面

当然,以上示例写在一个文件中 只是为了告诉你什么是门面模式,真正开发中 功能类门面类客户端类,都是分离模块化(不同文件夹与文件),高内聚低耦合嘛。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_44198965/article/details/108224946

智能推荐

多线程基础之设计模式Future模式_线程 future-程序员宅基地

文章浏览阅读258次。多线程基础之设计模式Future模式_线程 future

CCS中关于error#5、error#10008-D、error#16001的更正指导_cannot find file "libc.a-程序员宅基地

文章浏览阅读1w次,点赞17次,收藏60次。本文档仅对ccs编程过程中所出现的error#5、error#10008-D、error#10010做简要讲解在使用ccs对dsp编程过程中,用户可能会参考一些例程或在维护优化时阅读他人程序,而在导入程序时会出现各种各样的错误或警告,下面对编者在修改程序时遇到的error#5、error#10008-D和error#10010做简要讲解。1.error#5的错误更正讲解在ccs中导入其..._cannot find file "libc.a

poj 3080(3450) KMP(暴力也能过) 多个串的最长公共子串-程序员宅基地

文章浏览阅读359次。题意:给定m(m思路:暴力找出第一个串的所有长度大于等于3的子串,用KMP算法求其是否为剩下m-1个串的子串。为了复用next数组,枚举子串时先固定起点(求一遍next数组即可),然后由长到短枚举子串(剪枝)。#include #include using namespace std;#define N 60char s[12][N+5],t[N+5],res[N+5];int

matlab reshape意义,matlab reshape使用-程序员宅基地

文章浏览阅读1.4k次。reshape把指定的矩阵改变形状,但是元素个数不变,例如,行向量:a = [1 2 3 4 5 6]执行下面语句把它变成3行2列:b = reshape(a,3,2)执行结果:b =1 42 53 6若a=[1 2 34 5 67 8 9]使用reshpe后想得到b=[1 2 3 4 5 6 7 8 9]只需要将a转置一下就可以了:b=reshape(a',1,9)---------------..._matlab中reshape的含义

c语言中数学运算符,运算符在数学和C语言中的区别.doc-程序员宅基地

文章浏览阅读1k次。运算符在数学和C语言中的区别刚开始学C语言的人,一般都认为C语言中的运算符跟数学中的运算符完全相同,没必要去考虑和研究,从而在利用过程中经常出错而把学习C语言越来越难或神秘化,其实学C语言并不是很难的事,要把握有些重要技巧,很容易学会.著名计算机科学家沃思(Nikiklaus Wirth)说“程序=算法+数据类型”,要好好学会程序,首先要深入了解算法,而了解算法事实上指的是就是正确地了解和利用运算..._c语言中的加减乘除和数学中的加减乘除有什么不同【

SSM三大框架Spring_后端框架三大框架-程序员宅基地

文章浏览阅读3.9k次。一、三大框架基本结构1.为什么需要框架说明: 如果生产环境下的项目,都是从头(从底层写起)开发,难度太大了,并且开发的效率极其低下. 所以为了让项目快速的上线部署. 将某些特定的功能.进行了高级的封装. 那么我们如果需要使用封装后的API.,则必须按照人家的要求编码2.框架的分类:1.Spring框架:整个框架中负责“宏观调控”的(主导),负责整合其它的第三方的框架2.SpringMVC框架:主要负责实现前后端数据的交互3.Mybatis框架/MybatisPlus框架:持久层框.._后端框架三大框架

随便推点

数据结构(3):java使用数组模拟堆栈-程序员宅基地

文章浏览阅读2次。   堆栈原理:        数组模拟堆栈: //数组模拟栈class ArrayStack{ //栈顶 private int top = -1; private int maxSize; private int[] arrayStack; public ArrayStack(int maxSize){ this.maxSi...

Understand_6.5.1175::New Project Wizard_understand 6.5.1176-程序员宅基地

文章浏览阅读742次,点赞16次,收藏17次。不选: Enforce portability rules to share this project with others。勾选: Configure Advanced Settings after project creation。保存类型(T):Understand projects (*.udb)勾选:Include subdirectories (包含子文件夹)Additional Filters: (空)单击 文件夹 lab1。文件名(N):lab1。双击 文件夹 boot。_understand 6.5.1176

从零开始带你成为MySQL实战优化高手学习笔记(二) Innodb中Buffer Pool的相关知识_mysql_global_status_innodb_buffer_pool_reads-程序员宅基地

文章浏览阅读969次。在从零开始带你成为MySQL实战优化高手学习笔记(一)中学习到一条语句到底是怎么执行的,从链接获取数据到通过查询解析器解析SQL语句表达的什么意思,解析之后由查询优化器生成查询路径树,选出一条最优查询路径调用存储引擎接口..._mysql_global_status_innodb_buffer_pool_reads

美化上传文件框(上传图片框)_文件上传框很丑-程序员宅基地

文章浏览阅读8.8k次,点赞6次,收藏12次。传统的表单控件十分简陋,可以说是很难看,那怎么办?方法:我们自己做一个好看的样式出来,用各种标签啊,css啊,是可以做到的。如图:做出这样一个样子应该是很简单的,但是怎么让他具有上传的功能的呢?那就使用代理的方法,点击上传就等于点击(上传文件表单控件)废话不多说,直接上代码:html:测试插件body{font_文件上传框很丑

js简单表格操作_"var str = '<table border=\"5px\"><tr><td>序号</td><-程序员宅基地

文章浏览阅读4.8k次,点赞3次,收藏18次。js简单表格操作,对表格进行增删改,效果图:全部代码:&lt;!DOCTYPE html&gt;&lt;html&gt;&lt;head&gt; &lt;meta charset="utf-8" /&gt; &lt;script type="text/javascript" src="js/jquery.2.1.4.min.js" &gt;&lt;/sc_"var str = '序号名字

Power BI销售数据分析_powerbi汇总销售人员业绩包括无销售记录的人-程序员宅基地

文章浏览阅读1.1w次,点赞8次,收藏99次。今天通过一份销售数据,聊聊Power BI数据分析。一、分析数据数据源总的有四个表,店铺资料,销售目标,销售数据_本期,销售数据_去年同期。各表表头如下:1店铺资料表:2销售目标:3销售数据_本期:4销售数据_去年同期:数据中包含多个城市、督导、店铺的数据,我希望经过分析后能得到各个城市/店铺的销售情况,即业绩、业绩完成率、业绩贡献度、业绩增长率、各销售人员的销售能力等。此次..._powerbi汇总销售人员业绩包括无销售记录的人

推荐文章

热门文章

相关标签