欢迎来到天天文库
浏览记录
ID:13872907
大小:232.00 KB
页数:11页
时间:2018-07-24
《java设计模式之外观》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
Java设计模式之外观模式研究 外观模式(Facadepattern)涉及到子系统的一些类。所谓子系统,是为提供一系列相关的特征(功能)而紧密关联的一组类。例如,一个Account类、Address类和CreditCard类相互关联,成为子系统的一部分,提供在线客户的特征。在真实的应用系统中,一个子系统可能由很多类组成。子系统的客户为了它们的需要,需要和子系统中的一些类进行交互。客户和子系统的类进行直接的交互会导致客户端对象和子系统(Figure1)之间高度耦合。任何的类似于对子系统中类的接口的修改,会对依赖于它的所有的客户类造成影响。 Figure1:ClientInteractionwithSubsystemClassesbeforeApplyingtheFacadePattern外观模式(Facadepattern)很适用于在上述情况。外观模式(Facadepattern)为子系统提供了一个更高层次、更简单的接口,从而降低了子系统的复杂度和依赖。这使得子系统更易于使用和管理。外观是一个能为子系统和客户提供简单接口的类。当正确的应用外观,客户不再直接和子系统中的类交互,而是与外观交互。外观承担与子系统中类交互的责任。实际上,外观是子系统与客户的接口,这样外观模式降低了子系统和客户的耦合度(Figure2). Figure2:ClientInteractionwithSubsystemClassesafterApplyingtheFacadePattern 从Figure2中我们可以看到:外观对象隔离了客户和子系统对象,从而降低了耦合度。当子系统中的类进行改变时,客户端不会像以前一样受到影响。尽管客户使用由外观提供的简单接口,但是当需要的时候,客户端还是可以视外观不存在,直接访问子系统中的底层次的接口。这种情况下,它们之间的依赖/耦合度和原来一样。例子:让我们建立一个应用:(1)接受客户的详细资料(账户、地址和信用卡信息)(2)验证输入的信息(3)保存输入的信息到相应的文件中。这个应用有三个类:Account、Address和CreditCard。每一个类都有自己的验证和保存数据的方法。Listing1:AccountClasspublicclassAccount{ StringfirstName; StringlastName; finalStringACCOUNT_DATA_FILE="AccountData.txt"; publicAccount(Stringfname,Stringlname){ firstName=fname; lastName=lname; } publicbooleanisValid(){ /* Let'sgowithsimplervalidation heretokeeptheexamplesimpler. */ … … } publicbooleansave(){ FileUtilfutil=newFileUtil(); StringdataLine=getLastName()+”,"+getFirstName(); returnfutil.writeToFile(ACCOUNT_DATA_FILE,dataLine,true,true); } publicStringgetFirstName(){ returnfirstName; } publicStringgetLastName(){ returnlastName; }}Listing2:AddressClasspublicclassAddress{ Stringaddress; Stringcity; Stringstate; finalStringADDRESS_DATA_FILE="Address.txt"; publicAddress(Stringadd,Stringcty,Stringst){ address=add; city=cty; state=st; } publicbooleanisValid(){ /* Theaddressvalidationalgorithm couldbecomplexinreal-world applications. Let'sgowithsimplervalidation heretokeeptheexamplesimpler. */ if(getState().trim().length()<2) returnfalse; returntrue; } publicbooleansave(){ FileUtilfutil=newFileUtil(); StringdataLine=getAddress()+”,"+getCity()+”,"+getState(); returnfutil.writeToFile(ADDRESS_DATA_FILE,dataLine,true,true); } publicStringgetAddress(){ returnaddress; } publicStringgetCity(){ returncity; } publicStringgetState(){ returnstate; }} Listing3:CreditCardClasspublicclassCreditCard{ StringcardType; StringcardNumber; StringcardExpDate; finalStringCC_DATA_FILE="CC.txt"; publicCreditCard(StringccType,StringccNumber, StringccExpDate){ cardType=ccType; cardNumber=ccNumber; cardExpDate=ccExpDate; } publicbooleanisValid(){ /* Let'sgowithsimplervalidation heretokeeptheexamplesimpler. */ 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); } returnfalse; } publicbooleansave(){ FileUtilfutil=newFileUtil(); StringdataLine=getCardType()+,”"+getCardNumber()+”,"+getCardExpDate(); returnfutil.writeToFile(CC_DATA_FILE,dataLine,true,true); } publicStringgetCardType(){ returncardType; } publicStringgetCardNumber(){ returncardNumber; } publicStringgetCardExpDate(){ returncardExpDate; }} Figure3:SubsystemClassestoProvidetheNecessaryFunctionalitytoValidateandSavetheCustomerData让我们建立一个客户AccountManager,它提供用户输入数据的用户界面。Listing4:ClientAccountManagerClasspublicclassAccountManagerextendsJFrame{ publicstaticfinalStringnewline=" "; publicstaticfinalStringVALIDATE_SAVE="Validate&Save"; … … publicAccountManager(){ super("FacadePattern-Example"); cmbCardType=newJComboBox(); cmbCardType.addItem(AccountManager.VISA); cmbCardType.addItem(AccountManager.MASTER); cmbCardType.addItem(AccountManager.DISCOVER); … … //Createbuttons JButtonvalidateSaveButton=newJButton(AccountManager.VALIDATE_SAVE); … … } publicStringgetFirstName(){ returntxtFirstName.getText(); } … …}//EndofclassAccountManager当客户AccountManage运行的时候,展示的用户接口如下: Figure4:UserInterfacetoEntertheCustomerData为了验证和保存输入的数据,客户AccountManager需要:(1)建立Account、Address和CreditCard对象。(2)用这些对象验证输入的数据(3)用这些对象保存输入的数据。下面是对象间的交互顺序图: Figure5:HowaClientWouldNormallyInteract(Directly)withSubsystemClassestoValidateandSavetheCustomerData在这个例子中应用外观模式是一个很好的设计,它可以降低客户和子系统组件(Address、Account和CreditCard)之间的耦合度。应用外观模式,让我们定义一个外观类CustomerFacade(Figure6andListing5)。它为由客户数据处理类(Address、Account和CreditCard)所组成的子系统提供一个高层次的、简单的接口。CustomerFacadeaddress:Stringcity:Stringstate:StringcardType:StringcardNumber:StringcardExpDate:Stringfname:Stringlname:StringsetAddress(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:FacadeClasstoBeUsedbytheClientintheRevisedDesignListing5:CustomerFacadeClasspublicclassCustomerFacade{ privateStringaddress; privateStringcity; privateStringstate; privateStringcardType; privateStringcardNumber; privateStringcardExpDate; privateStringfname; privateStringlname; publicvoidsetAddress(StringinAddress){ address=inAddress; } publicvoidsetCity(StringinCity){ city=inCity; } publicvoidsetState(StringinState){ state=inState; } publicvoidsetFName(StringinFName){ fname=inFName; } publicvoidsetLName(StringinLName){ lname=inLName; } publicvoidsetCardType(StringinCardType){ cardType=inCardType; } publicvoidsetCardNumber(StringinCardNumber){ cardNumber=inCardNumber; } publicvoidsetCardExpDate(StringinCardExpDate){ cardExpDate=inCardExpDate; } publicbooleansaveCustomerData(){ AddressobjAddress; AccountobjAccount; CreditCardobjCreditCard; /* clientistransparentfromthefollowing setofsubsystemrelatedoperations. */ booleanvalidData=true; StringerrorMessage=""; objAccount=newAccount(fname,lname); if(objAccount.isValid()==false){ validData=false; errorMessage="InvalidFirstName/LastName"; } objAddress=newAddress(address,city,state); if(objAddress.isValid()==false){ validData=false; errorMessage="InvalidAddress/City/State"; } objCreditCard=newCreditCard(cardType,cardNumber,cardExpDate); if(objCreditCard.isValid()==false){ validData=false; errorMessage="InvalidCreditCardInfo"; } if(!validData){ System.out.println(errorMessage); returnfalse; } if(objAddress.save()&&objAccount.save()&&objCreditCard.save()){ returntrue; }else{ returnfalse; } }}CustomerFacade类以saveCustomData方法的形式提供了业务层次上的服务。客户AccountManager不是直接和子系统的每一个组件交互,而是使用了由CustomFacade对象提供的验证和保存客户数据的更高层次、更简单的接口(Figure7). Figure7:ClassAssociationwiththeFa?adeClassinPlace。在新的设计中,为了验证和保存客户数据,客户需要:(1)建立或获得外观对象CustomFacade的一个实例。(2)传递数据给CustomFacade实例进行验证和保存。(3)调用CustomFacade实例上的saveCustomData方法。CustomFacade处理创建子系统中必要的对象并且调用这些对象上相应的验证、保存客户数据的方法这些细节问题。客户不再需要直接访问任何的子系统中的对象。Figure8展示了新的设计的消息流图: Figure22.8:IntheRevisedDesign,ClientsInteractwiththeFa?adeInstancetoInterfacewiththeSubsystem重要提示:下面是应用外观模式的注意事项:(1)在设计外观时,不需要增加额外的功能。(2)不要从外观方法中返回子系统中的组件给客户。例如:有一个下面的方法:CreditCardgetCreditCard()会报漏子系统的细节给客户。应用就不能从应用外观模式中取得最大的好处。(3)应用外观的目的是提供一个高层次的接口。因此,外观方法最适合提供特定的高层次的业务服务,而不是进行底层次的单独的业务执行。
此文档下载收益归作者所有
举报原因
联系方式
详细说明
内容无法转码请点击此处