設計模式之---外觀模式(Facade)

場景:
炒股,現在是全民炒股的時代,然而全民炒股,由於大多投資者對衆多股票的聯繫太多,反而不利於股票操作,這在軟件中叫藕合性過高。
而投資的另一種方式:基金,它將投資者分散的資金集中起來,交由專業的經理人進行管理,投資於股票,債券,外匯等領域。
而基金投資的收益是持有者所有。
管理機構只收取一定比例的託管費用。
這種買基金的方式就類似於軟件開發裏面的外觀模式.

意圖:
外觀模式定義了一個將子系統的一組接口集成在一起的高層接口,以提供一個一致的界面。通過這個界面,其他系統可以方便地調用子系統中的功能,而忽略子系統內部發生的變化…

使用場合:
1、爲一個比較複雜的子系統提供一個簡單的接口。
2、將客戶程序與子系統的實現部分分離,提高子系統的獨立性和可移植性。
3、簡化子系統間的依賴關係。

外觀模式(Facede pattern)涉及到子系統的一些類。
所謂子系統,是爲提供一系列相關的特徵〔功能)而緊密關聯的一組類。
例如,一個Account類、Address類和CreditCerd類相互關聯。
成爲子系統的一部分,提供在線客戶的特徵。
在真實的應用系統中,一個子系統可能由很多類組成。
子系統的客戶爲了它們的需要,需要和子系統中的一些類進行交互。
客戶和子系統的類進行直接的交互會導致客戶端對象和子系統(Figurel)之間高度耦合。
任何的類似於對子系統中類的接口的修改,會對依賴於它的所有的客戶類造成影響。
這裏寫圖片描述

外觀模式(Facede pattern)很適用於在上述情況;
外觀模式(Facede pattern)爲子系統提供了一個更高層次、更簡單的接口。
從而降低了子系統的複雜度和依賴。
這使得子系統更易於使用和管理。
外觀是一個能爲子系統和客戶提供簡單接口的類。
當正確的應用外觀,客戶不再直接和子系統中的類交互.而是與外觀交互。
外觀承擔與子系統中類交互的責任。
實際上,外觀是子系統與客戶的接口,這樣外觀模式降低了子系統和客戶的耦合度
這裏寫圖片描述
從圖中我們可以看到:
外觀對象隔離了客戶和子系統對象,從而降低了藕合度。
當子系統中的類進行改變時,客戶端不會像以前一樣受到影響。
儘管客戶使用由外觀提供的簡單接口,但是當需要的時候,客戶端還是可以視外觀不存在,直接訪問子系統中的底層次的接口。
這種情況下,它們之間的依賴/藕合度和原來一樣

應用實例:
我們來建立一個應用:
1、接受客戶的詳細資料(賬戶、地址和信用卡信息)。
2、驗證輸入的信息。
3、保存輸人的信息到相應的文件中。
這個應用有三個類:Account, Address和CreditCard。每一個類都有自己的驗證和保存數據的方法。
Account類

public class Account {
    String firstName;
    String lastName;
    final String ACCOUNT_DATA_FILE ="AccountData.txt";
    public Account(String firstName,String lastName){
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }
    public boolean isValid(){
        /*
        let's go with simpler validation
        here to keep example simpler;

         */
        return true;
    }

    public boolean save(){
          /*
        let's go with simpler validation
        here to keep example simpler;

         */
        return true;
    }
}

Address 類

public class Address {
    String address;
    String city;
    String state;
    final String Address_DATA_FILE ="AddressData.txt";
    public Address(String address,String city, String state){
        this.address = address;
        this.city = city;
        this.state = state;
    }

    public String getAddress() {
        return address;
    }

    public String getCity() {
        return city;
    }

    public String getState() {
        return state;
    }

    public boolean isValid(){
        /*
        let's go with simpler validation
        here to keep example simpler;

         */
        return true;
    }

    public boolean save(){
          /*
        let's go with simpler validation
        here to keep example simpler;

         */
        return true;
    }
}

