秒懂设计模式--学习笔记(10)【结构型-适配器模式】

2024-07-19 1365阅读

目录

      • 9、适配器模式
          • 9.1 适配器模式
          • 9.2 翻译(举例)
          • 9.3 插头与插座(举例)
          • 9.4 通用适配器(对象适配器)
          • 9.5 特定适配器(类适配器)
          • 9.6 化解难以调和的矛盾

            9、适配器模式

            9.1 适配器模式
            • 适配器模式(Adapter)通常也被称为转换器(适应与匹配)
            • 当一个对象或类的接口不能匹配用户所期待的接口时,适配器就充当中间转换的角色,达到兼容用户接口的目的
            • 适配器也实现了客户端与接口的解耦,提高了组件的可复用性
            • 测试类结构

              秒懂设计模式--学习笔记(10)【结构型-适配器模式】

              9.2 翻译(举例)
              • 不懂英文的人与不懂中文的人交流,双方都听不懂对方说什么
              • 找个会两种语言的翻译官
              • 双方通过翻译官进行交流
              • 这个翻译官就相当于适配两个不兼容接口的适配器
                9.3 插头与插座(举例)
                • 两脚插头与三孔插座
                • 定义通电标准接口:DualPin(两插)、TriplePin(三相)
                  package adapter;
                  /**
                   * @Description 两插
                   */
                  public interface DualPin {
                      /**
                       * 两脚插头: 通电标准
                       * @param l 火线(live)
                       * @param n 零线(null)
                       */
                      public void electrify(int l, int n);
                  }
                  
                  package adapter;
                  /**
                   * @Description 三相
                   */
                  public interface TriplePin {
                      /**
                       * 三孔插座: 通电标准
                       * @param l 火线(live)
                       * @param n 零线(null)
                       * @param e 地线(earth)
                       */
                      public void electrify(int l,int n, int e);
                  }
                  
                  • 定义两插的电视机类TVDualPinImpl
                    package adapter.impl;
                    import adapter.DualPin;
                    /**
                     * @Description 两脚插头的电视机类
                     */
                    public class TVDualPinImpl implements DualPin {
                        @Override
                        public void electrify(int l, int n) {
                            System.out.println("火线通电:" + l + ",零线通电:" + n);
                            System.out.println("电视开机");
                        }
                    }
                    
                    • 但是到这里,可以看到两插和三相的通电便准并不一致,这个两插电视机并不能使用三孔插座进行开机,接口不兼容会提示类型不匹配,如测试类Client.test1()
                      package adapter;
                      import adapter.impl.TVDualPinImpl;
                      /**
                       * @Description 测试类
                       */
                      public class Client {
                          /**
                           * 这个两脚电视机并不能使用三孔插座进行开机
                           * 接口不兼容会提示类型不匹配
                           */
                          private static void test1() {
                          	// 这一行会提示错误
                              TriplePin triplePinDevice = new TVDualPinImpl();
                          }
                      }
                      
                      9.4 通用适配器(对象适配器)
                      • 极端解决方案: 将三孔插座改成两孔插座,三相变两相。这样的话就不能再使用三相了
                      • 如果通过一个中间件来进行兼容适配的话,可以不改变插座原来的功能,而又兼容了两脚插座的使用
                      • 制作一个电源转换器AdapterTriplePinImpl来适配,承上启下,解决接口冲突问题
                        • 适配器实现三相接口
                        • 然后在构造时传入需要被适配的两插接口(表示将两脚接口适配到三孔插座)
                        • 在实现通电方法时,适配器转换两插,达到适配效果
                        • 至此,该适配器就可以将任意两脚插头,匹配到三孔插座了
                          package adapter.impl;
                          import adapter.DualPin;
                          import adapter.TriplePin;
                          /**
                           * @Description 三相适配器(实现三相接口):在三孔插座与两脚插头之间做适配
                           */
                          public class AdapterTriplePinImpl implements TriplePin {
                              /**
                               * 适配:两插(任何此规格的设备都是可以接入进来的)
                               */
                              private DualPin dualPin;
                              /**
                               * 创建适配器:传入需要与三孔插座适配的两脚插头
                               * @param dualPin
                               */
                              public AdapterTriplePinImpl(DualPin dualPin) {
                                  this.dualPin = dualPin;
                              }
                              /**
                               * 适配器实现
                               * @param l 火线(live)
                               * @param n 零线(null)
                               * @param e 地线(earth)
                               */
                              @Override
                              public void electrify(int l, int n, int e) {
                                  // 被适配的方法,忽略地线e
                                  dualPin.electrify(l, n);
                              }
                          }
                          
                          • 使用适配器进行接入,Client.test2()
                                /**
                                 * 对象适配器兼容两插和三孔设备
                                 *      输出结果:
                                 *          火线通电:1,零线通电:0
                                 *          电视开机
                                 */
                                private static void test2() {
                                    // 两插电视机(需要进行适配的)
                                    DualPin tvDualPin = new TVDualPinImpl();
                                    // 适配器,串联两插和三孔:将电视机两相插头插入适配器,并将匹配好的适配器插入墙上的三相插孔
                                    TriplePin triplePin = new AdapterTriplePinImpl(tvDualPin);
                                    // 底层使用三孔(适配)的通电标准:直接调用三插通电方法给电视机供电
                                    triplePin.electrify(1, 0, -1);
                                }
                            
                            • 适配器并不关心接入的设备是电视机还是电冰箱,只要是两相插头的设备均可以进行适配,所以说它是一种通用的适配器
                              9.5 特定适配器(类适配器)
                              • 属于某个类的“专属适配器”,也就是在编码阶段已经将被匹配的设备与目标接口进行对接了
                              • 电视机专属适配器类TVAdapter,继承两插电视机类,实现三相接口类:
                                • 类适配器模式实现起来更简单
                                • 继承两插电视,表明该适配器兼容两插
                                • 实现三项接口,表明该适配器适配三相
                                • 重写三相通电方法
                                • 在通电方法中,使用“super”关键字调用父类(电视机类TV)定义的两插通电方法,以实现适配
                                  package adapter.impl;
                                  import adapter.TriplePin;
                                  /**
                                   * @Description 电视机专属适配器类:
                                   *                  类适配器模式实现起来更简单
                                   *                  继承两插电视,表明该适配器兼容两插
                                   *                  实现三项接口,表明该适配器适配三相
                                   */
                                  public class TVAdapter extends TVDualPinImpl implements TriplePin {
                                      /**
                                       * 重写三相通电方法
                                       * @param l 火线(live)
                                       * @param n 零线(null)
                                       * @param e 地线(earth)
                                       */
                                      @Override
                                      public void electrify(int l, int n, int e) {
                                          // “super”关键字调用父类(电视机类TV)定义的两插通电方法,以实现适配
                                          super.electrify(l, n);
                                      }
                                  }
                                  
                                  • 测试Client.test3()
                                        /**
                                         * 类适配器,类适配器模式不但使用起来更加简单,其效果与对象适配器模式毫无二致
                                         *      输出结果:
                                         *          火线通电:1,零线通电:0
                                         *          电视开机
                                         */
                                        private static void test3() {
                                            // 电视机专属三插适配器插入三相插孔
                                            TriplePin tvAdapter = new TVAdapter();
                                            // //此处调用的是三插通电标准
                                            tvAdapter.electrify(1, 0, -1);
                                        }
                                    
                                    • 类适配器模式不但使用起来更加简单,而且其效果与对象适配器模式毫无二致。
                                    • 这个类适配器是继承自电视机的子类,在类定义的时候就已经与电视机完成了接驳
                                    • 也就是说,类适配器与电视机的继承关系让它固化为一种专属适配器,这就造成了继承耦合
                                    • 倘若我们需要适配其他两插设备,就不得不再写一个“洗衣机专属适配器”
                                    • 适配器兼容性较差
                                      9.6 化解难以调和的矛盾
                                      • 适配器模式让兼容性问题在不必修改任何代码的情况下得以解决,其中适配器类是核心
                                      • 对象适配器模式的各角色定义如下
                                        • Target(目标接口):客户端要使用的目标接口标准,TriplePin。
                                        • Adapter(适配器):实现了目标接口,负责适配(转换)被适配者的接口为目标接口,AdapterTriplePinImpl。
                                        • Adaptee(被适配者):被适配者的接口标准,目前不能兼容目标接口的问题接口,可以有多种实现类,DualPin。
                                        • Client(客户端):目标接口的使用者
                                        • 类适配器模式的各角色定义如下
                                          • Target(目标接口):客户端要使用的目标接口标准,TriplePin。
                                          • Adapter(适配器):继承自被适配者类且实现了目标接口,负责适配(转换)被适配者的接口为目标接口,TVAdapter
                                          • Adaptee(被适配者):被适配者的类实现,目前不能兼容目标接口的问题类,TVDualPinImpl
                                          • Client(客户端):目标接口的使用者
                                          • 对象适配器模式与类适配器模式基本相同,二者的区别在于
                                            • 对象适配器的Adaptee(被适配者)以接口形式出现并被Adapter(适配器)引用(更灵活)
                                            • 类适配器以父类的角色出现并被Adapter(适配器)继承(更简单)、
                                            • 适配器至少都应该具备模块两侧的接口特性
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]