关闭

Java设计模式11:外观模式

标签: java设计模式外观模式
123人阅读 评论(0) 收藏 举报
分类:

外观模式

外观模式是对象的结构模式,外部与一个子系统的通信必须通过一个统一的外观对象进行。外观模式是一个高层次的接口,使得子系统更易于使用。

 

医院的例子

现代的软件系统都是比较复杂的。假如把医院比作一个子系统,按照部门职能,这个系统划分为挂号、门诊、划价、化验、收费、取药等。看病的人要与这些部门打交道,就如同一个子系统的客户端与一个子系统的各个类打交道一样,不是一件容易的事。

解决这种不便的方法便是引入外观模式,医院可以设置一个接待员的位置,由接待员负责代为挂号、划价、缴费、取药等。病人只需要接触接待员,由接待员与各个部门打交道。

 

外观模式的结构

外观模式的结构可以这么表示:

这个图中,体现了两种角色:

1、外观角色

客户端调用这个角色的方法。此角色知晓相关的子系统的功能和责任,正常情况下,本角色会将所有从客户端发来的请求委派到响应的子系统中

2、子系统角色

可以同时有一个或多个子系统,每个子系统都不是一个单独的类,而是一个类的集合。每个子系统都可以被客户端直接调用,或者被外观角色直接调用。子系统并不知道外观角色的存在,对于子系统而言,外观仅仅是另外一个客户端而已

 

外观模式示例

模拟三个子系统ModuleA、ModuleB、ModuleC:

复制代码
public class ModuleA
{
    public void testA()
    {
        System.out.println("调用Module中的testA方法");
    }
}
复制代码
复制代码
public class ModuleB
{
    public void testB()
    {
        System.out.println("调用Module中的testB方法");
    }
}
复制代码
复制代码
public class ModuleC
{
    public void testC()
    {
        System.out.println("调用Module中的testC方法");
    }
}
复制代码

模拟一个外观对象:

复制代码
public class Facade
{
    public void test()
    {
        ModuleA ma = new ModuleA();
        ma.testA();
        ModuleB mb = new ModuleB();
        mb.testB();
        ModuleC mc = new ModuleC();
        mc.testC();
    }
}
复制代码

写一个客户端调用一下外观角色:

public static void main(String[] args)
{
    Facade facade = new Facade();
    facade.test();
}

运行结果很明显:

调用Module中的testA方法
调用Module中的testB方法
调用Module中的testC方法

这样,客户端不需要亲自调用子系统的A、B、C模块了,也不需要知道内部系统的实现细节,甚至不需要知道模块A、模块B、模块C的存在,只需要和Facade类交互就好了,从而更好地实现了客户端和子系统中的三个模块的解耦,让客户端更容易地使用子系统。

另外,定义一个外观类还可以有效地屏蔽内部的细节。因为子系统中有一些方法,是模块之间相互交互用的,并不需要外部调用。如果直接调用子系统的类方法,会出现一些不需要客户端知道的方法,这样既暴露了内部细节,又让客户端模迷惑。外观类就不一样了,可以只给客户端提供那些子系统给外部使用的方法。

 

外观模式在Java中的应用及解读

Tomcat中有很多场景都使用到了外观模式,因为Tomcat中有很多不同的组件,每个组件需要相互通信,但又不能将自己内部数据过多地暴露给其他组件。用外观模式隔离数据是个很好的方法,比如Request上使用外观模式:

比如Servlet,doGet和doPost方法,参数类型是接口HttpServletRequest和接口HttpServletResponse,那么Tomcat中传递过来的真实类型到底是什么呢?

有过对Java Web项目Debug经验的肯定会发现,在真正调用Servlet前,会经过很多Tomcat方法。反编译一下javaee.jar包就会看到,传递给Tomcat的request和response的真正类型是:

看到返回的都是一个Facade类。因为Request类中很多方法都是组件内部之间交互用的,比如setComet、setReuqestedSessionId等方法,这些方法并不对外公开,但又必须设置为public,因为还要和内部组件交互使用。最好的解决方法就是通过使用一个Facade类,屏蔽掉内部组件之间交互的方法,只提供外部程序要使用的方法。

如果不使用Facade,直接传递的是HttpServletRequest和HttpServletResponse,那么熟悉容器内部运作的开发者可以分别把ServletRequest和ServletResponse向下转型为HttpServletRequest和HttpServletResponse,这样就有安全性的问题了。

 

外观模式的优点

外观模式有如下几个优点:

1、松散耦合

外观模式松散了客户端和子系统的耦合关系,让子系统内部的模块能更容易扩展和维护

2、简单易用

客户端不需要了解系统内部的实现,也不需要和众多子系统内部的模块交互,只需要和外观类交互就可以了

3、更好地划分层次

通过合理使用Facade,可以帮助我们更好地划分层次。有些方法是系统对内的,有些方法是对外的,把需要暴露给外部的功能集中到Facade中,这样既方便客户端使用,也很好地隐藏了内部的细节

0
0
查看评论

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

医院的例子   现代的软件系统都是比较复杂的,设计师处理复杂系统的一个常见方法便是将其“分而治之”,把一个系统划分为几个较小的子系统。如果把医院作为一个子系统,按照部门职能,这个系统可以划分为挂号、门诊、划价、化验、收费、取药等。看病的病人要与这些部门打交道,就如同一个子系统的客户端与一个子系统的各...
  • jason0539
  • jason0539
  • 2014-04-02 07:16
  • 26080

java/android 设计模式学习笔记(14)---外观模式

这篇博客来介绍外观模式(Facade Pattern),外观模式也称为门面模式,它在开发过程中运用频率非常高,尤其是在现阶段各种第三方 SDK 基本很大概率都会使用外观模式。通过一个外观类使得整个系统的接口只有一个统一的高层的接口,这样能够降低用户的使用成本,也对用户屏蔽了很多实现细节。当然,在我们...
  • zhao_zepeng
  • zhao_zepeng
  • 2016-07-17 18:14
  • 3495

深入浅出设计模式之命令模式、适配器模式、外观模式

命令模式
  • u011531613
  • u011531613
  • 2017-03-22 20:42
  • 482

浅谈JAVA设计模式之——外观模式(Facade)

一、概述 为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 二、适用性 1.当你要为一个复杂子系统提供一个简单接口时。子系统往往因为不断演化而变得越来越 复杂。大多数模式使用时都会产生更多更小的类。这使得子系统更具可重用性,也更容 易对...
  • l1028386804
  • l1028386804
  • 2015-05-07 23:32
  • 3383

JAVA设计模式十九--Facade(外观模式)

Facade(外观)模式为子系统中的各类(或结构与方法)提供一个简明一致的界面,隐藏子系统的复杂性,使子系统更加容易使用。 Facade模式概述         实际应用中,我们在对付一些老旧的code(尤其是将C的代码转成C++代...
  • hfmbook
  • hfmbook
  • 2012-06-29 15:25
  • 18509

c#设计模式==外观模式

外观模式,是一种使用频率非常高的结构型设计模式,它通过引入一个外观角色来简化客户端与子系统之间的交互,为复杂的子系统调用提供一个统一的入口,降低子系统与客户端的耦合度,且客户端调用非常方便。   不知道大家有没有比较过自己泡茶和去茶馆喝茶的区别,如果是自己泡茶需要自行准备茶叶、茶具和开水,如图1(...
  • hjf161105
  • hjf161105
  • 2017-07-06 20:53
  • 99

最常用的设计模式---外观模式(C++实现)

外观模式:提供了一个统一的接口,用来访问子系统的一群接口。外观定义了一个高层接口,让子系统更容易使用。目地:让接口变得简单,是为了简化子系统的接口。
  • lh844386434
  • lh844386434
  • 2014-01-09 17:25
  • 1668

[设计模式](二)外观模式和建造者模式的区别

网上博客很多使用KFC套餐来做的例子,讲述地不够贴切,觉得容易误导读者,在那个例子中KFC的套餐(ConcretedBulider)的具体内容被消费者(Client)清楚地了解且也是其关心的点,但是在建造者模式里消费者并不了解也不关心产品的创建过程,而在例子中建造者(Builder)也只是简单地提供...
  • stephzcj
  • stephzcj
  • 2017-05-22 16:05
  • 480

Unity3d之设计模式(四)外观模式

一、定义 外观模式:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 解释:简单来说,客户端需要调用一个特别复杂的子系统中的多个接口,如果直接调用逻辑处理起来会非常复杂,而且不便于系统扩展。外观模式把这个复杂的子系统统一起来,提供几个高层接口...
  • qq563129582
  • qq563129582
  • 2016-12-15 18:24
  • 697

【设计模式】学习笔记10:外观模式(Facade)

上一次我们已经知道了适配器模式是如何将一个类的接口转换成另一个符合客户期望的接口了。Java中要做到这一点,必须将一个不兼容接口的对象包装起来,变成兼容的对象。 这次要学的是外观模式. 外观模式是将一个或数个类的复杂的一切都隐藏在背后,只显露出一个干净美好的外观。 走近外观模式 假设要用Java设计...
  • shuangde800
  • shuangde800
  • 2013-08-13 00:42
  • 2720
    个人资料
    • 访问:47127次
    • 积分:837
    • 等级:
    • 排名:千里之外
    • 原创:19篇
    • 转载:112篇
    • 译文:0篇
    • 评论:3条
    文章分类
    最新评论