Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 488|回复: 0

[设计模式学习]Java设计模式之外观模式研究

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-29 23:59:05 | 显示全部楼层 |阅读模式
    外观模式(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
            
          
         
       
       
      
       

      
       
      
      
       
       
       
       
      
       让我们建立一个客户AccountManager,它提供用户输入数据的用户界面。
       

       
    Listing4: Client AccountManager Class
       

       

       
         
          
          public class AccountManager extends JFrame {
    public static final String newline = "
    ";
    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运行的时候,展示的用户接口如下:
       

       

       
         
          
          
          
              
            
    Figure4: User Interface to Enter the Customer Data
            
          
         
       
       
    为了验证和保存输入的数据,客户AccountManager需要:
       

       
    (1) 建立Account、Address和CreditCard对象。
       

       
    (2) 用这些对象验证输入的数据
       

       
    (3) 用这些对象保存输入的数据。
       

       
    下面是对象间的交互顺序图:
       

       

       
         
          
          
          
            
            
    Figure5: How a Client Would Normally Interact (Directly) with Subsystem Classes to Validate and Save the Customer Data
            
          
         
       
       
    在这个例子中应用外观模式是一个很好的设计,它可以降低客户和子系统组件(Address、Account和CreditCard)之间的耦合度。应用 外观模式,让我们定义一个外观类CustomerFacade (Figure6 and Listing5)。它为由客户数据处理类(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()
          
         
       
       

       
         
          
          
            
            
            
    Figure6: Facade Class to Be Used by the Client in the Revised Design
            
          
         
       
       
    Listing5: CustomerFacade Class
       

       

       
         
          
          public class CustomerFacade {
    private String address;
    private String city;
    private String state;
    private String cardType;
    private String cardNumber;
    private String cardExpDate;
    private String fname;
    private String lname;
    public void setAddress(String inAddress) {
    address = inAddress;
    }
    public void setCity(String inCity) {
    city = inCity;
    }
    public void setState(String inState) {
    state = inState;
    }
    public void setFName(String inFName) {
    fname = inFName;
    }
    public void setLName(String inLName) {
    lname = inLName;
    }
    public void setCardType(String inCardType) {
    cardType = inCardType;
    }
    public void setCardNumber(String inCardNumber) {
    cardNumber = inCardNumber;
    }
    public void setCardExpDate(String inCardExpDate) {
    cardExpDate = inCardExpDate;
    }
    public boolean saveCustomerData() {
    Address objAddress;
    Account objAccount;
    CreditCard objCreditCard;
    /*
    client is transparent from the following
    set of subsystem related operations.
    */
    boolean validData = true;
    String errorMessage = "";
    objAccount = new Account(fname, lname);
    if (objAccount.isValid() == false) {
    validData = false;
    errorMessage = "Invalid FirstName/LastName";
    }
    objAddress = new Address(address, city, state);
    if (objAddress.isValid() == false) {
    validData = false;
    errorMessage = "Invalid Address/City/State";
    }
    objCreditCard = new CreditCard(cardType, cardNumber, cardExpDate);
    if (objCreditCard.isValid() == false) {
    validData = false;
    errorMessage = "Invalid CreditCard Info";
    }
    if (!validData) {
    System.out.println(errorMessage);
    return false;
    }
    if (objAddress.save() && objAccount.save() && objCreditCard.save()) {
    return true;
    } else {
    return false;
    }
    }
    }  
          
         
       
       
    CustomerFacade类以saveCustomData方法的形式提供了业务层次上的服务。客户AccountManager不是直接和子系统 的每一个组件交互,而是使用了由CustomFacade对象提供的验证和保存客户数据的更高层次、更简单的接口(Figure7).
       

       

       
         
          
          
          
            
            
    Figure7: Class Association with the Fa?ade Class in Place 。
            
          
         
       
       
    在新的设计中,为了验证和保存客户数据,客户需要:
       

       
    (1) 建立或获得外观对象CustomFacade的一个实例。
       

       
    (2) 传递数据给CustomFacade实例进行验证和保存。
       

       
    (3) 调用CustomFacade实例上的saveCustomData方法。
       

       
    CustomFacade处理创建子系统中必要的对象并且调用这些对象上相应的验证、保存客户数据的方法这些细节问题。客户不再需要直接访问任何的子系统中的对象。
       

       
    Figure8展示了新的设计的消息流图:
       

       

       
         
          
          
          
            
            
    Figure 22.8: In the Revised Design, Clients Interact with the Fa?ade Instance to Interface with the Subsystem
            
          
         
       
       

       重要提示
       

       
    下面是应用外观模式的注意事项:
       

       
    (1) 在设计外观时,不需要增加额外的功能。
       

       
    (2) 不要从外观方法中返回子系统中的组件给客户。例如:有一个下面的方法:
       

       
    CreditCard getCreditCard()
       

       
    会报漏子系统的细节给客户。应用就不能从应用外观模式中取得最大的好处。
       

       
    (3)应用外观的目的是提供一个高层次的接口。因此,外观方法最适合提供特定的高层次的业务服务,而不是进行底层次的单独的业务执行。
       
      



      
      
       
       

         
       

         
       
      


    源码下载:http://www.hnzz3z.com:8103/zz3zcwb/cwb/dir2/no
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-5 13:52 , Processed in 0.332642 second(s), 34 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表