欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java設(shè)計(jì)模式之java外觀模式詳解

 更新時(shí)間:2021年09月15日 15:51:02   作者:大忽悠愛(ài)忽悠  
這篇文章主要介紹了Java設(shè)計(jì)模式之外觀模式(Facade模式)介紹,外觀模式(Facade)的定義:為子系統(tǒng)中的一組接口提供一個(gè)一致的界面,需要的朋友可以參考下

模式動(dòng)機(jī)

在這里插入圖片描述

引入外觀角色之后,用戶只需要直接與外觀角色交互,用戶與子系統(tǒng)之間的復(fù)雜關(guān)系由外觀角色來(lái)實(shí)現(xiàn),從而降低了系統(tǒng)的耦合度。

在這里插入圖片描述

模式定義

外觀模式是一種使用頻率非常高的結(jié)構(gòu)型設(shè)計(jì)模式,它通過(guò)引入一個(gè)外觀角色來(lái)簡(jiǎn)化客戶端與子系統(tǒng)之間的交互,為復(fù)雜的子系統(tǒng)調(diào)用提供一個(gè)統(tǒng)一的入口,降低子系統(tǒng)與客戶端的耦合度,且客戶端調(diào)用非常方便。

外觀模式又稱為門面模式,它是一種對(duì)象結(jié)構(gòu)型模式。外觀模式是迪米特法則的一種具體實(shí)現(xiàn),通過(guò)引入一個(gè)新的外觀角色可以降低原有系統(tǒng)的復(fù)雜度,同時(shí)降低客戶類與子系統(tǒng)的耦合度。

模式結(jié)構(gòu)

在這里插入圖片描述

角色

  • Facade(外觀角色):在客戶端可以調(diào)用它的方法,在外觀角色中可以知道相關(guān)的(一個(gè)或者多個(gè))子系統(tǒng)的功能和責(zé)任;在正常情況下,它將所有從客戶端發(fā)來(lái)的請(qǐng)求委派到相應(yīng)的子系統(tǒng)去,傳遞給相應(yīng)的子系統(tǒng)對(duì)象處理。
  • SubSystem(子系統(tǒng)角色):在軟件系統(tǒng)中可以有一個(gè)或者多個(gè)子系統(tǒng)角色,每一個(gè)子系統(tǒng)可以不是一個(gè)單獨(dú)的類,而是一個(gè)類的集合,它實(shí)現(xiàn)子系統(tǒng)的功能;每一個(gè)子系統(tǒng)都可以被客戶端直接調(diào)用,或者被外觀角色調(diào)用,它處理由外觀類傳過(guò)來(lái)的請(qǐng)求;子系統(tǒng)并不知道外觀的存在,對(duì)于子系統(tǒng)而言,外觀角色僅僅是另外一個(gè)客戶端而已。

外觀模式的目的不是給予子系統(tǒng)添加新的功能接口,而是為了讓外部減少與子系統(tǒng)內(nèi)多個(gè)模塊的交互,松散耦合,從而讓外部能夠更簡(jiǎn)單地使用子系統(tǒng)。

外觀模式的本質(zhì)是:封裝交互,簡(jiǎn)化調(diào)用。

模式分析

根據(jù)“單一職責(zé)原則”,在軟件中將一個(gè)系統(tǒng)劃分為若干個(gè)子系統(tǒng)有利于降低整個(gè)系統(tǒng)的復(fù)雜性,一個(gè)常見(jiàn)的設(shè)計(jì)目標(biāo)是使子系統(tǒng)間的通信和相互依賴關(guān)系達(dá)到最小,而達(dá)到該目標(biāo)的途徑之一就是引入一個(gè)外觀對(duì)象,它為子系統(tǒng)的訪問(wèn)提供了一個(gè)簡(jiǎn)單而單一的入口。

外觀模式也是“迪米特法則”的體現(xiàn),通過(guò)引入一個(gè)新的外觀類可以降低原有系統(tǒng)的復(fù)雜度,同時(shí)降低客戶類與子系統(tǒng)類的耦合度。

外觀模式要求一個(gè)子系統(tǒng)的外部與其內(nèi)部的通信通過(guò)一個(gè)統(tǒng)一的外觀對(duì)象進(jìn)行,外觀類將客戶端與子系統(tǒng)的內(nèi)部復(fù)雜性分隔開(kāi),使得客戶端只需要與外觀對(duì)象打交道,而不需要與子系統(tǒng)內(nèi)部的很多對(duì)象打交道。

外觀模式的目的在于降低系統(tǒng)的復(fù)雜程度。

