本文源碼:GitHub·點這裏 || GitEE·點這裏git
在移動互聯網沒有普及以前,去飯店吃飯的流程大體以下:選座位,排隊,點菜,結帳。後來移動互聯網普及,經過手機APP就能夠操做這些流程,很是的方便快捷:經過手機能夠知道某飯店是否是還有空位,到了飯店以後直接入座,而後經過手機點菜,結帳,中間省去了不少繁瑣的流程。
/** * 外觀模式描述飯店就餐流程 */ 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(); } }
外觀模式是對象的結構模式,客戶端與一個子系統的通訊必須經過一個統一的外觀對象進行。外觀模式提供一個高層次的接口,使得子系統更易於使用。
客戶端能夠調用這個角色的方法。此角色具備相關的子模塊的功能。在正常狀況下,本角色會將全部從客戶端發來的請求委派到相應的子系統去。
能夠同時有一個或者多個子模塊。每一個子模塊都不是一個單獨的類,而是一個類的集合(如上面的子模塊就是由ModuleA、ModuleB、ModuleC三個類組合而成)。每一個子系統均可以被客戶端直接調用,或者被外觀角色調用。子模塊並不知道外觀的存在,對於子模塊而言,外觀角色僅僅是另一個客戶端。
外觀對象功能的調用者。
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(); } }
Configuration 建立 MetaObject 的時候。github
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); } // ... 省去其餘源碼 }
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