Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> java/android 設計模式學習筆記(14)---外觀模式

java/android 設計模式學習筆記(14)---外觀模式

編輯:關於Android編程

這篇博客來介紹外觀模式(Facade Pattern),外觀模式也稱為門面模式,它在開發過程中運用頻率非常高,尤其是第三方 SDK 基本很大概率都會使用外觀模式。通過一個外觀類使得整個子系統只有一個統一的高層的接口,這樣能夠降低用戶的使用成本,也對用戶屏蔽了很多實現細節。當然,在我們的開發過程中,外觀模式也是我們封裝 API 的常用手段,例如網絡模塊、ImageLoader 模塊等。其實我們在開發過程中可能已經使用過很多次外觀模式,只是沒有從理論層面去了解它。

特點

外觀模式提供一個統一的接口,用來訪問子系統中的一群接口,外觀定義了一個高層接口,讓子系統更容易使用。
  外觀模式的使用場景:

為一個復雜子系統提供一個簡單接口。Facade 可以提供一個簡單統一的接口,對外隱藏子系統的具體實現、隔離變化。當需要構建一個層次結構的子系統時,使用 Facade 模式定義子系統中每層的入口點。如果子系統之間是相互依賴,你可以讓他們僅通過 Facade 接口進行通信,從而簡化了它們之間的依賴關系。  外觀模式簡化了接口,並且同時允許我們讓客戶端和子系統之間避免緊耦合。

 

UML類圖

外觀模式沒有一個一般化的類圖描述,我們先用一個結構圖來說明:
  這裡寫圖片描述
根據結構圖抽象出一個類圖:
這裡寫圖片描述vcfJq6O6PC9wPg0KRmFjYWRlIL3Hyaujus+1zbO21M3itcTNs9K7vdO/2qOsv827p7bLway909fTz7XNs7mmxNy1xMjrv9qho9fTz7XNs73HyaujqFN1YlN5c3RlbaOpvcfJq6O6v8nS1M2syrHT0NK7uPa78tXftuC49tfTz7XNs6Osw7+49tfTz7XNs7a8srvKx9K7uPa1pbbAtcTA4KOstvjKx9K7uPbA4LXEvK+6z6Gjw7+49tfTz7XNs7a8v8nS1LG7v827p7bL1rG907X308OjrLvy1d+xu8PFw+a9x8mrtffTw6Gj19PPtc2zsqKyu9aqtcDDxcPmtcS05tTao6y21NPa19PPtc2ztvjR1KOsw8XD5r32vfbKx8HtzeLSu7j2v827p7bLtvjS0aGjztLDx7j5vt3Jz8PmtcQgdW1sIMDgzby/ydLU0LSz9s3iudvEo8q9tcTNqNPDtPrC66O6PGJyIC8+DQo8c3Ryb25nPtfTz7XNs6O6PC9zdHJvbmc+DQo8cD4mbmJzcDs8L3A+DQo8cHJlIGNsYXNzPQ=="brush:java;"> public class SystemA { public void operation1(){ System.out.print("SystemA:operation1\n"); } public void operation2(){ System.out.print("SystemA:operation2\n"); } public void operation3(){ System.out.print("SystemA:operation3\n"); } }

public class SystemB {

    public void operation1(){
        System.out.print("SystemB:operation1\n");
    }

    public void operation2(){
        System.out.print("SystemB:operation2\n");
    }

    public void operation3(){
        System.out.print("SystemB:operation3\n");
    }
}
public class SystemC {
    public void operation1(){
        System.out.print("SystemC:operation1\n");
    }

    public void operation2(){
        System.out.print("SystemC:operation2\n");
    }

    public void operation3(){
        System.out.print("SystemC:operation3\n");
    }
}

然後是外觀對象 IFacade.class

public interface IFacade {
    void operationA();

    void operationB();

    void operationC();
}

Facade.class

public class Facade implements IFacade{

    private SystemA systemA = new SystemA();
    private SystemB systemB = new SystemB();
    private SystemC systemC = new SystemC();

    @Override
    public void operationA() {
        systemA.operation1();
        systemB.operation2();
        systemC.operation3();
    }

    @Override
    public void operationB() {
        systemA.operation2();
        systemB.operation1();
        systemC.operation3();
    }

    @Override
    public void operationC() {
        systemC.operation1();
        systemB.operation2();
        systemA.operation3();
    }
}

最後的測試代碼:

public static void main(String args[]) {
    IFacade facade = new Facade();
    facade.operationA();
    facade.operationB();
    facade.operationC();
}