外觀模式從很大程度上提高了客戶端使用的便捷性,使得客戶端無(wú)須關(guān)心子系統(tǒng)的工作細(xì)節(jié),通過(guò)外觀角色即可調(diào)用相關(guān)功能。

典型的外觀角色代碼

 public class Facade
  {
      private SubSystemA obj1 = new SubSystemA();
      private SubSystemB obj2 = new SubSystemB();
      private SubSystemC obj3 = new SubSystemC();
      public void method()
      {
          obj1.method();
          obj2.method();
         obj3.method();
     }
 } 

外觀模式實(shí)例與解析

實(shí)例一:電源總開(kāi)關(guān)

現(xiàn)在考察一個(gè)電源總開(kāi)關(guān)的例子,以便進(jìn)一步說(shuō)明外觀模式。為了使用方便,一個(gè)電源總開(kāi)關(guān)可以控制四盞燈、一個(gè)風(fēng)扇、一臺(tái)空調(diào)和一臺(tái)電視機(jī)的啟動(dòng)和關(guān)閉。通過(guò)該電源總開(kāi)關(guān)可以同時(shí)控制上述所有電器設(shè)備,使用外觀模式設(shè)計(jì)該系統(tǒng)

在這里插入圖片描述

//子系統(tǒng)角色
public class Fan 
{
    private Fan(){}
    private static  Fan instance;
    //靜態(tài)代碼塊中創(chuàng)建單例對(duì)象
    static {
        instance=new Fan();
    }
    public static  Fan getInstance()
    {
        return instance;
    }
    public void on()
    {
        System.out.println("風(fēng)扇開(kāi)");
    }
    public  void off()
    {
        System.out.println("風(fēng)扇關(guān)");
    }
}
//子系統(tǒng)角色
public class Light
{
    //靜態(tài)常量
    private static  Light  instance=new Light();;
    //構(gòu)造器私有化
    private  Light(){};
  //共有靜態(tài)方法,返回一個(gè)實(shí)例對(duì)象
    public  static  Light getInstance()
    {
        return instance;
    }
    public  void on()
    {
        System.out.println("燈開(kāi)");
    }
    public  void  off()
    {
        System.out.println("燈關(guān)");
    }
}

//外觀角色
public class GeneralSwitchFaced
{
    private Light light;
    private  Fan fan;
  public GeneralSwitchFaced()
    {
        light=Light.getInstance();
        fan=Fan.getInstance();
    }
    public void on()
    {
        light.on();
        fan.on();
    }
    public void off()
    {
        light.off();
        fan.off();
    }
}
//測(cè)試
public class Test
{
    @org.junit.Test
    public void test()
    {
        GeneralSwitchFaced faced=new GeneralSwitchFaced();
        faced.on();
        faced.off();
    }
}

在這里插入圖片描述

實(shí)例二:文件加密

某系統(tǒng)需要提供一個(gè)文件加密模塊,加密流程包括三個(gè)操作,分別是讀取源文件、加密、保存加密之后的文件。讀取文件和保存文件使用流來(lái)實(shí)現(xiàn),這三個(gè)操作相對(duì)獨(dú)立,其業(yè)務(wù)代碼封裝在三個(gè)不同的類中?,F(xiàn)在需要提供一個(gè)統(tǒng)一的加密外觀類,用戶可以直接使用該加密外觀類完成文件的讀取、加密和保存三個(gè)操作,而不需要與每一個(gè)類進(jìn)行交互,使用外觀模式設(shè)計(jì)該加密模塊。

在這里插入圖片描述

通過(guò)外觀角色的一個(gè)方法,封裝了三個(gè)獨(dú)立的操作過(guò)程,即將文件的加密過(guò)程封裝在了外觀角色的文件加密方法中,客戶通過(guò)調(diào)用該方法即可完成對(duì)文件的加密,無(wú)需挨個(gè)調(diào)用三個(gè)獨(dú)立的操作

