书城计算机大话设计模式
11030400000031

第31章 4 例子

大B:“我给你举个例子来说明吧!”

小A:“嗯。好的。”

大B:“让我们建立一个应用:1、接受客户的详细资料(账户、地址和信用卡信息)2、验证输入的信息3、保存输入的信息到相应的文件中。这个应用有三个类:Account、Address和CreditCard。每一个类都有自己的验证和保存数据的方法。”

Listing1:AccountClass

public class Account{

String firstName;

String lastName;

final String ACCOUNTDATAFILE=“AccountData。txt”;

public Account(String fname,String lname){

firstName=fname;

lastName=lname;

}

public boolean isValid(){

/*

Lets go with simpler validation

here to keep the example simpler。

*/

}

public boolean save(){

FileUtil futil=new FileUtil();

String dataLine=getLastName() , getFirstName();

return futil。writeToFile(ACCOUNTDATAFILE,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 ADDRESSDATAFILE=“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。

Lets 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(ADDRESSDATAFILE,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 CCDATAFILE=“CC。txt”;

public CreditCard(String ccType,String ccNumber,

String ccExpDate){

cardType=ccType;

cardNumber=ccNumber;

cardExpDate=ccExpDate;

}

public boolean isValid(){

/*

Lets 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(CCDATAFILE,dataLine,true,true);

}

public String getCardType(){

return cardType;

}

public String getCardNumber(){

return cardNumber;

}

public String getCardExpDate(){

return cardExpDate;

}

}

Listing4:Client AccountManager Class

public class AccountManager extends JFrame{

public static final-0*963String newline=“\n”;

public static final String VALIDATESAVE=“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。VALIDATESAVE);

}

public String getFirstName(){

return txtFirstName。getText();

}

}//End of class AccountManager

当客户AccountManage运行的时候,展示的用户接口如下:

图大B:“在这个例子中应用外观模式是一个很好的设计,它可以降低客户和子系统组件(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()

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;

}

}

}

大B:“CustomerFacade类以saveCustomData方法的形式提供了业务层次上的服务。客户AccountManager不是直接和子系统的每一个组件交互,而是使用了由CustomFacade对象提供的验证和保存客户数据的更高层次、更简单的接口。”

B:“在新的设计中,为了验证和保存客户数据,客户需要:1、建立或获得外观对象CustomFacade的一个实例。2、传递数据给CustomFacade实例进行验证和保存。3、调用CustomFacade实例上的saveCustomData方法。CustomFacade处理创建子系统中必要的对象并且调用这些对象上相应的验证、保存客户数据的方法这些细节问题。客户不再需要直接访问任何的子系统中的对象。”

小A:“师兄,应用外观模式有哪些注意事项?”

大B:“应用外观模式要注意以下事项:1、在设计外观时,不需要增加额外的功能。2、不要从外观方法中返回子系统中的组件给客户。例如:有一个下面的方法:CreditCard getCreditCard()会报漏子系统的细节给客户。应用就不能从应用外观模式中取得最大的好处。3、应用外观的目的是提供一个高层次的接口。因此,外观方法最适合提供特定的高层次的业务服务,而不是进行底层次的单独的业务执行。”

小A:“明白。我记住了!”