Java描述设计模式(12):外观模式

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

一、生活场景

1、场景描述

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

2、代码图解

3、代码实现

1/** 2 * 外观模式描述饭店就餐流程 3 */ 4public class C01_InScene { 5 public static void main(String[] args) { 6 EatAppFacade eatAppFacade = new EatAppFacade () ; 7 eatAppFacade.dining(); 8 } 9} 10// 预定 11class 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// 点餐 21class 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// 付款 31class 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 41class 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、源代码实现

1public class C02_Facade { 2 public static void main(String[] args) { 3 Facade facade = new Facade(); 4 facade.clientNeed1(); 5 facade.clientNeed2(); 6 } 7} 8class ModuleA { 9 public void testA (){ 10 System.out.println("ModuleA.testA()"); 11 } 12} 13class ModuleB { 14 public void testB (){ 15 System.out.println("ModuleB.testB()"); 16 } 17} 18class ModuleC { 19 public void testC (){ 20 System.out.println("ModuleC.testC()"); 21 } 22} 23class 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源码

1public 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 源码

1public 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,可以更好地划分访问的层次。有些方法是对系统外的,有些方法是系统内部使用的,把需要暴露给外部的功能集中到门面中。如果过多的使用外观模式,会让子模块功能的维护变的复杂,一个功能方法改变,会牵扯到多个外观对象的改变。

五、源代码地址

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

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

Java描述设计模式(15):责任链模式

本文源码:GitHub·点这里(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.com%2Fcicadasmile%2Fmodelarithmeticparent)||GitEE·点这里(https://gitee.com/cicadasmile/modela

Java描述设计模式(21):状态模式

本文源码:GitHub·点这里(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.com%2Fcicadasmile%2Fmodelarithmeticparent)||GitEE·点这里(https://gitee.com/cicadasmile/modela