描述 外观模式(Fa?ade pattern)涉及到子系统的一些类所谓子系统是为提供一系列相关的特征(功能)而紧密关联的一组类例如一个Account类Address类和CreditCard类相互关联成为子系统的一部分提供在线客户的特征 在真实的应用系统中一个子系统可能由很多类组成子系统的客户为了它们的需要需要和子系统中的一些类进行交互客户和子系统的类进行直接的交互会导致客户端对象和子系统(Figure )之间高度耦合任何的类似于对子系统中类的接口的修改会对依赖于它的所有的客户类造成影响 Figure : Client Interaction with Subsystem Classes before Applying the Fa?ade Pattern 外观模式(Fa?ade pattern)很适用于在上述情况外观模式(Fa?ade pattern)为子系统提供了一个更高层次更简单的接口从而降低了子系统的复杂度和依赖这使得子系统更易于使用和管理 外观是一个能为子系统和客户提供简单接口的类当正确的应用外观客户不再直接和子系统中的类交互而是与外观交互外观承担与子系统中类交互的责任实际上外观是子系统与客户的接口这样外观模式降低了子系统和客户的耦合度(Figure ) Figure : Client Interaction with Subsystem Classes after Applying the Fa?ade Pattern 从Figure 中我们可以看到外观对象隔离了客户和子系统对象从而降低了耦合度当子系统中的类进行改变时客户端不会像以前一样受到影响 尽管客户使用由外观提供的简单接口但是当需要的时候客户端还是可以视外观不存在直接访问子系统中的底层次的接口这种情况下它们之间的依赖/耦合度和原来一样 例子 让我们建立一个应用 ()接受客户的详细资料(账户地址和信用卡信息) ()验证输入的信息 ()保存输入的信息到相应的文件中 这个应用有三个类AccountAddress和CreditCard每一个类都有自己的验证和保存数据的方法 Listing : AccountClass public class Account { String firstName; String lastName; final String ACCOUNT_DATA_FILE = AccountDatatxt; public Account(String fname String lname) { firstName = fname; lastName = lname; } public boolean isValid() { /* Lets go with simpler validation here to keep the example simpler */ … … } public boolean save() { FileUtil futil = new FileUtil(); String dataLine = getLastName() + + getFirstName(); return futilwriteToFile(ACCOUNT_DATA_FILE dataLine true true); } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } } Listing : Address Class public class Address { String address; String city; String state; final String ADDRESS_DATA_FILE = Addresstxt; public Address(String add String cty String st) { address = add; city = cty; state = st; } public boolean isValid() { /* The address validation algorithm could be complex in realworld applications Lets go with simpler validation here to keep the example simpler */ if (getState()trim()length() < ) return false; return true; } public boolean save() { FileUtil futil = new FileUtil(); String dataLine = getAddress() + + getCity() + + getState(); return futilwriteToFile(ADDRESS_DATA_FILE dataLine true true); } public String getAddress() { return address; } public String getCity() { return city; } public String getState() { return state; } } Listing : CreditCard Class public class CreditCard { String cardType; String cardNumber; String cardExpDate; final String CC_DATA_FILE = CCtxt; public CreditCard(String ccType String ccNumber String ccExpDate) { cardType = ccType; cardNumber = ccNumber; cardExpDate = ccExpDate; } public boolean isValid() { /* Lets go with simpler validation here to keep the example simpler */ if (getCardType()equals(AccountManagerVISA)) { return (getCardNumber()trim()length() == ); } if (getCardType()equals(AccountManagerDISCOVER)) { return (getCardNumber()trim()length() == ); } if (getCardType()equals(AccountManagerMASTER)) { return (getCardNumber()trim()length() == ); } return false; } public boolean save() { FileUtil futil = new FileUtil(); String dataLine = getCardType() + + getCardNumber() + + getCardExpDate(); return futilwriteToFile(CC_DATA_FILE dataLine true true); } public String getCardType() { return cardType; } public String getCardNumber() { return cardNumber; } public String getCardExpDate() { return cardExpDate; } } 让我们建立一个客户AccountManager它提供用户输入数据的用户界面 Listing : Client AccountManager Class public class AccountManager extends JFrame { public static final String newline = \n; public static final String VALIDATE_SAVE = Validate & Save; … … public AccountManager() { super( Facade Pattern Example ); cmbCardType = new JComboBox(); cmbCardTypeaddItem(AccountManagerVISA); cmbCardTypeaddItem(AccountManagerMASTER); cmbCardTypeaddItem(AccountManagerDISCOVER); … … //Create buttons JButton validateSaveButton = new JButton(AccountManagerVALIDATE_SAVE); … … } public String getFirstName(){ return txtFirstNamegetText(); } … … }//End of class AccountManager 当客户AccountManage运行的时候展示的用户接口如下 Figure : User Interface to Enter the Customer Data 为了验证和保存输入的数据客户AccountManager需要 ()建立AccountAddress和CreditCard对象 ()用这些对象验证输入的数据 ()用这些对象保存输入的数据 下面是对象间的交互顺序图 Figure : How a Client Would Normally Interact (Directly) with Subsystem Classes to Validate and Save the Customer Data 在这个例子中应用外观模式是一个很好的设计它可以降低客户和子系统组件(AddressAccount和CreditCard)之间的耦合度应用外观模式让我们定义一个外观类CustomerFacade (Figure and Listing )它为由客户数据处理类(AddressAccount和CreditCard)所组成的子系统提供一个高层次的简单的接口 CustomerFacade address:String city:String state:String cardType:String cardNumber:String cardExpDate:String fname:String lname:String setAddress(inAddress:String) setCity(inCity:String) setState(inState:String) setCardType(inCardType:String) setCardNumber(inCardNumber:String) setCardExpDate(inCardExpDate:String) setFName(inFName:String) setLName(inLName:String) saveCustomerData() Figure : Fa?ade Class to Be Used by the Client in the Revised Design Listing : CustomerFacade Cl |