Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forwarding Class Example

Reading Effective Java, I saw the following example from Item 16: Favor composition over inheritance.

In the below InstrumentedSet, the book shows we can keep track of how many times an element was inserted (via the InstrumentedSet.addCount variable).

To do this, we can simply append to this class object's addCount, and then call ForwardingSet.add(), which calls the actual Set class's actual implementation of add().

// 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);
       }
       ...
    }

Am I correct in understanding that, to use this pattern/approach, it's necessary for the Forwarding* class to call all of its parent class's methods (in this case Set)?

like image 342
Kevin Meredith Avatar asked Nov 22 '13 18:11

Kevin Meredith


1 Answers

Yes, you are correct, ForwardingSet delegates/forwards all of it's calls to a backing set.

You might want to have a look at a working example in a popular library Guava: ForwardingMap.

like image 198
Andrey Chaschev Avatar answered Oct 06 '22 00:10

Andrey Chaschev