美文网首页
结构型模式--代理模式&&适配器模式&&装饰器模式

结构型模式--代理模式&&适配器模式&&装饰器模式

作者: kirito_song | 来源:发表于2020-03-13 15:30 被阅读0次

    算是读书笔记吧

    极客时间--设计模式之美


    代理模式和装饰器模式的在实现上相同,所以放在一起看。

    以代理模式为例

    // 代理模式的代码结构(下面的接口也可以替换成抽象类)
    public interface IA {
      void f();
    }
    public class A impelements IA {
      public void f() { //... }
    }
    public class AProxy impements IA {
      private IA a;
      public AProxy(IA a) {
        this.a = a;
      }
      
      public void f() {
        // 新添加的代理逻辑
        a.f();
        // 新添加的代理逻辑
      }
    }
    
    private void demo() {
      IA a = AProxy(A.new())
      a.f()
    }
    

    二者的相似性

    • 目的上

    主要解决继承关系过于复杂的问题,借助面向接口的编程思想,通过组合来替代继承。

    • 实现上

    在不改变原始类(或叫被代理类)代码的情况下,由新的类和原始类需要实现相同的接口。


    二者的区别性

    二者的区别体现在想要对原始类附加的功能

    代理模式

    将功能直接转交给代理类进行实现。

    偏重业务无关,高度抽象,和稳定性较高的场景。
    由原始类指定代理类,对业务方隐藏代理类的存在。

    比如对数据访问功能添加日志,缓存。

    装饰器模式

    给原始类添加增强功能。

    偏重业务相关,定制化诉求高,改动较频繁的场景。
    由业务方指定装饰类,依赖业务方的具体实现。

    比如业务级别上对日志增加字段、数据的加工整理。

    代理模式主要目的是控制访问,而非加强功能。这是它跟装饰器模式最大的不同


    适配器模式

    适配器模式与代理和装饰器模式一样,也是基于面向接口编程的特性,通过接口对不同的类进行统一约束。

    这里的统一,体现在:

    • 不同类的调用方式统一,更好的利用多态特性
    
    // 使用适配器模式进行改造
    public interface ISensitiveWordsFilter { // 统一接口定义
      String filter(String text);
    }
    
    // 扩展性更好,更加符合开闭原则,如果添加一个新的敏感词过滤系统,
    // 这个类完全不需要改动;而且基于接口而非实现编程,代码的可测试性更好。
    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) {  //这里每个filter的filter方法内部,包裹着真实实现
          maskedText = filter.filter(maskedText);
        }
        return maskedText;
      }
    }
    

    当然,也有为了版本兼容而使用的适配器模式。将适配器实现的细节,转接给另一个类进行实现

    /**
     * Returns an enumeration over the specified collection.  This provides
     * interoperability with legacy APIs that require an enumeration
     * as input.
     *
     * @param  <T> the class of the objects in the collection
     * @param c the collection for which an enumeration is to be returned.
     * @return an enumeration over the specified collection.
     * @see Enumeration
     */
    public static <T> Enumeration<T> enumeration(final Collection<T> c) {
      return new Enumeration<T>() {
        private final Iterator<T> i = c.iterator();
    
        public boolean hasMoreElements() {
          return i.hasNext();
        }
    
        public T nextElement() {
          return i.next();
        }
      };
    }
    

    适配器模式是用来做适配,它将不兼容的接口转换为可兼容的接口,让原本由于接口不兼容而不能一起工作的类可以一起工作。适配器模式有两种实现方式:类适配器和对象适配器。其中,类适配器使用继承关系来实现,对象适配器使用组合关系来实现。
    一般来说,适配器模式可以看作一种“补偿模式”,用来补救设计上的缺陷。应用这种模式算是“无奈之举”,如果在设计初期,我们就能协调规避接口不兼容的问题,那这种模式就没有应用的机会了。

    相关文章

      网友评论

          本文标题:结构型模式--代理模式&&适配器模式&&装饰器模式

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