模式優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

  • 對(duì)客戶屏蔽子系統(tǒng)組件,減少了客戶處理的對(duì)象數(shù)目并使得子系統(tǒng)使用起來(lái)更加容易。通過(guò)引入外觀模式,客戶代碼將變得很簡(jiǎn)單,與之關(guān)聯(lián)的對(duì)象也很少。
  • 實(shí)現(xiàn)了子系統(tǒng)與客戶之間的松耦合關(guān)系,這使得子系統(tǒng)的組件變化不會(huì)影響到調(diào)用它的客戶類,只需要調(diào)整外觀類即可。
  • 降低了大型軟件系統(tǒng)中的編譯依賴性,并簡(jiǎn)化了系統(tǒng)在不同平臺(tái)之間的移植過(guò)程,因?yàn)榫幾g一個(gè)子系統(tǒng)一般不需要編譯所有其他的子系統(tǒng)。一個(gè)子系統(tǒng)的修改對(duì)其他子系統(tǒng)沒(méi)有任何影響,而且子系統(tǒng)內(nèi)部變化也不會(huì)影響到外觀對(duì)象
  • 只是提供了一個(gè)訪問(wèn)子系統(tǒng)的統(tǒng)一入口,并不影響用戶直接使用子系統(tǒng)類。

缺點(diǎn)

  • 不能很好地限制客戶使用子系統(tǒng)類,如果對(duì)客戶訪問(wèn)子系統(tǒng)類做太多的限制則減少了可變性和靈活性。
  • 在不引入抽象外觀類的情況下,增加新的子系統(tǒng)可能需要修改外觀類或客戶端的源代碼,違背了“開(kāi)閉原則”。

模式適用環(huán)境

  • 當(dāng)要為一個(gè)復(fù)雜子系統(tǒng)提供一個(gè)簡(jiǎn)單接口時(shí)可以使用外觀模式。該接口可以滿足大多數(shù)用戶的需求,而且用戶也可以越過(guò)外觀類直接訪問(wèn)子系統(tǒng)。
  • 客戶程序與多個(gè)子系統(tǒng)之間存在很大的依賴性。引入外觀類將子系統(tǒng)與客戶以及其他子系統(tǒng)解耦,可以提高子系統(tǒng)的獨(dú)立性和可移植性。
  • 在層次化結(jié)構(gòu)中,可以使用外觀模式定義系統(tǒng)中每一層的入口,層與層之間不直接產(chǎn)生聯(lián)系,而通過(guò)外觀類建立聯(lián)系,降低層之間的耦合度。

源碼分析外觀模式的典型應(yīng)用

(1) 外觀模式應(yīng)用于JDBC數(shù)據(jù)庫(kù)操作

 public class JDBCFacade {
     private Connection conn=null;
     private Statement statement=null;
     public void open(String driver,String jdbcUrl,String userName,String userPwd) {
         ......
      }
      public int executeUpdate(String sql) {
         ......
      }
     public ResultSet executeQuery(String sql) {
         ......
     }
     public void close() {
         ......
     }
 }

(2) Session外觀模式是外觀模式在Java EE框架中的應(yīng)用

在這里插入圖片描述

模式擴(kuò)展

一個(gè)系統(tǒng)有多個(gè)外觀類

在外觀模式中,通常只需要一個(gè)外觀類,并且此外觀類只有一個(gè)實(shí)例,換言之它是一個(gè)單例類。在很多情況下為了節(jié)約系統(tǒng)資源,一般將外觀類設(shè)計(jì)為單例類。當(dāng)然這并不意味著在整個(gè)系統(tǒng)里只能有一個(gè)外觀類,在一個(gè)系統(tǒng)中可以設(shè)計(jì)多個(gè)外觀類,每個(gè)外觀類都負(fù)責(zé)和一些特定的子系統(tǒng)交互,向用戶提供相應(yīng)的業(yè)務(wù)功能。

不要試圖通過(guò)外觀類為子系統(tǒng)增加新行為

不要通過(guò)繼承一個(gè)外觀類在子系統(tǒng)中加入新的行為,這種做法是錯(cuò)誤的。外觀模式的用意是為子系統(tǒng)提供一個(gè)集中化和簡(jiǎn)化的溝通渠道,而不是向子系統(tǒng)加入新的行為,新的行為的增加應(yīng)該通過(guò)修改原有子系統(tǒng)類或增加新的子系統(tǒng)類來(lái)實(shí)現(xiàn),不能通過(guò)外觀類來(lái)實(shí)現(xiàn)。

外觀模式與迪米特法則

外觀模式創(chuàng)造出一個(gè)外觀對(duì)象,將客戶端所涉及的屬于一個(gè)子系統(tǒng)的協(xié)作伙伴的數(shù)量減到最少,使得客戶端與子系統(tǒng)內(nèi)部的對(duì)象的相互作用被外觀對(duì)象所取代。外觀類充當(dāng)了客戶類與子系統(tǒng)類之間的“第三者”,降低了客戶類與子系統(tǒng)類之間的耦合度,外觀模式就是實(shí)現(xiàn)代碼重構(gòu)以便達(dá)到“迪米特法則”要求的一個(gè)強(qiáng)有力的武器。

