1. 程式人生 > >設計模式的藝術 結構性模式之外觀模式

設計模式的藝術 結構性模式之外觀模式

前言

去飯館吃飯,自己只需要點個菜,然後自然後廚做好了之後會有服務員給你端上來,真正來講,自己只需要告訴服務員自己要吃的菜就行,不需要與原材料和廚子之間發生任何的互動,在軟體設計思想中也有這樣的場景,為了完成一個複雜的功能,一個類可能需要與多個其他業務類發生互動,而這些互動類經常會作為一個整體出現,因為涉及的業務類比較多,導致使用程式碼時比較複雜,所以這時候就需要一個類似於服務員的外觀類,由他為這些需要互動的業務類提供一個統一的入口,從而簡化類與類之間的互動。

什麼是外觀模式 Facade Pattern

外部與一個子系統的通訊通過一個統一的外觀角色進行,為子系統中的一組介面提供一個一致的入口,外觀模式定義了一個高層介面,這個介面使得這一子系統更加容易的使用。外觀模式又稱為門面模式,它是一種物件結構型模式。

外觀模式的優點

(1)、對客戶端遮蔽了子系統的元件,減少了客戶端所需處理的物件數目並使得子系統使用起來更加容易。通過引入外觀模式,客戶端程式碼將變得簡單,與之關聯的物件也很少。

(2)、實現了子系統與客戶端之間的鬆耦合關係,這使得子系統的變化不會影響到呼叫它的客戶端,只需要調整外觀類即可。

(3)、一個子系統的修改對其他子系統沒有任何的影響,而且子系統內部的變化也不會影響到外觀物件。

(4)、只是提供了一個訪問子系統的統一入口,並不影響客戶端直接使用子系統類。

外觀模式的主要缺點

(1)、不能很好地限制客戶端直接使用子系統類,如果對客戶端訪問子系統類做太多的限制則減少了可變性和靈活性。

(2)、如果設計不當,增加新的子系統可能需要修改外觀類的原始碼,這違背了開閉原則

外觀模式的適用場景

(1)、當要為訪問一系列複雜的子系統提供一個簡單入口時可以使用外觀模式

(2)、客戶端程式與多個子系統之間存在著很大的依賴性。引入外觀類可以將子系統與客戶端之間實現解耦,從而提供子系統的獨立性和可移植性,這是迪米特法則的具體體現

(3)、在層次結構中,可以使用外觀模式定義系統中每一層的入口,層與層之間不直接產生聯絡,而通過外觀類建立聯絡,降低層之間的耦合度。

外觀模式的具體實現

專案結構

子系統的類

//資料加密類:子系統類
public class CipherMachine {
    public String encrypt(String plainText){
        System.out.println("資料加密,將明文轉換為密文");
        String es="";
        for(int i=0;i<plainText.length();i++){
            String c=String.valueOf(plainText.charAt(i)%7);
            es+=c;
        }
        System.out.println(es);
        return es;
    }
}
package com.company.documentFunction;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

//檔案讀取類:子系統類
public class FileReader {
    public String read(String fileNameSrc){
        System.out.println("讀取檔案,獲取明文");
        StringBuffer sb=new StringBuffer();
        try {
            FileInputStream inFS=new FileInputStream(fileNameSrc);
            int data;
            while ((data=inFS.read())!=-1){
                sb=sb.append((char) data);
            }
            inFS.close();
            System.out.println(sb.toString());
        }catch (FileNotFoundException e){
            e.printStackTrace();
            System.out.println("檔案不存在");
            return null;
        }
        catch (IOException e){
            System.out.println("檔案操作錯誤");
        }
        return  sb.toString();
    }
}
package com.company.documentFunction;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

//檔案儲存類:子系統類
public class FileWriter {
    public void write(String encryptStr,String fileNameDes){
        System.out.println("儲存密文,寫入檔案");
        try {
            FileOutputStream outFS=new FileOutputStream(fileNameDes);
            outFS.write(encryptStr.getBytes());
            outFS.close();
        }catch (FileNotFoundException e){
            System.out.println("檔案不存在");
        }catch (IOException e){
            System.out.println("檔案操作錯誤");
        }
    }
}

外觀類

package com.company;

import com.company.documentFunction.CipherMachine;
import com.company.documentFunction.FileReader;
import com.company.documentFunction.FileWriter;

//加密外觀類:外觀類
public class EncryptFacade {
    //維持對其他物件的引用
    private FileReader fileReader;
    private FileWriter fileWriter;
    private CipherMachine cipherMachine;
    public EncryptFacade(){
        fileReader=new FileReader();
        fileWriter=new FileWriter();
        cipherMachine=new CipherMachine();
    }
    //呼叫其他物件的業務方法
    public void fileEncrypt(String fileNameSrc,String fileNameDes){
        String plainStr=fileReader.read(fileNameSrc);
        String encryptStr=cipherMachine.encrypt(plainStr);
        fileWriter.write(encryptStr,fileNameDes);

    }
}

客戶端測試

package com.company;

public class Client {

    public static void main(String[] args) {
           EncryptFacade ef=new EncryptFacade();
           ef.fileEncrypt("1.txt","2.txt");
    }
}

轉載請註明出處,掌聲送給社會人