Chinaunix首页 | 论坛 | 博客
  • 博客访问: 467333
  • 博文数量: 1496
  • 博客积分: 79800
  • 博客等级: 大将
  • 技术积分: 9940
  • 用 户 组: 普通用户
  • 注册时间: 2008-09-09 13:22
文章分类

全部博文(1496)

文章存档

2011年(1)

2008年(1495)

我的朋友

分类:

2008-09-09 13:31:39


  描述
  
  外观模式(Fa?ade pattern)涉及到子系统的一些类。所谓子系统,是为提供一系列相关的特征(功能)而紧密关联的一组类。例如,一个Account类、Address类和CreditCard类相互关联,成为子系统的一部分,提供在线客户的特征。
  
  在真实的应用系统中,一个子系统可能由很多类组成。子系统的客户为了它们的需要,需要和子系统中的一些类进行交互。客户和子系统的类进行直接的交互会导致客户端对象和子系统(Figure 22.1)之间高度耦合。任何的类似于对子系统中类的接口的修改,会对依赖于它的所有的客户类造成影响。
  
 
  Figure 22.1: Client Interaction with Subsystem Classes before Applying the Fa?ade Pattern
  

  外观模式(Fa?ade pattern)很适用于在上述情况。外观模式(Fa?ade pattern)为子系统提供了一个更高层次、更简单的接口,从而降低了子系统的复杂度和依赖。这使得子系统更易于使用和管理。
  
  外观是一个能为子系统和客户提供简单接口的类。当正确的应用外观,客户不再直接和子系统中的类交互,而是与外观交互。外观承担与子系统中类交互的责任。实际上,外观是子系统与客户的接口,这样外观模式降低了子系统和客户的耦合度(Figure 22.2).
  
 
  Figure 22.2: Client Interaction with Subsystem Classes after Applying the Fa?ade Pattern
  

  从Figure 22.2中我们可以看到:外观对象隔离了客户和子系统对象,从而降低了耦合度。当子系统中的类进行改变时,客户端不会像以前一样受到影响。
  
  尽管客户使用由外观提供的简单接口,但是当需要的时候,客户端还是可以视外观不存在,直接访问子系统中的底层次的接口。这种情况下,它们之间的依赖/耦合度和原来一样。
  
  例子:
  
  让我们建立一个应用:
  
  (1)  接受客户的详细资料(账户、地址和信用卡信息)
  
  (2)  验证输入的信息
  
  (3)  保存输入的信息到相应的文件中。
  
  这个应用有三个类:Account、Address和CreditCard。每一个类都有自己的验证和保存数据的方法。
  
  Listing 22.1: AccountClass
  
  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需要:
  
  (1)  建立Account、Address和CreditCard对象。
  
  (2)  用这些对象验证输入的数据
  
  (3)  用这些对象保存输入的数据。
  
  下面是对象间的交互顺序图:
  
 
  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)所组成的子系统提供一个高层次的、简单的接口。
  
  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 22.6: Fa?ade Class to Be Used by the Client in the Revised Design
  

  Listing 22.5: CustomerFacade Cl
【责编:admin】

--------------------next---------------------

阅读(81) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~