专栏首页Vincent-yuan设计模式~门面模式

设计模式~门面模式

门面模式是对象的结构模式。

外部与一个子系统的通信必须通过一个统一的门面对象进行,这就是门面模式。

什么是门面模式

门面模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面对象进行。

门面模式提供一个高层次的接口,使得子系统更易于使用。

门面模式的结构

在这个对象图中,出现了两个角色:

  • 门面角色(Facade): 客户端可以调用这个角色的方法。此角色知晓相关的(一个或多个)子系统的的功能和责任。在正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去。
  • 子系统角色(Subsystem): 可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合。每一个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另一个客户端而已。

门面模式的实现

一个系统可以有几个门面类:

在门面模式中,通常只需要一个门面类,并且此门面类只有一个实例,也就是说,它是一个单例类。

但这并不意味着在整个系统里只能有一个门面类,而仅仅是说,对每一个子系统只有一个门面类。

或者说,如果一个系统有好几个子系统的话,每一个子系统有一个门面类,整个系统可以有数个门面类。

  以医院为例,可以为每一个不同的科室配备不同的接待员类。

为子系统增加新行为:

  初学者往往以为通过继承一个门面类便可以在系统中加入新的行为,这是错误的。

门面模式的用意是,为子系统提供一个集中化和简化的沟通管道,而不能向子系统加入新的行为。

  仍以医院为例,接待员并不是医护人员,接待员并不能为病人提供医疗服务。

在什么情况下使用门面模式

为一个复杂子系统提供一个简单接口

  子系统往往因为不断演化而变的越来越复杂,使用门面模式可以使得子系统更具有可复用性。

Facade模式可以提供一个简单的默认视图,对大多数用户来说这个视图已经足够用了,

而那些需要进一步继承的用户可以越过Facade层直接对子系统进行继承。

子系统的独立性

一般而言,子系统和其他子系统之间、客户端与实现化层之间存在着很大的依赖性。

引入Facade模式将一个子系统与它的客户端及其他子系统分离,可以提高子系统的独立性和可移植性。

层次化结构

在构建一个层次化的系统时,可以使用 Facade模式定义系统中每一层的入口。如果层与层之间是相互依赖的,

则可以限定它们仅通过Facade进行通信,从而简化层与层之间的依赖关系。

一个例子

这里从代码重构的角度演示门面模式的应用。

这里给出一个保安系统,首先给出一个系统不适用门面模式的解决方案,然后指出其缺点,再将门面模式引入,并对源代码进行改组重构。

一个保安系统由两个录像机、三个电灯、一个遥感器和一个报警器组成。保安系统的操作人员需要经常将这些仪器启动和关闭。

不使用门面模式的设计

代码清单:

客户端角色

public class Client {
    static private Camera camera1,camera2;
    static private Light light1,light2,light3;
    static private Sensor sensor;
    static private Alarm alarm;

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        camera1.turnOn();
        camera2.turnOn();
        light1.turnOn();
        light2.turnOn();
        light3.turnOn();
        sensor.activate();
        alarm.activate();
    }
}

Camera

public class Camera {

    public void turnOn(){
        System.out.println("Turning on the camera.");
    }
    public void turnOff(){
        System.out.println("Turning off the camera");
    }
    public void rotate(int degrees){
        System.out.println("rotating the camera by" + degrees + " degrees.");
    }
}

Light

public class Light {

    public void turnOn()
    {
        System.out.println("Turning on the light.");
    }
    public void turnOff(){
        System.out.println("Turning off the light.");
    }
    public void changeBulb(){
        System.out.println("changing the light-bulb.");
    }
}

Sensor

public class Sensor {

    public void activate(){
        System.out.println("Activating the sensor.");
    }
    public void deactivate(){
        System.out.println("Deactivating the sensor.");
    }
    public void trigger(){
        System.out.println("The sensor has been triggered.");
    }
}

Alarm

public class Alarm {

    public void activate(){
        System.out.println("Activating the alarm.");
    }
    public void deactivate(){
        System.out.println("deactivating the alarm.");
    }
    public void ring()
    {
        System.out.println("Ringing the alarm.");
    }
    public void stopRing(){
        System.out.println("Stop the alarm.");
    }
}

使用门面模式的设计

一个合情合理的改进方法是准备一个系统的控制台,作为保安系统的用户界面。

用户只需要操作这个简化的界面就可以操控所有的内部仪器,这实际上就是门面模式的用意。

可以看出,门面SecurityFacade 对象承担了与保安系统内部各个对象打交道的任务,客户端对象只需要与门面对象打交道即可。

客户端

public class Client {

    private static SecurityFacade security;
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        security.activate();
    }
}

门面类 SecurityFacade

public class SecurityFacade {

     private Camera camera1,camera2;
     private Light light1,light2,light3;
     private Sensor sensor;
     private Alarm alarm;
     
     public void activate(){
         camera1.turnOn();
         camera2.turnOn();
         light1.turnOn();
         light2.turnOn();
         light3.turnOn();
         sensor.activate();
         alarm.activate();
     }
     public void deactivate(){
         camera1.turnOff();
         camera2.turnOff();
         light1.turnOff();
         light2.turnOff();
         light3.turnOff();
         sensor.deactivate();
         alarm.deactivate();
     }
}

其他Camera,Light, Sensor, Alarm类与改进前相同。

Session门面模式

Session门面模式是J2EE模式的一种,实际上也是门面模式在J2EE框架中的应用。

什么是Session门面模式

Session门面模式用一个SessionBean作为门面,封装一个工作流程中的商务对象之间的相互作用。

Session门面对象管理商务对象并为客户端提供一个粗粒度的服务层。

Session门面模式的结构

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • java之单元测试

    Vincent-yuan
  • aabb

    Vincent-yuan
  • asp.net core 系列之webapi集成Dapper的简单操作教程

    在这之前,可以手动往数据库表里加几条数据,我这里没有加,只是在Get方法里打了个断点

    Vincent-yuan
  • 机器学习之决策树(Decision Tree)及其Python代码实现

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_35512245/articl...

    大黄大黄大黄
  • LeetCode Single Number题目分析代码

    Given an array of integers, every element appears twice except for one. Find tha...

    desperate633
  • Java能写外挂吗?那就写个跳一跳辅助程序吧

    ##起初是想使用按键精灵脚本程序控制,但还是选择熟悉的java。我这里使用了工具,造成延迟问题。也求教:java控制安卓的正确姿势,

    三哥
  • POJ 刷题系列:3299. Humidex

    POJ 刷题系列:3299. Humidex 传送门:POJ 3299. Humidex 题意: 给定T, D, H中的任意两个数,求另外一个。 思路: ...

    用户1147447
  • Android实现消息提醒小红点效果

    本人分享一下,自己写的一个消息提醒小红点控件,支持圆、矩形、椭圆、圆角矩形、正方形五种图形样式,可带文字,支持链式操作。

    砸漏
  • 组件化三问—字节真题

    组件化由于它的解耦,独立,开发效率已经成为了被广泛使用的项目架构了,特别是大项目重构的首选,今天就一起来看看组件化开发。

    码上积木
  • LeetCode Weekly Contest 29解题思路

    代码很简单,简单说明下思路就出来了。按照题意,不管怎么二分,整个数组都会被划分成两部分和,这两部分和必然一大一小。如nums = [1,4,3,2],划分如下[...

    用户1147447

扫码关注云+社区

领取腾讯云代金券