• Java设计模式之适配器设计模式(项目升级案例)


           今天是我学习到Java设计模式中的第三个设计模式了,但是天气又开始变得狂热起来,对于我这个凉爽惯了的青藏人来说,又是非常闹心的一件事儿,好了不管怎么样,目标还是目标(争取把23种Java设计模式接触一遍),我在北京向各位问好。老规矩,首先和各位谈谈适配器模式到底是个什么样的设计思想,而且在实际开发中又是如何应用的。

           那些官方的概念我就不在这儿粘贴了,请各位自己想想办法。所谓适配器模式,按我意思说吧,其实它的目的就想达到新老兼容,使把原本不能放在一块工作的类或对象能够让它们同时使用起来,举个例子:比如拿一个互联网产品它的升级换代过程来说吧,如果我们想升级一个产品后不仅能正常使用新开发接口的功能,而且还能保证原来接口的功能依然能正常调用,那么就必须考虑到兼容老接口的问题,这时我们设计的时候可以采用"适配器模式"就可以做到。再比如:有一位阿富汗女子在环游世界,假设她到中国爬长城顺便买了一个手机充电器,完事后接着打算去德国柏林找一个男朋友,可是到了德国她想给她的手机充电,但是问题来了,德国插座的插头只能是2个圆头插头,但是她买的充电器的插头是3个扁平得插头,所以无法使用,这时她不得不在网上订购一个电源转换头才能充电,到这儿我们就能正大光明的引出我们的"适配器设计模式"了,正因为有了它的出现,这些问题才得以解决,而且还让阿富汗女子正常充上电(哈哈哈,纯属虚构望各位不要嘲笑我,我只不过是想给自己找点乐趣能够如愿以偿地学完适配器模式罢了)。

           好了,我也不多扯了,直接上码,因为设计模式这块不是说你敲敲代码就能学会的,必须自己悟,希望我的总结能帮助各位更快的切入进去,更好的掌握适配器设计模式,再声明一次,我文章中的案例都是本人虚构的,如有不妥,请勿谩骂。

    【案例一】:

           项目的更新升级,假设对项目中获取用户信息的功能进行了改造,原来是通过主键获取用户信息,但是升级之后是通过主键和用户账号也能获取到用户信息,但是能够保证新功能和老功能都正常调用,这里我们可以通过适配器模式来设计,达到该需求。

    新开发的接口和原来的接口:

    复制代码
     1 /**
     2  * 旧接口
     3  */
     4 interface OldService{
     5     //根据主键获取用户信息
     6     Map<String,Object> getUserInfo(String Id);
     7 }
     8 /**
     9  * 旧接口实现类
    10  */
    11 class OldServiceImpl implements OldService{
    12     //根据主键获取用户信息
    13     @Override
    14     public Map<String,Object> getUserInfo(String Id) {
    15         HashMap<String,Object> userInfo = new HashMap<>();
    16         userInfo.put("id", Id);
    17         return userInfo;
    18     }
    19 }
    20 
    21 /**
    22  * 新接口
    23  */
    24 interface NewService{
    25     //根据主键和账号获取用户信息
    26     Map<String,Object> getUserInfo(String Id,String account);
    27 }
    28 /**
    29  * 新接口实现类
    30  */
    31 class NewServiceImpl implements NewService{
    32     @Override
    33     public Map<String,Object> getUserInfo(String Id, String account) {
    34         HashMap<String,Object> userInfo = new HashMap<>();
    35         userInfo.put("id", Id);
    36         userInfo.put("account", account);
    37         return userInfo;
    38     }
    39 }
    复制代码

           为了能够兼容新老接口同时使用,则通过适配器模式来设计一个适配器类,该适配器类需要实现新接口,因为项目已经开发了新接口,我们不可能再去使用旧接口的功能,其次在适配器类中声明一个老接口的实例,目的是能够兼容老接口中的方法。

    复制代码
     1 /**
     2  * 接口适配器,兼容新老接口的功能都能正常调用
     3  */
     4 class InterfaceAdapter implements NewService{    //既然开发了新接口,就必须使用新接口的功能,实现新接口
     5     
     6     //该适配器是针对为了能够兼容老接口正常使用,则在创建适配器对象时必须传入一个旧接口的实现类对象
     7     private OldService oldService;
     8     public InterfaceAdapter(OldService oldService) {
     9         this.oldService = oldService;
    10     }
    11     
    12     //经过适配器的兼容,就能通过适配器来正常调用旧接口的功能
    13     @Override
    14     public Map<String, Object> getUserInfo(String Id, String account) {
    15         System.out.println("升级后兼容旧接口");
    16         return oldService.getUserInfo(Id);
    17     }
    18 }
    复制代码

           最后通过测试,不管是新接口还是老接口,还是你想调用新接口时达到老接口的功能都没问题,适配器模式都帮你解决了这些问题。

    复制代码
     1 public class AdapterUpgrade {
     2 
     3     public static void main(String[] args) {
     4         //使用旧接口功能
     5         OldService old = new OldServiceImpl();
     6         Map<String, Object> oldMap = old.getUserInfo("7758520");
     7         System.out.println("旧接口功能:"+oldMap);
     8         
     9         //使用新接口功能
    10         NewService nw = new NewServiceImpl();
    11         Map<String, Object> newMap = nw.getUserInfo("7758520", "18513032646");
    12         System.out.println("新接口功能:"+newMap);
    13         
    14         //通过适配器,升级后依然兼容旧接口的功能
    15         InterfaceAdapter adapter = new InterfaceAdapter(old);
    16         oldMap = adapter.getUserInfo("7758820", "18513032646");
    17         System.out.println(oldMap);
    18     }
    19 }
    复制代码

    【案例二】:

           就是阿富汗女子环游世界,在不同的国家遇到充电的问题,适配器模式也能帮你解决了,设计思想还是不变,只是看你怎么理解了,设计模式这东西吧,看是看不来的,看多了只会浮躁我今天早上刚入手时,看了半天理论找了半天例子,一头雾水,一个Demo下来,详细斟酌了一会儿感觉到模式还是模式啊,自有它的强大之处,不说了,还是看码吧。

    复制代码
     1 /**
     2  * 适配器模式
     3  * 需求:一位阿富汗女子环游世界,首先她到中国爬长城顺便买了一个手机充电器给手机充电,接着打算去德国柏林找一个男朋友,可是到了德国她想给手机充电,
     4  *     但是问题来了,在德国插座的插头只能是2个圆头插头,但是中国充电器的插头是2/3个扁平插头,所以无法使用。
     5  */
     6 
     7 /**
     8  * 测试
     9  */
    10 public class Adapter {
    11     public static void main(String[] args) {
    12         //在德国使用德国充电器进行充电
    13         DBSocketInterface dbSocket = new DBSocket();
    14         dbSocket.DBCharge();
    15         
    16         //在中国使用中国充电器进行充电
    17         GBSocketInterface gbSocket = new GBSocket();
    18         gbSocket.GBCharge();
    19         
    20         //在德国使用中国充电器进行充电
    21         SocketAdapter adapter = new SocketAdapter(gbSocket);
    22         adapter.DBCharge();
    23     }
    24 }
    25 
    26 /**
    27  * 手机电源适配器,为了能够让阿富汗女子在德国正常使用中国的手机充电器。
    28  */
    29 class SocketAdapter implements DBSocketInterface{    //既然来到德国,就必须使用德国插座充电,实现德国插座接口
    30     
    31     //因为该适配器是针对中国插座的,所以在创建适配器对象时必须传入中国插座接口的实现类对象
    32     private GBSocketInterface gbSocket; //中国插座接口
    33     public SocketAdapter(GBSocketInterface gbSocket) {    
    34         this.gbSocket = gbSocket;
    35     }
    36 
    37     //经过适配器的转换,中国的充电器就可以在德国的插座上正常充电了
    38     @Override
    39     public void DBCharge() {
    40         System.out.println("在德国,经过电源适配器转换*****");
    41         gbSocket.GBCharge();
    42     }
    43     
    44 }
    45 
    46 /**
    47  * 德国插座(2个圆头的插头)
    48  */
    49 interface DBSocketInterface{
    50     //德国插座充电
    51     void DBCharge();
    52 }
    53 /**
    54  * 使用德国插座给手机充电
    55  */
    56 class DBSocket implements DBSocketInterface{
    57     @Override
    58     public void DBCharge() {
    59         System.out.println("2个圆头插头充电");
    60     }
    61 }
    62 
    63 /**
    64  * 中国插座(2/3个扁平的插头)
    65  */
    66 interface GBSocketInterface{
    67     //中国插座充电
    68     void GBCharge();
    69 }
    70 /**
    71  * 使用中国插座给手机充电
    72  */
    73 class GBSocket implements GBSocketInterface{
    74     @Override
    75     public void GBCharge() {
    76         System.out.println("2/3个扁平插头充电");
    77     }
    78 }
    复制代码

           还是那句话,目标还是目标,23种设计模式的学习一直在路上。

  • 相关阅读:
    Compiling Open Source Software for UNIX using Configure Script
    vlcandroid 移植live555到android
    xcode中armv6与armv7的困惑
    ZOJ 3204 Connect them (最小生成树,输出字典序最小的解)
    POJ 3133 Manhattan Wiring (插头DP)
    HDU 4419 Colourful Rectangle 第37届ACM/ICPC 杭州赛区网络赛 1010题 (线段树)
    HDU 3829 Cat VS Dog (二分匹配求最大独立集)
    最大流模板(SAP算法)(邻接表形式)
    HDU 4417 Super Mario 第37届ACM/ICPC 杭州赛区网络赛第1008题 (划分树)
    ZOJ 3203 Light Bulb (数学直接推公式 或者 三分法)
  • 原文地址:https://www.cnblogs.com/wangchaoyuana/p/7545289.html
Copyright © 2020-2023  润新知