第31章
大B:“我給你舉個例子來說明吧!”
小A:“嗯。好的。”
大B:“讓我們建立一個應用:1、接受客戶的詳細資料(賬戶、地址和信用卡信息)2、驗證輸入的信息3、保存輸入的信息到相應的文件中。這個應用有三個類:Account、Address和CreditCard。每一個類都有自己的驗證和保存數據的方法。”
Listing1:AccountClass
publicclassAccount{
StringfirstName;
StringlastName;
finalStringACCOUNTDATAFILE=“AccountData.txt”;
publicAccount(Stringfname,Stringlname){
firstName=fname;
lastName=lname;
}
publicbooleanisValid(){
/*
Letsgowithsimplervalidation
heretokeeptheexamplesimpler.
*/
}
publicbooleansave(){
FileUtilfutil=newFileUtil();
StringdataLine=getLastName()+,+getFirstName();
returnfutil.writeToFile(ACCOUNTDATAFILE,dataLine,true,true);
}
publicStringgetFirstName(){
returnfirstName;
}
publicStringgetLastName(){
returnlastName;
}
}
Listing2:AddressClass
publicclassAddress{
Stringaddress;
Stringcity;
Stringstate;
finalStringADDRESSDATAFILE=“Address.txt”;
publicAddress(Stringadd,Stringcty,Stringst){
address=add;
city=cty;
state=st;
}
publicbooleanisValid(){
/*
Theaddressvalidationalgorithm
couldbeplexinreal-world
applications.
Letsgowithsimplervalidation
heretokeeptheexamplesimpler.
*/
if(getState().trim().length()(2)
returnfalse;
returntrue;
}
publicbooleansave(){
FileUtilfutil=newFileUtil();
StringdataLine=getAddress()+,“+getCity()+”,+getState();
returnfutil.writeToFile(ADDRESSDATAFILE,dataLine,true,true);
}
publicStringgetAddress(){
returnaddress;
}
publicStringgetCity(){
returncity;
}
publicStringgetState(){
returnstate;
}
}
Listing3:CreditCardClass
publicclassCreditCard{
StringcardType;
StringcardNumber;
StringcardExpDate;
finalStringCCDATAFILE=“CC.txt”;
publicCreditCard(StringccType,StringccNumber,
StringccExpDate){
cardType=ccType;
cardNumber=ccNumber;
cardExpDate=ccExpDate;
}
publicbooleanisValid(){
/*
Letsgowithsimplervalidation
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(CCDATAFILE,dataLine,true,true);
}
publicStringgetCardType(){
returncardType;
}
publicStringgetCardNumber(){
returncardNumber;
}
publicStringgetCardExpDate(){
returncardExpDate;
}
}
Listing4:ClientAccountManagerClass
publicclassAccountManagerextendsJFrame{
publicstaticfinal-0*963Stringnewline=“\n”;
publicstaticfinalStringVALIDATESAVE=“Validate&Save”;
publicAccountManager(){
super(“FacadePattern-Example”);
cmbCardType=newJComboBox();
cmbCardType.addItem(AccountManager.VISA);
cmbCardType.addItem(AccountManager.MASTER);
cmbCardType.addItem(AccountManager.DISCOVER);
//Createbuttons
JButtonvalidateSaveButton=newJButton(AccountManager.VALIDATESAVE);
}
publicStringgetFirstName(){
returntxtFirstName.getText();
}
}//EndofclassAccountManager
當客戶AccountManage運行的時候,展示的用戶接口如下:
圖大B:“在這個例子中應用外觀模式是一個很好的設計,它可以降低客戶和子係統組件(Address、Account和CreditCard)之間的耦合度。應用外觀模式,定義一個外觀類CustomerFacade(Figure6andListing5)。它為由客戶數據處理類(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()
publicclassCustomerFacade{
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;
}
}
}
大B:“CustomerFacade類以saveCustomData方法的形式提供了業務層次上的服務。客戶AccountManager不是直接和子係統的每一個組件交互,而是使用了由CustomFacade對象提供的驗證和保存客戶數據的更高層次、更簡單的接口。”
B:“在新的設計中,為了驗證和保存客戶數據,客戶需要:1、建立或獲得外觀對象CustomFacade的一個實例。2、傳遞數據給CustomFacade實例進行驗證和保存。3、調用CustomFacade實例上的saveCustomData方法。CustomFacade處理創建子係統中必要的對象並且調用這些對象上相應的驗證、保存客戶數據的方法這些細節問題。客戶不再需要直接訪問任何的子係統中的對象。”
小A:“師兄,應用外觀模式有哪些注意事項?”
大B:“應用外觀模式要注意以下事項:1、在設計外觀時,不需要增加額外的功能。2、不要從外觀方法中返回子係統中的組件給客戶。例如:有一個下麵的方法:CreditCardgetCreditCard()會報漏子係統的細節給客戶。應用就不能從應用外觀模式中取得最大的好處。3、應用外觀的目的是提供一個高層次的接口。因此,外觀方法最適合提供特定的高層次的業務服務,而不是進行底層次的單獨的業務執行。”
小A:“明白。我記住了!”