适配器Adapter是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。简单地说,存在两个不相干不兼容的class1和class2,class1想要实现class2中的某些方法或功能,定义一个适配器adapter类来实现class2中的方法和功能,class1通过继承adapter或者持有adapter的对象,就能成功使用class2中的方法和功能,这个class2 可以是集合了所有需要用到的方法和功能的Target类。
举个例子:大象和飞机是两个八竿子打不着的类,但是呢现在的业务需求是使大象装上飞机的机翼,你不能让大象直接继承飞机吧,也不能直接引用一个飞机对象吧,要是后期要实现一个象群岂不是要应用很多飞机,所有直接用一个包含了一个adapter类,引用一个飞机对象,并有自己的方法来调用了飞机的机翼,然后大象就可以通过继承或者引用adapter来实现装上机翼了。
适配器模式分为两种,一种是类适配器,一种是对象适配器。
类适配器:
通过继承adapter类来实现
对象适配器:
通过调用adapter来实现
应用场景:
1:当系统要使用现有的类,但是现有的类接口不符合系统需求时。
2.当需要通过常见一个可以复用的类,使得本来接口不相容并且无关的类结合在一起工作时
3.在设计中需要改变多个子类接口,在作用相同但名称不同的类或者方法之间进行适配时。
个人感觉adapter就是归纳,归纳好后形成一个工具类,供其他类调用或者继承。
【实验报告】以下部分可以不用看来
实验一:类适配器
代码修改或添加部分:
public interface CusInfoValidator{
public abstract boolean isValidName(String name);
public abstract boolean isValidAddress(String address);
public abstract boolean isValidZipCode(String zipCode);
public abstract boolean isValidCellPhoneNum(String phoneNum);
public abstract boolean isValidSSNNum(String SSNNum);
//添加
public abstract boolean isValidEmailAddr(String EmailAddr);
}
class InformationAdapter extends InfoValidation implements CusInfoValidator {
public boolean isValidSSNNum(String SSNNum) {
boolean isValid = true;
String ns = SSNNum.trim();
String nStr = ns.replaceAll("\\s{1,}", "");
int len = nStr.length();
if ((nStr.charAt(3) == '-') && (nStr.charAt(6) == '-') && (len == 11)) {
for (int m = 0; m < len; m++) {
if ((m != 3) && (m != 6) && (Character.isDigit(nStr.charAt(m)) == false)) {
isValid = false;
}
}
return isValid;
} else {
return false;
}
}
//10234423@qq.com
//电子邮件地址应由26个英文字母和数字(0、1、2、3、4、5、6、7、8、9)混合的英文字符组成,
//正好有一个“@”,至少有一个句号“”。
//域名应该是26个英文字母
//整个邮件地址的长度至少为5@Override
public boolean isValidEmailAddr(String Email) {
boolean flag = false;
try {
String check = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
Pattern regex = Pattern.compile(check);
Matcher matcher = regex.matcher(Email);
flag = matcher.matches();
} catch (Exception e) {
flag = false;
}
return flag;
}
}
时序图
实验二:对象适配器
代码修改或添加
public class ChinesePostalCode {
private boolean digitFlag = true;
/*
中国邮政编码是由6位数字构成
*/
public boolean isValidChinesePcode(String postalCode, String province) {
char[] pCode = toNonBlankCharArray(postalCode);
if (pCode.length != 6)
return false;
for(int i=0; i<pCode.length; i++){
if(Character.isDigit(pCode[i]) == false)
digitFlag = false;
}
return digitFlag;
}
//去掉输入的所有空格
public char[] toNonBlankCharArray(String postalCode){
int m=0;
for (int k=0;k<postalCode.length(); k++){
if (Character.isSpaceChar(postalCode.charAt(k)) == false ){
m++;
}
}
char[] p = new char[m];
int n = 0;
for (int k=0;k<postalCode.length(); k++){
if (Character.isSpaceChar(postalCode.charAt(k)) == false ){
p[n] = postalCode.charAt(k);
n++;
}
}
return p;
}
}
public class CNPostalCodeAdapter implements ZipCodeValidator{
public ChinesePostalCode objCPostCode ;
public CNPostalCodeAdapter(ChinesePostalCode objCPostCode){
this.objCPostCode=objCPostCode ;
}
@Override
public boolean isValidZipCode(String postalCode, String province) {
return objCPostCode.isValidChinesePcode(postalCode,province);
}
}
类customer
public class Customer {
public static final String US = "US";
public static final String CANADA = "Canada";
//添加
public static final String CHINA = "China";
private String country, state,zip;
public boolean isValidZip() {
if (country.equals(Customer.US)) {
USAZipCode us = new USAZipCode();
return us.isValidZipCode(zip, state);
}
if (country.equals(Customer.CANADA)) {
CanadianPostalCode objCAPCode = new CanadianPostalCode();
ZipCodeValidator adapter = new CAPostalCodeAdapter(objCAPCode);
return adapter.isValidZipCode(zip, state);
}
//here
if (country.equals(Customer.CHINA)){
ChinesePostalCode objCNPCode=new ChinesePostalCode();
ZipCodeValidator adapter =new CNPostalCodeAdapter(objCNPCode) ;
return adapter.isValidZipCode(zip,state);
}
else
return false;
}
public Customer( String inp_zip, String inp_state, String inp_country) {
zip = inp_zip;
state = inp_state;
country = inp_country;
}
}
输入输出:
类图:
时序图: