Java描述設計模式(12):外觀模式

  • 2019 年 10 月 4 日
  • 筆記

一、生活場景

1、場景描述

在移動互聯網沒有普及之前,去飯店吃飯的流程大致如下:選座位,排隊,點菜,結賬。後來移動互聯網普及,通過手機APP就可以操作這些流程,非常的方便快捷:通過手機可以知道某飯店是不是還有空位,到了飯店之後直接入座,然後通過手機點菜,結賬,中間省去了很多繁瑣的流程。

2、程式碼圖解

3、程式碼實現

/**   * 外觀模式描述飯店就餐流程   */  public class C01_InScene {      public static void main(String[] args) {          EatAppFacade eatAppFacade = new EatAppFacade () ;          eatAppFacade.dining();      }  }  // 預定  class Booking {      private static Booking booking = new Booking() ;      public static Booking getInstance (){          return booking ;      }      public void bookPlace (){          System.out.println("位置預定...");      }  }  // 點餐  class TakeOrder {      private static TakeOrder takeOrder = new TakeOrder ();      public static TakeOrder getInstance (){          return takeOrder ;      }      public void orderDishes (){          System.out.println("點餐...");      }  }  // 付款  class Payment {      private static Payment payment = new Payment () ;      public static Payment getInstance (){          return payment ;      }      public void payMoney (){          System.out.println("結賬...");      }  }  // 點餐APP  class EatAppFacade {      private Booking booking ;      private TakeOrder takeOrder ;      private Payment payment ;      public EatAppFacade (){          this.booking = Booking.getInstance() ;          this.takeOrder = TakeOrder.getInstance() ;          this.payment = Payment.getInstance() ;      }      // 就餐流程      public void dining (){          booking.bookPlace();          takeOrder.orderDishes();          payment.payMoney();      }  }  

二、外觀設計模式

1、基本簡介

外觀模式是對象的結構模式,客戶端與一個子系統的通訊必須通過一個統一的外觀對象進行。外觀模式提供一個高層次的介面,使得子系統更易於使用。

2、模式圖解

3、核心角色

  • 外觀角色

客戶端可以調用這個角色的方法。此角色具有相關的子模組的功能。在正常情況下,本角色會將所有從客戶端發來的請求委派到相應的子系統去。

  • 子模組角色

可以同時有一個或者多個子模組。每個子模組都不是一個單獨的類,而是一個類的集合(如上面的子模組就是由ModuleA、ModuleB、ModuleC三個類組合而成)。每個子系統都可以被客戶端直接調用,或者被外觀角色調用。子模組並不知道外觀的存在,對於子模組而言,外觀角色僅僅是另外一個客戶端。

  • 客戶端角色

外觀對象功能的調用者。

4、源程式碼實現

public class C02_Facade {      public static void main(String[] args) {          Facade facade = new Facade();          facade.clientNeed1();          facade.clientNeed2();      }  }  class ModuleA {      public void testA (){          System.out.println("ModuleA.testA()");      }  }  class ModuleB {      public void testB (){          System.out.println("ModuleB.testB()");      }  }  class ModuleC {      public void testC (){          System.out.println("ModuleC.testC()");      }  }  class Facade {      /**       * 客戶需求1       */      public void clientNeed1 (){          ModuleA moduleA = new ModuleA();          moduleA.testA();          ModuleB moduleB = new ModuleB();          moduleB.testB();      }      /**       * 客戶需求1       */      public void clientNeed2 (){          ModuleB moduleB = new ModuleB();          moduleB.testB();          ModuleC moduleC = new ModuleC();          moduleC.testC();      }  }  

三、Mybatis應用場景

1、使用場景

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

Configuration 創建 MetaObject 的時候。

2、Configuration源碼

public class Configuration {      protected ObjectFactory objectFactory;      protected ObjectWrapperFactory objectWrapperFactory;      public Configuration() {          this.objectFactory = new DefaultObjectFactory();          this.objectWrapperFactory = new DefaultObjectWrapperFactory();      }      public MetaObject newMetaObject(Object object) {          return MetaObject.forObject(object, this.objectFactory, this.objectWrapperFactory);      }      // ... 省去其他源碼  }  

3、MetaObject 源碼

public static MetaObject forObject(Object object,                                     ObjectFactory objectFactory,                                     ObjectWrapperFactory objectWrapperFactory) {      return object == null ?              SystemMetaObject.NULL_META_OBJECT :              new MetaObject(object, objectFactory, objectWrapperFactory);  }  

四、優缺點總結

鬆散了客戶端與子模組的耦合關係,使子模組功能的調用更加簡單。通過合理使用Facade,可以更好地劃分訪問的層次。有些方法是對系統外的,有些方法是系統內部使用的,把需要暴露給外部的功能集中到門面中。如果過多的使用外觀模式,會讓子模組功能的維護變的複雜,一個功能方法改變,會牽扯到多個外觀對象的改變。

五、源程式碼地址

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