public class Account { String firstName; String lastName; final String ACCOUNT_DATA_FILE = "AccountData.txt"; public Account(String fname, String lname) { firstName = fname; lastName = lname; } public boolean isValid() { /* Let's go with simpler validation here to keep the example simpler. */ … … } public boolean save() { FileUtil futil = new FileUtil(); String dataLine = getLastName() + ”," + getFirstName(); return futil.writeToFile(ACCOUNT_DATA_FILE, dataLine, true, true); } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } }
Listing 22.2: Address Class
public class Address { String address; String city; String state; final String ADDRESS_DATA_FILE = "Address.txt"; 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 real-world applications. Let's go with simpler validation here to keep the example simpler. */ if (getState().trim().length() < 2) return false; return true; } public boolean save() { FileUtil futil = new FileUtil(); String dataLine = getAddress() + ”," + getCity() + ”," + getState(); return futil.writeToFile(ADDRESS_DATA_FILE, dataLine, true, true); } public String getAddress() { return address; } public String getCity() { return city; } public String getState() { return state; } }
Listing 22.3: CreditCard Class
public class CreditCard { String cardType; String cardNumber; String cardEXPDate; final String CC_DATA_FILE = "CC.txt"; public CreditCard(String ccType, String ccNumber, String ccExpDate) { cardType = ccType; cardNumber = ccNumber; cardExpDate = ccExpDate; } public boolean isValid() { /* Let's go with simpler validation here to keep the example simpler. */ if (getCardType().equals(AccountManager.VISA)) { return (getCardNumber().trim().length() == 16); } if (getCardType().equals(AccountManager.DISCOVER)) { return (getCardNumber().trim().length() == 15); } if (getCardType().equals(AccountManager.MASTER)) { return (getCardNumber().trim().length() == 16); } return false; } public boolean save() { FileUtil futil = new FileUtil(); String dataLine = getCardType() + ,”" + getCardNumber() + ”," + getCardExpDate(); return futil.writeToFile(CC_DATA_FILE, dataLine, true, true); } public String getCardType() { return cardType; } public String getCardNumber() { return cardNumber; } public String getCardExpDate() { return cardExpDate; } }
讓我們建立一個客戶AccountManager,它提供用戶輸入數據的用戶界面。
Listing 22.4: 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(); cmbCardType.addItem(AccountManager.VISA); cmbCardType.addItem(AccountManager.MASTER); cmbCardType.addItem(AccountManager.DISCOVER); … … //Create buttons JButton validateSaveButton = new JButton(AccountManager.VALIDATE_SAVE); … … } public String getFirstName() { return txtFirstName.getText(); } … … }//End of class AccountManager
當客戶AccountManage運行的時候,展示的用戶接口如下:
Figure 22.4: User Interface to Enter the Customer Data
為了驗證和保存輸入的數據,客戶AccountManager需要:
?。?) 建立Account、Address和CreditCard對象。
?。?) 用這些對象驗證輸入的數據
?。?) 用這些對象保存輸入的數據。
下面是對象間的交互順序圖:
Figure 22.5: How a Client Would Normally Interact (Directly) with Subsystem Classes to Validate and Save the Customer Data
在這個例子中應用外觀模式是一個很好的設計,它可以降低客戶和子系統組件(Address、Account和CreditCard)之間的耦合度。應用外觀模式,讓我們定義一個外觀類CustomerFacade (Figure 22.6 and Listing 22.5)。它為由客戶數據處理類(Address、Account和CreditCard)所組成的子系統提供一個高層次的、簡單的接口。