前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >外观模式

外观模式

作者头像
帅飞
发布2019-01-22 17:23:57
4460
发布2019-01-22 17:23:57
举报
文章被收录于专栏:Java知其所以然Java知其所以然

外观模式遵守的面向对象的原则之一:迪米特法则。

外观模式也叫门面模式。

迪米特法则(最少知道法则)

一个软件实体应当尽可能少的与其他实体直接发生相互作用(耦合)。

核心思想

为子系统提供统一的入口封装子系统的复杂性,便于客户端调用。在一个由多个模块组成的系统中,模块与模块之间就可以通过提供外观模式来进行数据的交互,每个模块只需要暴漏出其他模块感兴趣的数据,这样就达到了各个模块之间数据的隔离。(这就很满足封装的特性:只暴露该暴漏的,其他的就隐藏起来)

在我们生活中其实也处处体现了这种思想。比如:手机运行需要主板、电池、声卡等,但我们在玩手机时只需要对屏幕操作就行了。这就是手机厂商为我们提供的统一的入口,把具体执行流程的复杂性封装了起来。我们只需要和这个统一入口打交道。

角色

  • Facade: 外观角色
  • SubSystem:子系统角色

UML 图

代码示例

子系统角色

代码语言:javascript
复制
  public class SystemA {
  
      public void operatorA() {
          System.out.println("operatorA finish");
      }
  }
  
  public class SystemB {
  
      public void operatorB() {
          System.out.println("operatorB finish");
      }
  }
  
  public class SystemC {
  
      public void operatorC() {
          System.out.println("operatorC finish");
      }
  }

外观角色

代码语言:javascript
复制
  public class OperatorFacade {
      public void wrapOperator(){
          SystemA a = new SystemA();
          a.operatorA();
          SystemB b = new SystemB();
          b.operatorB();
          SystemC c = new SystemC();
          c.operatorC();
      }
  }

测试类

假设我们在开发一个产品,开发某个功能需要用到 SystemA、SystemB、SystemC 三个子系统的操作才可以完成。

代码语言:javascript
复制
  public class Client {
      public static void main(String[] args) {
          // 没有使用外观模式完成这个功能
          SystemA a = new SystemA();
          a.operatorA();
          SystemB b = new SystemB();
          b.operatorB();
          SystemC c = new SystemC();
          c.operatorC();
          
          // 使用外观模式完成这个功能
          new OperatorFacade().operator();    
          
      }
  }

很明显在没有使用外观模式时,我们完成一个功能需要和多个子系统直接耦合在一起,而且调用关系复杂。

开发中常见的场景

  • commons 提供的 DBUtils 类,把数据库连接、驱动加载、增删改查等都封装起来,提供一个统一的接口供我们使用,我们在写代码时只需要调接口中提供的方法就可以了。
  • tomcat 中使用了大量的外观模式(比如:HttpRequestFacade),不过它的巧妙之处在于只将别的模块感兴趣的数据封装起来,通过外观模式对其他模块提供。

优点

  • 对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易。通过引入外观模式,客户代码将变得很简单,与之关联的对象也很少。
  • 实现了子系统与客户之间的松耦合关系,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整外观类即可。

缺点

  • 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了"开闭原则"。

总结

解耦客户端和子系统之间的关系,更好的封装。方便模块与模块之间的数据交互。

参考链接:https://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/facade.html

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-01-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java知其所以然 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 迪米特法则(最少知道法则)
  • 核心思想
    • 角色
      • UML 图
      • 代码示例
      • 开发中常见的场景
      • 优点
      • 缺点
      • 总结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档