美文网首页
java--适配模式

java--适配模式

作者: Raral | 来源:发表于2021-11-26 19:27 被阅读0次

    适配模式(Adapter Pattern)

    适配器模式的定义

    适配器模式:将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作。

    适配器模式的别名为包装器(Wrapper)模式,它既可以作为类结构型模式,也可以作为对象结构型模式。在适配器模式定义中所提及的接口是指广义的接口,它可以表示一个方法或者方法的集合。

    适配器模式的结构

    类适配器模式结构图:

    image-20211127145629618.png

    活动发劵举例子

    
    //目标接口
    public interface AtvSendCoupon {
        //目标接口期待的方法
        public void sendCouponByAtv();
    }
    
    
    //适配者(源类)
    public class SendCouponAdpatee {
        public void sendCoupon(){
            System.out.println("发劵逻辑(最核心方法)");
        }
    
    }
    
    
    //适配器类(针对活动发劵适配的)
    public class AtvSendCouponAdpater extends SendCouponAdpatee implements AtvSendCoupon {
        @Override
        public void sendCouponByAtv() {
            System.out.println("活动发劵的逻辑");
            this.sendCoupon();
        }
    }
    
    
    //客户端测试
    public class Test {
        public static void main(String[] args) {
            //1.使用 活动适配器
            AtvSendCouponAdpater atvSendCouponAdpater = new AtvSendCouponAdpater();
            atvSendCouponAdpater.sendCouponByAtv();
        }
        
        //活动发劵的逻辑
        //发劵逻辑(最核心方法)
    
    }
    
    

    UXM类图

    image-20211127151539484.png

    适配器模式-扩展

    场景需求:

    /**
     * 需求:
     * 1. 退款流程分两种
     *      a. 通过xxx平台退劵有两个途径;在xxx1退劵,在xxx2退劵(核心流程一样)
     *      b. yyy退劵(组合劵): 在yyy的退劵(又是核心流程一种)
     *
     * 实现思路:
     * 1. 需要一个 xxx退劵的适配器,和一个yyy退劵的适配器
     * 2. 需要把两个对应的适配器在项目启动自动加载进去
     * 3. 需要一个派发类,去控制 是执行xxxx的适配器退款逻辑,还是执行yyyy退劵的逻辑
     * 4. 不同的客户端测试
     * */
    
    image-20211127170929648.png

    代码搭建--适配器搭建

    1. 目标接口2(IPackageRefund-权益包退款接口)
    //目标接口2(权益包平台退款)
    public interface IPackageRefund {
        //客户端期待的退款方法
        public void refund();
    }
    
    
    1. 目标接口1(IZszRefund-折上折退款接口)

      //目标接口1(折上折平台退款)
      public interface IZszRefund {
          //客户端期待的退款方法
          public void refund();
      }
      
      
    2. 适配者-抽象类(AbstractRefundAdaptee--核心方法注册适配器插件)

    //适配者 抽象类,作用:自动注册到适配器集合里
    public abstract class AbstractRefundAdaptee implements IRefundAdapterPlugin {
    
    
    
        //构造函数
        public AbstractRefundAdaptee() {
            this.register();
        }
    
        //自动注册
      
    public interface IRefundAdapterPlugin {
        String getAdapterName();
    }
      private void register() {
    //        System.out.println("自动注册");
            //单例模式调用
            AutoRefundAdapterBundleService instance = AutoRefundAdapterBundleService.getInstance();
            instance.register(this);
    //        AutoRefundAdapterBundleService autoRefundAdapterBundleService = new AutoRefundAdapterBundleService();
    //        autoRefundAdapterBundleService.register(this);
    
        }
    }
    
    

    IRefundAdapterPlugin 退款适配器插件-作用是让每一个子类的适配器定义适配器插件名称

    //退款适配器插件
    public interface IRefundAdapterPlugin {
        String getAdapterName();
    }
    
    

    AutoRefundAdapterBundleService 自动注册退款适配器插件--作用:提供获取已注册插件和注册插件方法

    此类使用的单例模式--目的为了客户端测试获取到最新的已注册记录

    //自动注册适配器到一个list,并且可以获取所有的适配器
    public class AutoRefundAdapterBundleService {
    
        //先定义一个 适配器的集合
        private List<IRefundAdapterPlugin> adpaters;
    
        //获取所有的适配器
        public List<IRefundAdapterPlugin> getAdpaters() {
            return adpaters;
        }
    
        //注册适配器到list中
        public void register(IRefundAdapterPlugin adapterPlugin) {
            if(adpaters == null) {
                adpaters = new ArrayList<>();
            }
            System.out.println("注册适配器--开始");
            System.out.println(adapterPlugin);
            //适配器注册
            if(!adpaters.contains(adapterPlugin)) {
                adpaters.add(adapterPlugin);
            }
            System.out.println("注册适配器--结束");
        }
    
        //将此类作成单例模式
       public static  AutoRefundAdapterBundleService instance;
        public AutoRefundAdapterBundleService() {}
        public static synchronized AutoRefundAdapterBundleService getInstance() {
            if(instance == null) {
                instance = new AutoRefundAdapterBundleService();
            }
            return instance;
        }
    
    }
    
    
    1. 不同适配器设置
    • 一手劵退款适配器
    // 折上折一手劵退款适配器
    public class FirstRefundAdapter extends AbstractRefundAdaptee implements IZszRefund {
        @Override
        public void refund() {
            System.out.println("折上折一手劵退款适配器--退款的方法");
        }
    
        @Override
        public String getAdapterName() {
            return "FirstRefundAdapter";
        }
    }
    
    • 二手劵退款适配器

      // 折上折二手劵退款适配器
      public class SecondRefundAdapter extends AbstractRefundAdaptee implements IZszRefund {
          @Override
          public void refund() {
              System.out.println("折上折二手劵退款适配器--退款的方法");
          }
      
          @Override
          public String getAdapterName() {
              return "SecondRefundAdapter";
          }
      }
      
      
    • 权益包退款适配器

    // 权益包退款适配器
    public class PackageRefundAdapter extends AbstractRefundAdaptee implements IPackageRefund {
        @Override
        public void refund() {
            System.out.println("权益包退款适配器--退款的方法");
        }
    
        @Override
        public String getAdapterName() {
            return "PackageRefundAdapter";
        }
    }
    
    
    1. 客户端测试验证

      public class Test {
          public static void main(String[] args) {
      
                //1. 先注册适配器插件
              FirstRefundAdapter firstRefundAdapter = new FirstRefundAdapter();
              SecondRefundAdapter secondRefundAdapter = new SecondRefundAdapter();
              PackageRefundAdapter packageRefundAdapter = new PackageRefundAdapter();
      
      
              //2.单例模式查看当前已注册适配器
              AutoRefundAdapterBundleService instance = AutoRefundAdapterBundleService.getInstance();
              List<IRefundAdapterPlugin> adpaters = instance.getAdpaters();
              System.out.println("当前已注册的适配器");
              System.out.println(adpaters);
      
              //3. 执行不同适配器的方法
              firstRefundAdapter.refund();
              secondRefundAdapter.refund();
              packageRefundAdapter.refund();
          }
      }
      
      /**
       * 需求:
       * 1. 退款流程分两种
       *      a. 通过xxx平台退劵有两个途径;在xxx1平台退劵,在xxx2退劵(核心流程一样)
       *      b. yyy退劵(组合劵): 在yyy的退劵(又是核心流程一样)
       *
       * 实现思路:
       * 1. 需要一个xxx退劵的适配器,和一个yyy退劵的适配器
       * 2. 需要把两个对应的适配器在项目启动自动加载进去
       * 3. 需要一个派发类,去控制 是执行xxxx的适配器退款逻辑,还是执行yyy退劵的逻辑
       * 4. 不同的客户端测试
       * */
      
      

      终端打印

      注册适配器--开始
      com.kuang.demo06_adapter_pattern_more.adpater.FirstRefundAdapter@2503dbd3
      注册适配器--结束
      注册适配器--开始
      com.kuang.demo06_adapter_pattern_more.adpater.SecondRefundAdapter@4b67cf4d
      注册适配器--结束
      注册适配器--开始
      com.kuang.demo06_adapter_pattern_more.adpater.PackageRefundAdapter@7ea987ac
      注册适配器--结束
      当前已注册的适配器
      [com.kuang.demo06_adapter_pattern_more.adpater.FirstRefundAdapter@2503dbd3, com.kuang.demo06_adapter_pattern_more.adpater.SecondRefundAdapter@4b67cf4d, com.kuang.demo06_adapter_pattern_more.adpater.PackageRefundAdapter@7ea987ac]
      xxx一手劵退款适配器--退款的方法
      

    xxx二手劵退款适配器--退款的方法
    yyy退款适配器--退款的方法

    
    **目录结构**
    
     ![image-20211127184922578.png](https://img.haomeiwen.com/i25041675/5c0c7d2ebc08b6f5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
    
    
    ## 分配器执行退款
    
    ```java
    //分配器执行不同退款适配器退款流程--目的:方便客户端不同的调度使用
    public class RefundDispatcher extends AutoRefundAdapterBundleService {
     private String adapterName = "";//适配器插件名称
    
     //执行退款流程
     public void doRefund(Integer type) {
         //模拟一个区分逻辑
         if(type == 1) {
             adapterName = "FirstRefundAdapter";
         } else if(type == 2) {
             adapterName = "SecondRefundAdapter";
         } else if(type == 3) {
             adapterName = "PackageRefundAdapter";
         }
         //单例模式获取对象
         AutoRefundAdapterBundleService instance = AutoRefundAdapterBundleService.getInstance();
         List<IRefundAdapterPlugin> adpaters = instance.getAdpaters();
         adpaters.stream().forEach(adpater -> {
             try {
                 //反射相关知识
                 Class<? extends IRefundAdapterPlugin> aClass = adpater.getClass();
    
                 Method getAdapterName = aClass.getDeclaredMethod("getAdapterName");
                 String currentName =(String) getAdapterName.invoke(adpater.getClass().newInstance());
                 System.out.println(currentName);
                 Method refund = aClass.getDeclaredMethod("refund");
    
                 if(adapterName.equals(currentName)) {
                     refund.invoke(adpater.getClass().newInstance());
                 }
    
    
    //                if(adpater instanceof IZszRefund) {
    //                    //如果是xxx的适配器
    //                    if(adpater instanceof FirstRefundAdapter) {
    //                        //如果是xxx的一手退款适配器
    //                    }
    //                    if(adpater instanceof SecondRefundAdapter) {
    //                        //如果是xxx的一手退款适配器
    //                    }
    //
    //                }
    //                if(adpater instanceof IPackageRefund) {
    //                    //如果是yyy的适配器
    //
    //                }
             } catch (Exception e) {
                 e.printStackTrace();
             }
    
         });
    
    
     }
    
    }
    
    

    测试验证--通过分配器可以不同切换对应适配器的退款逻辑

    注册适配器--开始
    com.kuang.demo06_adapter_pattern_more.adpater.FirstRefundAdapter@470e2030
    注册适配器--结束
    注册适配器--开始
    com.kuang.demo06_adapter_pattern_more.adpater.SecondRefundAdapter@33833882
    注册适配器--结束
    注册适配器--开始
    com.kuang.demo06_adapter_pattern_more.adpater.PackageRefundAdapter@e2d56bf
    注册适配器--结束
    当前已注册的适配器
    [com.kuang.demo06_adapter_pattern_more.adpater.FirstRefundAdapter@470e2030, com.kuang.demo06_adapter_pattern_more.adpater.SecondRefundAdapter@33833882, com.kuang.demo06_adapter_pattern_more.adpater.PackageRefundAdapter@e2d56bf]
    注册适配器--开始
    com.kuang.demo06_adapter_pattern_more.adpater.FirstRefundAdapter@7a92922
    注册适配器--结束
    FirstRefundAdapter
    注册适配器--开始
    com.kuang.demo06_adapter_pattern_more.adpater.FirstRefundAdapter@71f2a7d5
    注册适配器--结束
    xxx一手劵退款适配器--退款的方法
    

    相关文章

      网友评论

          本文标题:java--适配模式

          本文链接:https://www.haomeiwen.com/subject/wgjqxrtx.html