設(shè)計模式--外觀模式(Facade)

外觀模式(Facade)

在現(xiàn)實生活中,常常存在辦事較復雜的例子,如辦房產(chǎn)證或注冊一家公司,有時要同多個部門聯(lián)系,這時要是有一個綜合部門能解決一切手續(xù)問題就好了。

軟件設(shè)計也是這樣,當一個系統(tǒng)的功能越來越強,子系統(tǒng)會越來越多,客戶對系統(tǒng)的訪問也變得越來越復雜。這時如果系統(tǒng)內(nèi)部發(fā)生改變,客戶端也要跟著改變,這違背了“開閉原則”,也違背了“迪米特法則”,所以有必要為多個子系統(tǒng)提供一個統(tǒng)一的接口,從而降低系統(tǒng)的耦合度,這就是外觀模式的目標。

外觀模式的定義與特點

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

  • 外觀(Facade)模式的優(yōu)點:
    1.降低了子系統(tǒng)與客戶端之間的耦合度,使得子系統(tǒng)的變化不會影響調(diào)用它的客戶類。
    2.對客戶屏蔽了子系統(tǒng)組件,減少了客戶處理的對象數(shù)目,并使得子系統(tǒng)使用起來更加容易。
    3.降低了大型軟件系統(tǒng)中的編譯依賴性,簡化了系統(tǒng)在不同平臺之間的移植過程,因為編譯一個子系統(tǒng)不會影響其他的子系統(tǒng),也不會影響外觀對象。

  • 外觀(Facade)模式的缺點:
    1.不能很好地限制客戶使用子系統(tǒng)類。
    2.增加新的子系統(tǒng)可能需要修改外觀類或客戶端的源代碼,違背了“開閉原則”。

外觀模式的結(jié)構(gòu)與實現(xiàn)

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

1. 模式的結(jié)構(gòu)

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

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

其結(jié)構(gòu)圖如圖 2 所示。


圖2 外觀(Facade)模式的結(jié)構(gòu)圖
2. 模式的實現(xiàn)

外觀模式的實現(xiàn)代碼如下:

package facade;
public class FacadePattern
{
    public static void main(String[] args)
    {
        Facade f=new Facade();
        f.method();
    }
}
//外觀角色
class Facade
{
    private SubSystem01 obj1=new SubSystem01();
    private SubSystem02 obj2=new SubSystem02();
    private SubSystem03 obj3=new SubSystem03();
    public void method()
    {
        obj1.method1();
        obj2.method2();
        obj3.method3();
    }
}
//子系統(tǒng)角色
class SubSystem01
{
    public  void method1()
    {
        System.out.println("子系統(tǒng)01的method1()被調(diào)用!");
    }   
}
//子系統(tǒng)角色
class SubSystem02
{
    public  void method2()
    {
        System.out.println("子系統(tǒng)02的method2()被調(diào)用!");
    }   
}
//子系統(tǒng)角色
class SubSystem03
{
    public  void method3()
    {
        System.out.println("子系統(tǒng)03的method3()被調(diào)用!");
    }   
}

程序運行結(jié)果如下:

子系統(tǒng)01的method1()被調(diào)用!
子系統(tǒng)02的method2()被調(diào)用!
子系統(tǒng)03的method3()被調(diào)用!

外觀模式的實例

我們將創(chuàng)建一個 Shape 接口和實現(xiàn)了 Shape 接口的實體類。下一步是定義一個外觀類 ShapeMaker。
ShapeMaker 類使用實體類來代表用戶對這些類的調(diào)用。FacadePatternDemo,我們的演示類使用 ShapeMaker 類來顯示結(jié)果。

image

1.創(chuàng)建一個接口。Shape.java

public interface Shape {
   void draw();
}

2.創(chuàng)建實現(xiàn)接口的實體類。Rectangle.java、Square.java、Circle.java

public class Rectangle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Rectangle::draw()");
   }
}

public class Square implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Square::draw()");
   }
}

public class Circle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Circle::draw()");
   }
}

3.創(chuàng)建一個外觀類。ShapeMaker.java

public class ShapeMaker {
   private Shape circle;
   private Shape rectangle;
   private Shape square;
 
   public ShapeMaker() {
      circle = new Circle();
      rectangle = new Rectangle();
      square = new Square();
   }
 
   public void drawCircle(){
      circle.draw();
   }
   public void drawRectangle(){
      rectangle.draw();
   }
   public void drawSquare(){
      square.draw();
   }
}

4.使用該外觀類畫出各種類型的形狀。FacadePatternDemo.java

public class FacadePatternDemo {
   public static void main(String[] args) {
      ShapeMaker shapeMaker = new ShapeMaker();
 
      shapeMaker.drawCircle();
      shapeMaker.drawRectangle();
      shapeMaker.drawSquare();      
   }
}

程序運行結(jié)果如下:

子系統(tǒng)01的method1()被調(diào)用!
子系統(tǒng)02的method2()被調(diào)用!
子系統(tǒng)03的method3()被調(diào)用!

外觀模式的應(yīng)用場景

  • 對分層結(jié)構(gòu)系統(tǒng)構(gòu)建時,使用外觀模式定義子系統(tǒng)中每層的入口點可以簡化子系統(tǒng)之間的依賴關(guān)系。
  • 當一個復雜系統(tǒng)的子系統(tǒng)很多時,外觀模式可以為系統(tǒng)設(shè)計一個簡單的接口供外界訪問。
  • 當客戶端與多個子系統(tǒng)之間存在很大的聯(lián)系時,引入外觀模式可將它們分離,從而提高子系統(tǒng)的獨立性和可移植性。

外觀模式的擴展

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


引入抽象外觀類的外觀模式的結(jié)構(gòu)圖
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容