服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 高级技术 > 设计模式 > 查看文档

外观设计模式组图(fa?ade pattern)


  描述
  
  外观模式(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

扫描关注微信公众号