Java 设计模式 适配器模式


        当现有的某个类的接口不能满足客户所需要的接口,需要将这个类的接口转换为客户想要的接口,可以使用适配器模式。这相当于给接口做了一个适配,使这个接口可以在现有的模块内可以使用。

       举一个简单的例子,我们国家家用电网提供的是220V交流电,对于台式机而言,主板需要12V直流电,当然不能直接拿交流电来使用啦。所以主机都有一个电源适配器,将220V 交流电 转换成 12V直流电。这个电源适配器就是从中间起到了一个转换的作用。

看一下类图:

 

Java 设计模式 适配器模式_第1张图片

[java] view plain copy
print ?
  1. package com.lou.adapter.instance;  
  2.   
  3. public interface AbstractComputerPower {  
  4.   
  5.     /* 
  6.      * 直流电电源 提供直流电 
  7.      */  
  8.     public String provideDirectCurrent();  
  9. }  

 

[java] view plain copy
print ?
  1. package com.lou.adapter.instance;  
  2.   
  3. public interface AbstractNationalPower {  
  4.   
  5.     /* 
  6.      * 国家电网提供交流电 
  7.      */  
  8.     public String provideAlternatableCurrent();  
  9. }  

 

[java] view plain copy
print ?
  1. package com.lou.adapter.instance;  
  2.   
  3. public class ComputerPowerAdapter implements AbstractComputerPower {  
  4.   
  5.     private AbstractNationalPower power = new ChinesePower();  
  6.     @Override  
  7.     public String provideDirectCurrent() {  
  8.           
  9.         String nationalPower = power.provideAlternatableCurrent();  
  10.         return transfer(nationalPower);  
  11.     }  
  12.   
  13.     private String transfer(String nationalPower)  
  14.     {  
  15.         System.out.println( "对交流电整流,变压,输出直流电");  
  16.         return "12V 直流电";  
  17.     }  
  18. }  


 

[java] view plain copy
print ?
  1. package com.lou.adapter.instance;  
  2.   
  3. public class Client {  
  4.   
  5.     public static void main(String[] args) {  
  6.         AbstractComputerPower  computerPower = new ComputerPowerAdapter();  
  7.         computerPower.provideDirectCurrent();  
  8.     }  
  9. }  


 

[java] view plain copy
print ?
  1. package com.lou.adapter.instance;  
  2.   
  3. public class ChinesePower implements AbstractNationalPower {  
  4.   
  5.     @Override  
  6.     public String provideAlternatableCurrent() {  
  7.         return "220V 交流电。";  
  8.     }  
  9. }  


综上,适配器模式是指:

         将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不 兼容 而不能一起工作的那些类可以一起工作。——Gang of Four

适配器的通用模型为:

 Java 设计模式 适配器模式_第2张图片

 

 适配器模式最后真正完成业务的还是靠原来的接口,adapter从中间起到了转换,代理的作用。

 

再举一个更实际的例子:

在 项目中会涉及到查询用户信息的相关操作,在当前系统内,既有的底层提供的用户信息接口如下:

[java] view plain copy
print ?
  1. package com.lou.patterns.adapter;  
  2.   
  3. public interface UserInfo {  
  4.   
  5.     public String getUserName();  
  6.       
  7.     public String getUserId();  
  8.       
  9.     public Integer getUserAge();  
  10.       
  11.     public String getUserProvince();  
  12.       
  13.     public String getUserCity();  
  14.       
  15.     public String getUserStreet();  
  16.       
  17. }  

当前系统内,用户查询接口 可以查询 用户名,用户id,年龄 ,用户所在的省份,所在的城市,所在的街道。

但是现在系统的另外一个模块定义的用户查询 接口如下:

[java] view plain copy
print ?
  1. package com.lou.patterns.adapter;  
  2.   
  3. public interface UserInformation {  
  4.   
  5.     public String getUserName();  
  6.       
  7.     public String getUserId();  
  8.       
  9.     public Integer getUserAge();  
  10.          //UserAddredss = province + city + street;   
  11.          public String getUserAddress();  
  12.       
  13. }  