CreditCard 類

public class CreditCard {
    String cardType;
    String cardNumber;
    String cardExpDate;
    final String CreditCard_DATA_FILE ="CreditCardData.txt";

    public CreditCard(String cardType,String cardNumber, String cardExpDate){
        this.cardType = cardType;
        this.cardExpDate = cardExpDate;
        this.cardNumber = cardNumber;
    }

    public String getCardType() {
        return cardType;
    }

    public String getCardNumber() {
        return cardNumber;
    }

    public String getCardExpDate() {
        return cardExpDate;
    }
    public boolean isValid(){
        /*
        let's go with simpler validation
        here to keep example simpler;
         */
        return true;
    }

    public boolean save(){
          /*
        let's go with simpler validation
        here to keep example simpler;
         */
        return true;
    }
}

以上是子系統的內部功能類,然後我們建一個外觀CustomerFacede 類供外界訪問:

public class CustomerFacede {
    private String firstName;
    private String lastName;

    private String address;
    private String city;
    private String state;

    private String cardType;
    private String cardNumber;
    private String cardExpDate;

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public void setState(String state) {
        this.state = state;
    }

    public void setCardType(String cardType) {
        this.cardType = cardType;
    }

    public void setCardNumber(String cardNumber) {
        this.cardNumber = cardNumber;
    }

    public void setCardExpDate(String cardExpDate) {
        this.cardExpDate = cardExpDate;
    }

    public boolean saveCustomerData(){
        Address objAdress;
        Account objAccount;
        CreditCard objCreditCard;

        boolean validData = true;
        String errorMsg = "";

        objAccount = new Account(firstName,lastName);
        if(!objAccount.isValid()){
            validData =false;
            errorMsg = "invalid firstName/lastName";
        }

        objAdress = new Address(address,city,state);
        if(!objAdress.isValid()){
            validData =false;
            errorMsg = "invalid address/city/state";
        }

        objCreditCard = new CreditCard(cardType,cardNumber,cardExpDate);
        if(!objCreditCard.isValid()){
            validData =false;
            errorMsg = "invalid cardType/cardNumber/cardExpDate";
        }

        if(!validData){
            System.out.print(errorMsg);
        }

        if(objAccount.save() && objAdress.save() && objCreditCard.save()){
            return true;
        }else {
            return false;
        }
    }
}

最後,我們寫一個測試AccountManager 類:

//通過CustomerFacede 分別對子系統的三個功能模塊進行操作,而不需要知道其內部結構.
public class AccountManager {
    public static void main(String[] args) {

        CustomerFacede facede = new CustomerFacede();

        facede.setFirstName("summer");
        facede.saveCustomerData();

        facede.setAddress("China zhuzhou");
        facede.saveCustomerData();

        facede.setCardType("VISA");
        facede.saveCustomerData();
    }
}

客戶AccountManager不是直接和子系統的每一個組件交互,而是使用了由CustomerFacede對象提供的驗證和保存客戶數據的更高層次、更簡單的接口.
在新的設計中,爲了驗證和保存客戶數據,客戶需要:

1,建立或獲得外觀對象CustomFacade的一個實例。
2,傳遞數據給CustomFacade實例進行驗證和保存。
3,調用CustomFacade實例上的saveCustomerData方法。

CustomerFacede處理創建子系統中必要的對象並且調用這些對象上相應的驗證、保存客戶數據的方法這些細節間題。
客戶不再需要直接訪問任何的子系統中的對象。

注意事項:
1、在設計外觀時,不需要增加額外的功能。
2、不要從外觀方法中返回子系統中的組件給客戶。例如:有一個下面的方法:CreditCard getCteditCard0會報漏子系統的細節給客戶。應用就不能從應用外觀模式中取得最大的好處。
3、應用外觀的目的是提供一個高層次的接口。
因此,外觀方法最適合提供特定的高層次的業務服務,而不是進行底層次的單獨的業務執行。.

發佈了38 篇原創文章 · 獲贊 7 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章