結果輸出如下:
這裡寫圖片描述

示例與源碼

這裡直接展示一段簡單電腦啟動時的偽代碼來表示即可:

/* Complex parts */

class CPU {
    public void freeze() { ... }
    public void jump(long position) { ... }
    public void execute() { ... }
}

class Memory {
    public void load(long position, byte[] data) { ... }
}

class HardDrive {
    public byte[] read(long lba, int size) { ... }
}

/* Facade */

class ComputerFacade {
    private CPU processor;
    private Memory ram;
    private HardDrive hd;

    public ComputerFacade() {
        this.processor = new CPU();
        this.ram = new Memory();
        this.hd = new HardDrive();
    }

    public void start() {
        processor.freeze();
        ram.load(BOOT_ADDRESS, hd.read(BOOT_SECTOR, SECTOR_SIZE));
        processor.jump(BOOT_ADDRESS);
        processor.execute();
    }
}

/* Client */

class You {
    public static void main(String[] args) {
        ComputerFacade computer = new ComputerFacade();
        computer.start();
    }
}

總結

外觀模式是一個高頻率使用的設計模式,它的精髓就在於封裝二字。通過一個高層次結構為用戶提供統一的 API 入口,使得用戶通過一個類型就基本能夠操作整個系統,這樣減少了用戶的使用成本,也能夠提升系統的靈活性。
  外觀類遵循了一個很重要設計模式原則:迪米特原則(最少知識原則),它讓客戶端依賴於最少的類,直接依賴外觀類而不是依賴於所有的子系統類。
  優點:

對客戶程序隱藏子系統細節,因而減少了客戶對於子系統的耦合,能夠擁抱變化;外觀類對子系統的接口封裝,使得系統更易於使用;更好的劃分訪問層次,通過合理使用Facade,可以幫助我們更好地劃分訪問的層次。有些方法是對系統外的,有些方法是系統內部使用的。把需要暴露給外部的功能集中到外觀類中,這樣既方便客戶端使用,也很好地隱藏了內部的細節。  缺點:外觀類接口膨脹,由於子系統的接口都由外觀類統一對外暴露,使得外觀類的 API 接口較多,在一定程度上增加了用戶使用成本;外觀類沒有遵循開閉原則,當業務出現變更時,可能需要直接修改外觀類。

 

適配器 VS 裝飾者 VS 橋接 VS 代理 VS 外觀

這幾個都是結構型設計模式,他們有些類似,在實際使用過程中也容易搞混,我們在這就給他們做一個對比:

適配器模式

適配器模式和其他三個設計模式一般不容易搞混,它的作用是將原來不兼容的兩個類融合在一起,uml 圖也和其他的差別很大。
  uml 類圖:
  這裡寫圖片描述

裝飾者模式

裝飾者模式結構上類似於代理模式,但是和代理模式的目的是不一樣的,裝飾者是用來動態地給一個對象添加一些額外的職責,裝飾者模式為對象加上行為,而代理則是控制訪問。
  uml 類圖:
  這裡寫圖片描述

橋接模式

橋接模式的目的是為了將抽象部分與實現部分分離,使他們都可以獨立地進行變化,所以說他們兩個部分是獨立的,沒有實現自同一個接口,這是橋接模式與代理模式,裝飾者模式的區別。
  uml 類圖:
  這裡寫圖片描述

代理模式

代理模式為另一個對象提供代表,以便控制客戶對對象的訪問,管理的方式有很多種,比如遠程代理和虛擬代理等,這個在上面有,這裡就不說了,而裝飾者模式則是為了擴展對象。
  uml 類圖:
  這裡寫圖片描述

外觀模式

外觀模式提供一個統一的接口,用來訪問子系統中的一群接口。外觀定義了一個高層接口,讓子系統更容易使用。
  適配器模式將一個或多個類接口變成客戶端所期望的一個接口,雖然大多數資料所采用的例子中適配器只適配一個類,但是你可以適配許多類來提供一個接口讓客戶端訪問;類似的,外觀模式 也可以只針對一個擁有復雜接口的類提供簡化的接口,兩種模式的差異,不在於他們“包裝”了幾個類,而是在於它們的意圖。適配器模式 的意圖是,“改變”接口符合客戶的期望;而外觀模式的意圖是,提供子系統的一個簡化接口。
  uml類圖:
  這裡寫圖片描述

源碼下載

https://github.com/zhaozepeng/Design-Patterns/tree/master/FacadePattern

 
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved