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

算是读书笔记吧

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


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

以代理模式为例

// 代理模式的代码结构(下面的接口也可以替换成抽象类)
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();
    }
  };
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章