抽象外觀類的引入

外觀模式最大的缺點(diǎn)在于違背了“開(kāi)閉原則”,當(dāng)增加新的子系統(tǒng)或者移除子系統(tǒng)時(shí)需要修改外觀類,可以通過(guò)引入抽象外觀類在一定程度上解決該問(wèn)題,客戶端針對(duì)抽象外觀類進(jìn)行編程。對(duì)于新的業(yè)務(wù)需求,不修改原有外觀類,而對(duì)應(yīng)增加一個(gè)新的具體外觀類,由新的具體外觀類來(lái)關(guān)聯(lián)新的子系統(tǒng)對(duì)象,同時(shí)通過(guò)修改配置文件來(lái)達(dá)到不修改源代碼并更換外觀類的目的。

在這里插入圖片描述

總結(jié)

在這里插入圖片描述

參考文章

外觀模式

java設(shè)計(jì)模式之外觀模式(Facade)

總結(jié)

本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • java字符串的合并

    java字符串的合并

    合并兩個(gè)字符串,如:str1 ="001,002,003,004,006",str2 = "001,002,005" 合并后應(yīng)該是"001,002,003,004,005,006"。
    2008-10-10
  • Java簡(jiǎn)單計(jì)算圓周率完整示例

    Java簡(jiǎn)單計(jì)算圓周率完整示例

    這篇文章主要介紹了Java簡(jiǎn)單計(jì)算圓周率,結(jié)合完整實(shí)例形式分析了Java計(jì)算圓周率的原理與操作技巧,代碼備有較為詳盡的注釋便于理解,需要的朋友可以參考下
    2018-05-05
  • SpringBoot中l(wèi)ogback日志保存到mongoDB的方法

    SpringBoot中l(wèi)ogback日志保存到mongoDB的方法

    這篇文章主要介紹了SpringBoot中l(wèi)ogback日志保存到mongoDB的方法,
    2017-11-11
  • Java實(shí)現(xiàn)連接kubernates集群的兩種方式詳解

    Java實(shí)現(xiàn)連接kubernates集群的兩種方式詳解

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)連接kubernates集群的兩種方式,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • Spring中的接口重試機(jī)制spring-retry之listeners參數(shù)解析

    Spring中的接口重試機(jī)制spring-retry之listeners參數(shù)解析

    這篇文章主要介紹了Spring中的接口重試機(jī)制spring-retry之listeners參數(shù)解析,注解@Retryable有一個(gè)參數(shù)listeners沒(méi)有說(shuō)明,那么本篇文章我們?cè)敿?xì)介紹一個(gè)這個(gè)參數(shù)的用,需要的朋友可以參考下
    2024-01-01
  • 如何自定義Jackson序列化?@JsonSerialize

    如何自定義Jackson序列化?@JsonSerialize

    這篇文章主要介紹了如何自定義Jackson序列化?@JsonSerialize,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • java如何獲取兩個(gè)日期的時(shí)間差

    java如何獲取兩個(gè)日期的時(shí)間差

    這篇文章主要為大家詳細(xì)介紹了java獲取兩個(gè)日期時(shí)間差的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • SpringBoot整合Lucene實(shí)現(xiàn)全文檢索的詳細(xì)步驟

    SpringBoot整合Lucene實(shí)現(xiàn)全文檢索的詳細(xì)步驟

    全文搜索(Full-Text?Search)是指對(duì)大規(guī)模存儲(chǔ)在計(jì)算機(jī)系統(tǒng)中的文本數(shù)據(jù)進(jìn)行檢索和匹配的技術(shù),它允許用戶輸入關(guān)鍵字,然后從海量的文本數(shù)據(jù)中快速找到相關(guān)的信息,本文介紹了SpringBoot整合Lucene實(shí)現(xiàn)全文檢索的詳細(xì)步驟,需要的朋友可以參考下
    2024-03-03
  • Servlet實(shí)現(xiàn)簡(jiǎn)單文件上傳功能

    Servlet實(shí)現(xiàn)簡(jiǎn)單文件上傳功能

    這篇文章主要為大家詳細(xì)介紹了Servlet實(shí)現(xiàn)簡(jiǎn)單文件上傳功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • java中synchronized關(guān)鍵字的3種寫法實(shí)例

    java中synchronized關(guān)鍵字的3種寫法實(shí)例

    synchronized是Java中的關(guān)鍵字,是一種同步鎖,下面這篇文章主要給大家介紹了關(guān)于java中synchronized關(guān)鍵字的3種寫法,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-11-11

最新評(píng)論