设计模式之---外观模式(Facade)

场景:
炒股,现在是全民炒股的时代,然而全民炒股,由于大多投资者对众多股票的联系太多,反而不利于股票操作,这在软件中叫藕合性过高。
而投资的另一种方式:基金,它将投资者分散的资金集中起来,交由专业的经理人进行管理,投资于股票,债券,外汇等领域。
而基金投资的收益是持有者所有。
管理机构只收取一定比例的托管费用。
这种买基金的方式就类似于软件开发里面的外观模式.

意图:
外观模式定义了一个将子系统的一组接口集成在一起的高层接口,以提供一个一致的界面。通过这个界面,其他系统可以方便地调用子系统中的功能,而忽略子系统内部发生的变化…

使用场合:
1、为一个比较复杂的子系统提供一个简单的接口。
2、将客户程序与子系统的实现部分分离,提高子系统的独立性和可移植性。
3、简化子系统间的依赖关系。

外观模式(Facede pattern)涉及到子系统的一些类。
所谓子系统,是为提供一系列相关的特征〔功能)而紧密关联的一组类。
例如,一个Account类、Address类和CreditCerd类相互关联。
成为子系统的一部分,提供在线客户的特征。
在真实的应用系统中,一个子系统可能由很多类组成。
子系统的客户为了它们的需要,需要和子系统中的一些类进行交互。
客户和子系统的类进行直接的交互会导致客户端对象和子系统(Figurel)之间高度耦合。
任何的类似于对子系统中类的接口的修改,会对依赖于它的所有的客户类造成影响。
设计模式之---外观模式(Facade)_第1张图片

外观模式(Facede pattern)很适用于在上述情况;
外观模式(Facede pattern)为子系统提供了一个更高层次、更简单的接口。
从而降低了子系统的复杂度和依赖。
这使得子系统更易于使用和管理。
外观是一个能为子系统和客户提供简单接口的类。
当正确的应用外观,客户不再直接和子系统中的类交互.而是与外观交互。
外观承担与子系统中类交互的责任。
实际上,外观是子系统与客户的接口,这样外观模式降低了子系统和客户的耦合度
设计模式之---外观模式(Facade)_第2张图片
从图中我们可以看到:
外观对象隔离了客户和子系统对象,从而降低了藕合度。
当子系统中的类进行改变时,客户端不会像以前一样受到影响。
尽管客户使用由外观提供的简单接口,但是当需要的时候,客户端还是可以视外观不存在,直接访问子系统中的底层次的接口。
这种情况下,它们之间的依赖/藕合度和原来一样

应用实例:
我们来建立一个应用:
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、应用外观的目的是提供一个高层次的接口。
因此,外观方法最适合提供特定的高层次的业务服务,而不是进行底层次的单独的业务执行。.

你可能感兴趣的:(设计模式,软件开发,Facade,外观模式)