我正在经历Effective Java, Item-16 Favor composition over inheritance。我看了下面的Forwarding class示例。

我想知道ForwardingSet类有什么意义? InstrumentedSet可以很好地实现Set,并具有一个私有实例来调用所有方法。

如果将来我们最终拥有更多像类的InstrumentedSet,而这些代码除了基本行为外还需要做一些事情,它是否可以促进重用并防止冗余?仅仅是面向 future 的设计还是我缺少的其他东西?

// Reusable forwarding class
public class ForwardingSet<E> implements Set<E> {
  private final Set<E> s;
  public ForwardingSet(Set<E> s) { this.s = s; }
  public void clear()               { s.clear();            }
  public boolean contains(Object o) { return s.contains(o); }
...
}

// Wrapper class - uses composition in place of inheritance
public class InstrumentedSet<E> extends ForwardingSet<E> {
      private int addCount = 0;
      public InstrumentedSet(Set<E> s) { super(s); }
      @Override public boolean add(E e) {
          addCount++;
          return super.add(e);
       }
       ...
    }

最佳答案

是的,ForwardingSet是一个框架。

如果您必须内部编写与其他Set一起使用的几个Set,但是在“原始” Set的基础上提供不同的功能,则最好一次编写通用部分,而不是多次编写。

Joshua Bloch在Effective Java中将其称为“组合”,尽管实际实现看起来更像decorator pattern

实际的实现很容易在Guava中作为名为 ForwardingSet 的类获得。

如果将来我们最终拥有更多类似InstrumentedSet的类,而这些类除了基本行为之外还需要做一些事情,是否可以促进重用并防止冗余?

是。

它只是面向 future 的设计吗?

是。

还是我想念的其他东西?

不,您什么都不丢失。

08-28 00:40