Adapter 适配器模式

来源:互联网 发布:2016淘宝直通车技巧 编辑:程序博客网 时间:2024/05/16 23:38

模式定义
Adapter适配器模式将不适合客户类使用的接口重新包装,以实现接口的重用。

使用范围

  • 现有的类不能被客户类直接使用或不方便使用

使用方法
适配器模式分两类:

  • 类适配器:类适配器是通过继承类适配者类(Adaptee Class)实现的,另外类适配器实现客户类所需要的接口。当客户对象调用适配器类方法的时候,适配器内部调用它所继承的适配者的方法。
  • 对象适配器:对象适配器包含一个适配器者的引用(reference),与类适配器相同,对象适配器也实现了客户类需要的接口。当客户对象调用对象适配器的方法的时候,对象适配器调它所包含的适配器者实例的适当方法。

通俗一点来讲,类适配器的实现是基于类继承的概念,而对象适配器模式是使用了类的合成的方法。而被适配的对象或类则称为Adaptee。

举例说明

public class User {
private String userID;
private String userPwd;
private String userPostcode;
private static String userChina = "CHINA";
private static String userUsa = "USA";
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
public String getUserPostcode() {
return userPostcode;
}
public void setUserPostcode(String userPostcode) {
this.userPostcode = userPostcode;
}

public boolean checkPostcode(){
...

}

}

客户端创建一个User类的实例,同时需要去检查这个user的postcode的合法性(checkPostcode),可以使用一个postcode的验证类(假设为ChinaPostcode)来完成,而这个验证类为实现代码的可扩展的功能,可以将其公用方法提炼出来作为一个接口(PostcodeValidator)。

public interface PostcodeValidator {
public boolean isPoatcodeCorrect(String postCode);
}

于是这个验证类(ChinaPostcode)实现该接口:

public class ChinaPostcode implements PostcodeValidator{
public boolean isPoatcodeCorrect(String postCode) {
return postCode.length()==6;
}
}

因此,这个时候的User类的验证方法为:

public class User {
...
...
public boolean checkPostcode(){
PostcodeValidator vld = getValidator(userPostcode);
if (vld==null) return false;
return vld.isPoatcodeCorrect(userPostcode);

}

public PostcodeValidator getValidator(String userType){
PostcodeValidator vld = null;
if (userType == User.userChina){
vld = new ChinaPostcode();
}
return vld;
}

}

一切都顺理成章。接下来,客户端想要验证一个美国的postcode,同时手边已经有了一个第三方提供的现成的验证方法类,唯一的缺陷是,无法直接拿来使用,因为调用的接口完全不一样;也不能修改该代码,因为已编译或过于复杂。假设这个第三方的验证类为 UsaPostcode:

public class UsaPostcode {
public boolean validatePost(String postcode){
return postcode.length()==5;
}
}

这时,必须提供一个适配器能让客户直接使用该类。如果该适配器能享用这个第三方类的验证方法同时又能实现我们上面的公共接口,一切都可以解决了。于是就有UsaPostcodeAdapter :

public class UsaPostcodeAdapter extends UsaPostcode implements PostcodeValidator{
public boolean isPoatcodeCorrect(String postCode) {
return validatePost(postCode);
}
}

对于客户端而言,我们可以直接使用该适配器提供的类似ChinaPostcode的同样的验证方法,唯一需要修改的是在User中getValidator必须提供对UsaPostcodeAdapter的一个引用:

public class User {
...
...
public boolean checkPostcode(){
PostcodeValidator vld = getValidator(userPostcode);
if (vld==null) return false;
return vld.isPoatcodeCorrect(userPostcode);

}

public PostcodeValidator getValidator(String userType){
PostcodeValidator vld = null;
if (userType == User.userChina){
vld = new ChinaPostcode();
}
if (userType== User.userUsa){
vld = new UsaPostcodeAdapter();
}
return vld;
}

}

这里,UsaPostcode被称为Adaptee。

类结构示意 该样例的类结构如下:

下载示例

  • Java代码 zigzagsoft_designpattern_adapter.zip