四、外观模式
1.外观模式意图
外观模式定义了一个将子系统的一组接口集成在一起的高层接口,以提供一个一致的界面。通过这个界面,其他系统可以方便的调用子系统中的功能,而忽略子系统内部发生的变化。
2.何时使用外观模式
(1)在设计初期阶段,应该要有意识地将不同的两个层分离。
例如:数据访问层和业务逻辑层、业务逻辑层和表示层,层与层之间建立外观Facade
(2)在开发阶段,子系统往往因为不断地重构演化而变得越来越复杂,增加外观Facade可以提供一个简单的接口,减少他们之间的依赖。
(3)在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,你可以为新系统开发一个外观Facade类,来提供设计粗糙或高度复杂的遗留代码的比较清晰简单的接口,让新系统与Facade对象交互,Facade与遗留代码交互所有复杂的工作。
3.应用外观模式的注意事项
(1)在设计外观时,不需要增加额外的功能
(2)不要从外观方法中返回子系统中的组件给客户
(3)应用外观的目的是提供一个高层次的接口
因此,外观方法最适合提供特定的高层次的业务服务,而不是进行底层次的单独的业务执行
例子:
建立一个应用:
1.接受客户的详细资料(账户、地址和信用卡信息)应该有三个类:Account Address CreditCard
2.验证输入的信息
3.保存输入的信息到相应的文件中
定义一个外观类CustomerFacade 让它为客户处理(ccount Address CreditCard)所组成的子系统提供一个高层次、简单的接口
Account类:
public class Account {
String firstName;
String lastName;
final String ACCOUNT_DATA_FILE = "AccountData.txt";
public Account(String firstName, String lastName) {
super();
this.firstName = firstName;
this.lastName = lastName;
}
public boolean isValid(){
return true;
}
/**
* 验证时候保存
* @return
*/
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 void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
Address类:
public class Address {
String address;
String city;
String state;
final String ADDRESS_DATA_FILE = "Address.text";
public Address(String address, String city, String state) {
super();
this.address = address;
this.city = city;
this.state = state;
}
public boolean isValid(){
if(getState().trim().length()<2){
return false;
}else{
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 void setAddress(String address) {
this.address = address;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
CreditCard 类
public class CreditCard {
String cardType;
String cardNumber;
String cardExpDate;
final String CC_DATA_FILE = "Card.txt";
public CreditCard(String cardType, String cardNumber, String cardExpDate) {
super();
this.cardType = cardType;
this.cardNumber = cardNumber;
this.cardExpDate = cardExpDate;
}
public boolean isValid(){
if(getCardType().equals("AccountManager.VISA")){
return (getCardNumber().trim().length() == 16);
}
if(getCardType().equals("AccountManager.DISCOVER")){
return (getCardNumber().trim().length() == 15);
}
if(getCardType().equals("AccountManager.MUSTER")){
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 void setCardType(String cardType) {
this.cardType = cardType;
}
public String getCardNumber() {
return cardNumber;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
public String getCardExpDate() {
return cardExpDate;
}
public void setCardExpDate(String cardExpDate) {
this.cardExpDate = cardExpDate;
}
}
需要在创建一个用户类AccountManager,这里省去
现在的交互如图:
接下来定义一个外观类CustomerFacade 让它为客户处理(ccount Address CreditCard)所组成的子系统提供一个高层次、简单的接口。
CustomerFacade 类:
public class CustomerFacade {
public String address;
public String city;
public String state;
public String cardType;
public String cardNumber;
public String cardExpDate;
public String fname;
public String lname;
public void setAddress(String address) {
this.address = address;
}
public void setCity(String city) {
this.city = city;
}
public void setState(String state) {
this.state = state;
}
public void setCardType(String cardType) {
this.cardType = cardType;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
public void setCardExpDate(String cardExpDate) {
this.cardExpDate = cardExpDate;
}
public void setFname(String fname) {
this.fname = fname;
}
public void setLname(String lname) {
this.lname = lname;
}
public boolean saveCustomerData(){
Address objAddress;
Account objAccount;
CreditCard objCreditCard;
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(objAccount.save() && objAddress.save() && objCreditCard.save()){
return true;
}else{
return false;
}
}
}
有了CustomerFacade ,降低了客户和子系统(ccount Address CreditCard)之间耦合度。
客户和信息之间的交互: