Chinaunix首页 | 论坛 | 博客
  • 博客访问: 170300
  • 博文数量: 77
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 990
  • 用 户 组: 普通用户
  • 注册时间: 2009-06-21 18:13
文章分类

全部博文(77)

文章存档

2011年(1)

2009年(76)

我的朋友

分类: Java

2009-07-12 20:23:29

外观模式(Facade pattern)涉及到子系统的一些类。所谓子系统,是为提供一系列相关的特征(功能)而紧密关联的一组类。例如,一个Account类、Address类和CreditCard类相互关联,成为子系统的一部分,提供在线客户的特征。

    在真实的应用系统中,一个子系统可能由很多类组成。子系统的客户为了它们的需要,需要和子系统中的一些类进行交互。客户和子系统的类进行直接的交互会导 致客户端对象和子系统(Figure1)之间高度耦合。任何的类似于对子系统中类的接口的修改,会对依赖于它的所有的客户类造成影响。


Figure1: Client Interaction with Subsystem Classes before Applying the Facade Pattern

   外观模式(Facade pattern)很适用于在上述情况。外观模式(Facade pattern)为子系统提供了一个更高层次、更简单的接口,从而降低了子系统的复杂度和依赖。这使得子系统更易于使用和管理。

   外观是一个能为子系统和客户提供简单接口的类。当正确的应用外观,客户不再直接和子系统中的类交互,而是与外观交互。外观承担与子系统中类交互的责任。实际上,外观是子系统与客户的接口,这样外观模式降低了子系统和客户的耦合度(Figure2).


Figure2: Client Interaction with Subsystem Classes after Applying the Facade Pattern

   从Figure2中我们可以看到:外观对象隔离了客户和子系统对象,从而降低了耦合度。当子系统中的类进行改变时,客户端不会像以前一样受到影响。

   尽管客户使用由外观提供的简单接口,但是当需要的时候,客户端还是可以视外观不存在,直接访问子系统中的底层次的接口。这种情况下,它们之间的依赖/耦合度和原来一样。

   例子:

   让我们建立一个应用:

   (1) 接受客户的详细资料(账户、地址和信用卡信息)

   (2) 验证输入的信息

   (3) 保存输入的信息到相应的文件中。

   这个应用有三个类:Account、Address和CreditCard。每一个类都有自己的验证和保存数据的方法。

   Listing1: 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;
  }
}

   Listing2: 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;
  }
}

   Listing3: 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;
  }
}


Figure3: Subsystem Classes to Provide the Necessary Functionality to Validate and Save the Customer Data
 
阅读(230) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~