設計模式之外觀模式(Facade)詳解及代碼示例


一、外觀模式的定義

  外觀(Facade)模式的定義:又叫門面模式,是一種通過為多個復雜的子系統提供一個一致的接口,而使這些子系統更加容易被訪問的模式。該模式對外有一個統一接口,外部應用程序不用關心內部子系統的具體的細節,這樣會大大降低應用程序的復雜度,提高了程序的可維護性。

二、外觀模式優缺點

  優點:

  • 簡化了調用過程,無需了解深入子系統,防止帶來風險
  • 減少系統依賴、松散耦合
  • 更好的划分訪問層次
  • 符合迪米特法則,即最少知道原則

  缺點:

  • 增加子系統、擴展子系統行為容易引入風險
  • 不符合開閉原則

三、外觀模式的實現

  外觀(Facade)模式的結構比較簡單,主要是定義了一個高層接口。它包含了對各個子系統的引用,客戶端可以通過它訪問各個子系統的功能。現在來分析其基本結構和實現方法。

  外觀(Facade)模式包含以下主要角色。

  • 外觀(Facade)角色:為多個子系統對外提供一個共同的接口。
  • 子系統(Sub System)角色:實現系統的部分功能,客戶可以通過外觀角色訪問它。
  • 客戶(Client)角色:通過一個外觀角色訪問各個子系統的功能。

  其結構圖如圖所示:

              

  代碼常見有兩種情況都是屬於外觀模式,如下代碼:

  所有子系統實現統一接口:

public interface System {
    public void dosomething();
}

public class SubSystemA implements System {

    public void dosomething() {
        System.out.println("子系統方法A");
    }
}

public class SubSystemB implements System {

    public void dosomething() {
        System.out.println("子系統方法B");
    }
}

public class Facade {

    //被委托的對象
    System a,b;
    
    public Facade() {
        a = new SubSystemA();
        b = new SubSystemB();
    }
    
    //提供給外部訪問的方法
    public void methodA() {
        this.a.dosomething();
    }
    
    public void methodB() {
        this.b.dosomething();
    }
}

public class Client {

    public static void main(String[] args) {
        Facade facade = new Facade();
        
        facade.methodA();
        facade.methodB();
    }
}

  所有子系統未實現統一接口:

public class SubSystemA {

    public void dosomethingA() {
        System.out.println("子系統方法A");
    }
}

public class SubSystemB {

    public void dosomethingB() {
        System.out.println("子系統方法B");
    }
}

public class Facade {

    //被委托的對象
    SubSystemA a;
    SubSystemB b;
    
    public Facade() {
        a = new SubSystemA();
        b = new SubSystemB();
    }
    
    //提供給外部訪問的方法
    public void methodA() {
        this.a.dosomethingA();
    }
    
    public void methodB() {
        this.b.dosomethingB();
    }
}

public class Client {

    public static void main(String[] args) {
        Facade facade = new Facade();
        
        facade.methodA();
        facade.methodB();
    }
}

  測試結果如下:

子系統方法A
子系統方法B

四、外觀模式的應用場景

  通常在以下情況下可以考慮使用外觀模式。

  • 子系統越來越復雜,增加外觀模式提供簡單接口調用
  • 構建多層系統結構,利用外觀對象作為每層的入口,簡化層間調用

五、外觀模式的擴展

  在外觀模式中,當增加或移除子系統時需要修改外觀類,這違背了“開閉原則”。如果引入抽象外觀類,則在一定程度上解決了該問題,其結構圖如圖所示:
           

  代碼如下:

public class FacadePattern
{
    public static void main(String[] args)
    {
        Facade f=new FacadeImpl1();
        f.method();
        f=new FacadeImpl2();
        f.method();
    }
}

interface Facade {
    public void method();
}

//外觀角色
class FacadeImpl1 implements Facede
{
    private SubSystem01 obj1=new SubSystem01();
    private SubSystem02 obj2=new SubSystem02();
    private SubSystem03 obj3=new SubSystem03();
    public void method()
    {
        obj1.method1();
        obj2.method2();
        obj3.method3();
    }
}
//外觀角色
class FacadeImpl1 implements Facede
{
    private SubSystem02 obj2=new SubSystem02();
    private SubSystem03 obj3=new SubSystem03();
    private SubSystem04 obj4=new SubSystem04();
    public void method()
    {
        obj2.method2();
        obj3.method3();
        obj4.method4();
    }
}

//子系統角色
class SubSystem01
{
    public  void method1()
    {
        System.out.println("子系統01的method1()被調用!");
    }   
}
//子系統角色
class SubSystem02
{
    public  void method2()
    {
        System.out.println("子系統02的method2()被調用!");
    }   
}
//子系統角色
class SubSystem03
{
    public  void method3()
    {
        System.out.println("子系統03的method3()被調用!");
    }   
}
//子系統角色
class SubSystem04
{
    public  void method4()
    {
        System.out.println("子系統04的method4()被調用!");
    }   
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM