本文源码:GitHub·点这里 || GitEE·点这里

一、生活场景

1、场景描述

在移动互联网没有普及之前,去饭店吃饭的流程大致如下:选座位,排队,点菜,结账。后来移动互联网普及,通过手机APP就可以操作这些流程,非常的方便快捷:通过手机可以知道某饭店是不是还有空位,到了饭店之后直接入座,然后通过手机点菜,结账,中间省去了很多繁琐的流程。

2、代码图解

3、代码实现

  1. /**
  2. * 外观模式描述饭店就餐流程
  3. */
  4. public class C01_InScene {
  5. public static void main(String[] args) {
  6. EatAppFacade eatAppFacade = new EatAppFacade () ;
  7. eatAppFacade.dining();
  8. }
  9. }
  10. // 预定
  11. class Booking {
  12. private static Booking booking = new Booking() ;
  13. public static Booking getInstance (){
  14. return booking ;
  15. }
  16. public void bookPlace (){
  17. System.out.println("位置预定...");
  18. }
  19. }
  20. // 点餐
  21. class TakeOrder {
  22. private static TakeOrder takeOrder = new TakeOrder ();
  23. public static TakeOrder getInstance (){
  24. return takeOrder ;
  25. }
  26. public void orderDishes (){
  27. System.out.println("点餐...");
  28. }
  29. }
  30. // 付款
  31. class Payment {
  32. private static Payment payment = new Payment () ;
  33. public static Payment getInstance (){
  34. return payment ;
  35. }
  36. public void payMoney (){
  37. System.out.println("结账...");
  38. }
  39. }
  40. // 点餐APP
  41. class EatAppFacade {
  42. private Booking booking ;
  43. private TakeOrder takeOrder ;
  44. private Payment payment ;
  45. public EatAppFacade (){
  46. this.booking = Booking.getInstance() ;
  47. this.takeOrder = TakeOrder.getInstance() ;
  48. this.payment = Payment.getInstance() ;
  49. }
  50. // 就餐流程
  51. public void dining (){
  52. booking.bookPlace();
  53. takeOrder.orderDishes();
  54. payment.payMoney();
  55. }
  56. }

二、外观设计模式

1、基本简介

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

2、模式图解

3、核心角色

  • 外观角色

客户端可以调用这个角色的方法。此角色具有相关的子模块的功能。在正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去。

  • 子模块角色

可以同时有一个或者多个子模块。每个子模块都不是一个单独的类,而是一个类的集合(如上面的子模块就是由ModuleA、ModuleB、ModuleC三个类组合而成)。每个子系统都可以被客户端直接调用,或者被外观角色调用。子模块并不知道外观的存在,对于子模块而言,外观角色仅仅是另外一个客户端。

  • 客户端角色

外观对象功能的调用者。

4、源代码实现

  1. public class C02_Facade {
  2. public static void main(String[] args) {
  3. Facade facade = new Facade();
  4. facade.clientNeed1();
  5. facade.clientNeed2();
  6. }
  7. }
  8. class ModuleA {
  9. public void testA (){
  10. System.out.println("ModuleA.testA()");
  11. }
  12. }
  13. class ModuleB {
  14. public void testB (){
  15. System.out.println("ModuleB.testB()");
  16. }
  17. }
  18. class ModuleC {
  19. public void testC (){
  20. System.out.println("ModuleC.testC()");
  21. }
  22. }
  23. class Facade {
  24. /**
  25. * 客户需求1
  26. */
  27. public void clientNeed1 (){
  28. ModuleA moduleA = new ModuleA();
  29. moduleA.testA();
  30. ModuleB moduleB = new ModuleB();
  31. moduleB.testB();
  32. }
  33. /**
  34. * 客户需求1
  35. */
  36. public void clientNeed2 (){
  37. ModuleB moduleB = new ModuleB();
  38. moduleB.testB();
  39. ModuleC moduleC = new ModuleC();
  40. moduleC.testC();
  41. }
  42. }

三、Mybatis应用场景

1、使用场景

  • org.apache.ibatis.session.Configuration
  • org.apache.ibatis.reflection.MetaObject

Configuration 创建 MetaObject 的时候。

2、Configuration源码

  1. public class Configuration {
  2. protected ObjectFactory objectFactory;
  3. protected ObjectWrapperFactory objectWrapperFactory;
  4. public Configuration() {
  5. this.objectFactory = new DefaultObjectFactory();
  6. this.objectWrapperFactory = new DefaultObjectWrapperFactory();
  7. }
  8. public MetaObject newMetaObject(Object object) {
  9. return MetaObject.forObject(object, this.objectFactory, this.objectWrapperFactory);
  10. }
  11. // ... 省去其他源码
  12. }

3、MetaObject 源码

  1. public static MetaObject forObject(Object object,
  2. ObjectFactory objectFactory,
  3. ObjectWrapperFactory objectWrapperFactory) {
  4. return object == null ?
  5. SystemMetaObject.NULL_META_OBJECT :
  6. new MetaObject(object, objectFactory, objectWrapperFactory);
  7. }

四、优缺点总结

松散了客户端与子模块的耦合关系,使子模块功能的调用更加简单。通过合理使用Facade,可以更好地划分访问的层次。有些方法是对系统外的,有些方法是系统内部使用的,把需要暴露给外部的功能集中到门面中。如果过多的使用外观模式,会让子模块功能的维护变的复杂,一个功能方法改变,会牵扯到多个外观对象的改变。

五、源代码地址

  1. GitHub·地址
  2. https://github.com/cicadasmile/model-arithmetic-parent
  3. GitEE·地址
  4. https://gitee.com/cicadasmile/model-arithmetic-parent

Java描述设计模式(12):外观模式的更多相关文章

  1. C#设计模式(11)——外观模式(Facade Pattern)

    一.引言 在软件开发过程中,客户端程序经常会与复杂系统的内部子系统进行耦合,从而导致客户端程序随着子系统的变化而变化,然而为了将复杂系统的内部子系统与客户端之间的依赖解耦,从而就有了外观模式,也称作 ...

  2. 设计模式之 外观模式详解(Service第三者插足,让action与dao分手)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 各位好,LZ今天给各位分享一 ...

  3. 北风设计模式课程---外观模式(Facade)总结

    北风设计模式课程---外观模式(Facade)总结 一.总结 一句话总结: 不仅要通过视频学,还要看别的博客里面的介绍,搜讲解,搜作用,搜实例 设计模式都是对生活的抽象,比如用户获得装备,我可以先装备 ...

  4. python设计模式之外观模式

    python设计模式之外观模式 系统会随着演化变得非常复杂,最终形成大量的(并且有时是令人迷惑的)类和交互,这种情况并不少见.许多情况下,我们并不想把这种复杂性暴露给客户端.外观设计模式有助于隐藏系统 ...

  5. 每天一个设计模式-2 外观模式(Facade)

    每天一个设计模式-2  外观模式(Facade) 1.生活中的示例 客户想要购买一台电脑,一般有两种方法: 1.自己DIY,客户需要知道组成电脑的所有电子器件,并且需要熟悉那些配件,对客户要求较高. ...

  6. 乐在其中设计模式(C#) - 外观模式(Facade Pattern)

    原文:乐在其中设计模式(C#) - 外观模式(Facade Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 外观模式(Facade Pattern) 作者:webabcd 介绍 ...

  7. 8.4 GOF设计模式三: 外观模式 Facade

    GOF设计模式三: 外观模式 Facade  “现有系统”功能强大.复杂,开发“新系统”需要用到其中一部分,但又要增加一部 分新功能,该怎么办?4.1 Facade Pattern: Key Fea ...

  8. js设计模式——2.外观模式

    js设计模式——2.外观模式

  9. Java设计模式12:常用设计模式之外观模式(结构型模式)

    1. Java之外观模式(Facade Pattern) (1)概述:       现代的软件系统都是比较复杂的,设计师处理复杂系统的一个常见方法便是将其"分而治之",把一个系统划 ...

随机推荐

  1. prototype原型

    1.prototype是函数的一个属性,并且是函数的原型对象.引用它的必然是函数[对象都是通过函数创建的], 这个prototype的属性值是一个对象(属性的集合,再次强调!),默认的只有一个叫做co ...

  2. django基础之day10,cookie session token

    https://www.cnblogs.com/Dominic-Ji/p/10886902.html cookie session token

  3. 为什么要使用Unix时间戳

    概念: UNIX时间戳:Unix时间戳(英文为Unix epoch, Unix time, POSIX time 或 Unix timestamp) 是从1970年1月1日(UTC/GMT的午夜)开始 ...

  4. 【AHOI 2013】差异

    Problem Description 给定一个长度为 \(n\) 的字符串 \(S\),令 \(T_i\) 表示它从第 \(i\) 个字符开始的后缀.求 \(\sum_{1\leqslant i&l ...

  5. Cesium专栏-terrain地形、3dtiles模型、gltf模型 高度采样

    在Cesium中,对于terrain地形.3dtiles模型.gltf模型的高度采样是一个很基本的功能,基于此,可以做一些深度应用,而Cesium已经帮我们提供了相应的API,在这里,我帮大家总结一下 ...

  6. 关于选用ccflow你所担心的问题都在这里为您解答

    致ccflow客户 感谢大家ccbpm的认可,我们会一如既往的以踏实的技术来回应大家的支持. 针对大家疑问最多的几个问题,在这里我我为大家一一解答. 代码一直在更新,不稳定问题 版本控制我们做的差,是 ...

  7. JavaWeb中实现通过邮箱找回密码

    在开发JavaWeb项目中,利用邮箱帮用户找回密码.效果展示:   需要一个发送邮件的jar包 : javax.mail .jar1.JSP页面(设置邮箱输入框) HTML: <p >请输 ...

  8. linux 动态链接库查找方法;查找动态链接库位置; LIBRARY_PATH 和 LD_LIBRARY_PATH 的区别;LD_LIBRARY_PATH and LD_RUN_PATH的区别;

    今天配置之前项目的时候,发现有些动态链接库变了,想看看现在应用在使用哪些动态链接库的时候,进一步查了点资料: 下面针对linux动态链接库查找方法和动态链接库位置配置的过程进行记录: LIBRARY_ ...

  9. 代码管理平台之svn

    yum install -y subversion(server和client均安装subversion) configure svn:[root@node01 ~]# mkdir -p /data/ ...

  10. 什么是spring框架?spring特点与好处,使用spring框架的好处是什么?

    转载:https://blog.csdn.net/hht006158/article/details/80181207. Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Ja ...