即:这个模块定义的用户查询接口应该为 查询用户名,用户id,用户年龄,用户的地址
现在就会存在问题:因为这个模块定义的接口和底层定义的接口不兼容,无法将底层的UserInfo 实现类直接拿来使用,现在要在这两个接口之间架起一道桥梁,使我们可以是两个模块兼容起来,所以,我们构造一个适配器,这个适配器要能完成 UserInformation 定义的功能:

 

[java] view plain copy
print ?
  1. package com.lou.patterns.adapter;  
  2.   
  3. public class UserInfoAdapter implements UserInformation{  
  4.   
  5.     private UserInfo userInfo;  
  6.   
  7.     @Override  
  8.     public String getUserName() {  
  9.         return userInfo.getUserName();  
  10.     }  
  11.   
  12.     @Override  
  13.     public String getUserId() {  
  14.         return userInfo.getUserId();  
  15.     }  
  16.   
  17.     @Override  
  18.     public Integer getUserAge() {  
  19.         return userInfo.getUserAge();  
  20.     }  
  21.   
  22.     @Override  
  23.     public String getUserAddress() {  
  24.         return userInfo.getUserProvince()+" " + userInfo.getUserCity()+ " " +userInfo.getUserStreet();  
  25.     }  
  26. }  


 

 

[java] view plain copy
print ?
  1. package com.lou.patterns.adapter;  
  2.   
  3. public class UserInfoImpl implements UserInfo{  
  4.   
  5.     UserBean userBean = new UserBean();  
  6.     @Override  
  7.     public String getUserName() {  
  8.         return userBean.getName();  
  9.     }  
  10.   
  11.     @Override  
  12.     public String getUserId() {  
  13.         return userBean.getId();  
  14.     }  
  15.   
  16.     @Override  
  17.     public Integer getUserAge() {  
  18.         return userBean.getAge();  
  19.     }  
  20.   
  21.     @Override  
  22.     public String getUserProvince() {  
  23.         return userBean.getProvince();  
  24.     }  
  25.   
  26.     @Override  
  27.     public String getUserCity() {  
  28.         return userBean.getCity();  
  29.     }  
  30.   
  31.     @Override  
  32.     public String getUserStreet() {  
  33.         return userBean.getStreet();  
  34.     }  
  35.   
  36. }  


 

[java] view plain copy
print ?
  1. package com.lou.patterns.adapter;  
  2.   
  3. public class UserBean {  
  4.   
  5.     private String name;  
  6.     private String id;  
  7.     private Integer age;  
  8.     private String province;  
  9.     private String city;  
  10.     private String street;  
  11.     public String getName() {  
  12.         return name;  
  13.     }  
  14.     public void setName(String name) {  
  15.         this.name = name;  
  16.     }  
  17.     public String getId() {  
  18.         return id;  
  19.     }  
  20.     public void setId(String id) {  
  21.         this.id = id;  
  22.     }  
  23.     public Integer getAge() {  
  24.         return age;  
  25.     }  
  26.     public void setAge(Integer age) {  
  27.         this.age = age;  
  28.     }  
  29.     public String getProvince() {  
  30.         return province;  
  31.     }  
  32.     public void setProvince(String province) {  
  33.         this.province = province;  
  34.     }  
  35.     public String getCity() {  
  36.         return city;  
  37.     }  
  38.     public void setCity(String city) {  
  39.         this.city = city;  
  40.     }  
  41.     public String getStreet() {  
  42.         return street;  
  43.     }  
  44.     public void setStreet(String street) {  
  45.         this.street = street;  
  46.     }  
  47. }  



Java 设计模式 适配器模式_第3张图片


这样,两个模块就可以兼容起来使用了。

总结:

适配器模式在于,adaptee在系统中的不可代替性,一般为模块的底层或者是基础部分,当遇到不兼容的情况时,不方便或者对于当前系统稳定性和拓展性的考虑,应当遵循 “对修改关闭,对拓展开放”的原则,使用适配器模式可以很好地满足这一点。

这里的适配器模式,有一定程度的代理模式的意味在里面,真正业务的实现偏重在adaptee实现,adapter再对其进行转换,满足另外一个模块的要求。

 


本文转载自:http://blog.csdn.net/luanlouis/article/details/18404759

你可能感兴趣的:(Java 设计模式 适配器模式)