• 设计模式之美学习-结构型-适配器模式(二十二)


    说明

    这个模式就是用来做适配的,它将不兼容的接口转换为可兼容的接口,让原本由于接口不兼容而不能一起工作的类可以一起工作

    源码中应用

    1.《SpringMVC源码阅读-一个请求主要处理流程DispatcherServlet(四)》

    2.中 Handle是object可以以任何一种方式存在 通过HandleAdapter接口进行适配 不同的Handle不同的处理方式 

    再或者dubbo服务发布 https://www.cnblogs.com/LQBlog/p/12470179.html 将service接口统一转成内部的invoker接口

    3.dubbo com.alibaba.dubbo.common.logger.LoggerFactory 通过各个日志系统的adapter的来适合

    基于继承

    // 类适配器: 基于继承
    public interface ITarget {
      void f1();
      void f2();
      void fc();
    }
    
    public class Adaptee {
      public void fa() { //... }
      public void fb() { //... }
      public void fc() { //... }
    }
    
    public class Adaptor extends Adaptee implements ITarget {
      public void f1() {
        super.fa();
      }
      
      public void f2() {
        //...重新实现f2()...
      }
      
      // 这里fc()不需要实现,直接继承自Adaptee,这是跟对象适配器最大的不同点
    }

    基于组合

    // 对象适配器:基于组合
    public interface ITarget {
      void f1();
      void f2();
      void fc();
    }
    
    public class Adaptee {
      public void fa() { //... }
      public void fb() { //... }
      public void fc() { //... }
    }
    
    public class Adaptor implements ITarget {
      private Adaptee adaptee;
      
      public Adaptor(Adaptee adaptee) {
        this.adaptee = adaptee;
      }
      
      public void f1() {
        adaptee.fa(); //委托给Adaptee
      }
      
      public void f2() {
        //...重新实现f2()...
      }
      
      public void fc() {
        adaptee.fc();
      }
    }

    适配器模式的应用场景

    1.将外部接口转化为内部接口 使之能够兼容内部接口

    2.补偿内部接口设计缺陷问题.抽象一个更抽象的接口 通过适配器将之前接口适配新的接口

    例子

    封装有缺陷的接口设计

    引入了外部的sdk接口。通过抽象出一个更好的接口设计

    public class CD { //这个类来自外部sdk,我们无权修改它的代码
      //...
      public static void staticFunction1() { //... }
      
      public void uglyNamingFunction2() { //... }
    
      public void tooManyParamsFunction3(int paramA, int paramB, ...) { //... }
      
       public void lowPerformanceFunction4() { //... }
    }
    
    // 使用适配器模式进行重构
    public class ITarget {
      void function1();
      void function2();
      void fucntion3(ParamsWrapperDefinition paramsWrapper);
      void function4();
      //...
    }
    // 注意:适配器类的命名不一定非得末尾带Adaptor
    public class CDAdaptor extends CD implements ITarget {
      //...
      public void function1() {
         super.staticFunction1();
      }
      
      public void function2() {
        super.uglyNamingFucntion2();
      }
      
      public void function3(ParamsWrapperDefinition paramsWrapper) {
         super.tooManyParamsFunction3(paramsWrapper.getParamA(), ...);
      }
      
      public void function4() {
        //...reimplement it...
      }
    }

    统一多个类的接口设计

    我们有一个关键字过滤的功能,依赖外部系统多个类,不同的类有自己的实现,我们通过适配器进行抽象出内部接口

    public class ASensitiveWordsFilter { // A敏感词过滤系统提供的接口
      //text是原始文本,函数输出用***替换敏感词之后的文本
      public String filterSexyWords(String text) {
        // ...
      }
      
      public String filterPoliticalWords(String text) {
        // ...
      } 
    }
    
    public class BSensitiveWordsFilter  { // B敏感词过滤系统提供的接口
      public String filter(String text) {
        //...
      }
    }
    
    public class CSensitiveWordsFilter { // C敏感词过滤系统提供的接口
      public String filter(String text, String mask) {
        //...
      }
    }
    
    // 未使用适配器模式之前的代码:代码的可测试性、扩展性不好
    public class RiskManagement {
      private ASensitiveWordsFilter aFilter = new ASensitiveWordsFilter();
      private BSensitiveWordsFilter bFilter = new BSensitiveWordsFilter();
      private CSensitiveWordsFilter cFilter = new CSensitiveWordsFilter();
      
      public String filterSensitiveWords(String text) {
        String maskedText = aFilter.filterSexyWords(text);
        maskedText = aFilter.filterPoliticalWords(maskedText);
        maskedText = bFilter.filter(maskedText);
        maskedText = cFilter.filter(maskedText, "***");
        return maskedText;
      }
    }
    
    // 使用适配器模式进行改造
    public interface ISensitiveWordsFilter { // 统一接口定义
      String filter(String text);
    }
    
    public class ASensitiveWordsFilterAdaptor implements ISensitiveWordsFilter {
      private ASensitiveWordsFilter aFilter;
      public String filter(String text) {
        String maskedText = aFilter.filterSexyWords(text);
        maskedText = aFilter.filterPoliticalWords(maskedText);
        return maskedText;
      }
    }
    //...省略BSensitiveWordsFilterAdaptor、CSensitiveWordsFilterAdaptor...
    
    // 扩展性更好,更加符合开闭原则,如果添加一个新的敏感词过滤系统,
    // 这个类完全不需要改动;而且基于接口而非实现编程,代码的可测试性更好。
    public class RiskManagement { 
      private List<ISensitiveWordsFilter> filters = new ArrayList<>();
     
      public void addSensitiveWordsFilter(ISensitiveWordsFilter filter) {
        filters.add(filter);
      }
      
      public String filterSensitiveWords(String text) {
        String maskedText = text;
        for (ISensitiveWordsFilter filter : filters) {
          maskedText = filter.filter(maskedText);
        }
        return maskedText;
      }
    }
  • 相关阅读:
    md笔记——HTTP知识
    百万表格难题
    微信接口改良
    md笔记——正则学习
    md笔记——编程术语
    md笔记——微信JS接口
    md笔记——使用 @font-face 引入你喜欢的字体
    博客一年记
    “挨踢”的伙食怎样?
    比尔·盖茨早年
  • 原文地址:https://www.cnblogs.com/LQBlog/p/12572334.html
Copyright © 2020-2023  润新知