Wrapper (Decorator)

Wrapper (or Decorator) is one of the most important design patterns.

Wrappers are commonly used in:

The basic idea of a wrapper is to call-forward to an underlying object, while simultaneously allowing for new code to be executed just before and/or just after the call. Wrappers can be chained together, one after another. In this way, you can mix-and-match behaviors in various ways.

Note that this changes the behavior of an object, without needing to alter the implementation of a class, and also without needing to extend a class.

Here's an example implementation of a wrapper design pattern (other variations are also possible):

import java.util.function.Function;

/** 
 Wrapper (Decorator) design pattern.
 The core idea here is transforming text: text in, text out. 
*/
public final class WrapperDemoFunctional {

  /** Demo harness. */
  public static void main(String... args){
    //we take a simple trim to be the core operation here:
    Function<String, String> coreOperation = p -> p.trim();
    String output = coreOperation.apply(" blah ");
    show(output); // 'blah'

    //now we can add behaviour to the core operation, by wrapping it 
    //in other objects that implement the same (functional) interface
    Function<String, String> wrappedOperation = new Capitalizer(coreOperation);
    //notice it does TWO things: trims (core) and capitalizes (wrapper)
    show(wrappedOperation.apply(" blah ")); // 'BLAH'

    int MAX_CHARS = 3;
    wrappedOperation = new Chopper(coreOperation, MAX_CHARS);
    show(wrappedOperation.apply(" blah ")); // 'bla'
    
    //you can chain objects together with wild abandon, to implement 
    //many glorious variations on behaviour
    wrappedOperation = new Chopper(new Capitalizer(coreOperation), MAX_CHARS);
    show(wrappedOperation.apply(" blah ")); // 'BLA'
  }

  /** Show the result of the text transformations. */
  private static void show(String text){
    String QT = "'";
    System.out.println(QT + text + QT);
  }
  
  /**
   This class both implements the interface AND is constructed 
   with an implementation of the same (functional) interface.
  */
  private static class BaseWrapper implements Function<String, String> {
    BaseWrapper(Function<String, String> transformer){
      this.transformer = transformer;
    }
    /** Template method, calls 'before' and 'after' methods. */
    @Override public String apply(String aText) {
      String text = before(aText);
      text = transformer.apply(text); //call-forward
      return after(text);
    }
    /** This overridable default implementation does nothing.*/
    String before(String text){
      return text;
    }
    /** This overridable default implementation does nothing.*/
    String after(String text){
      return text;
    }
    private Function<String, String> transformer;
  }
  
  /** Capitalize before applying the core operation. */
  private static final class Capitalizer extends BaseWrapper {
    Capitalizer(Function<String, String> transformer){
      super(transformer);
    }
    @Override String before(String text) {
      String result = text;
       if (text != null){
         result = result.toUpperCase();
       }
       return result;
    }
  }

  /** Limit to N characters after applying the core operation. */
  private static final class Chopper extends BaseWrapper {
    Chopper(Function<String, String> transformer, int limit){
      super(transformer);
      this.limit = limit;
    }
    @Override String after(String text) {
      String result = text;
       if (text != null){
         result = result.substring(0, limit);
       }
       return result;
    }
    private int limit;
  }
} 
The output of this class is:
'blah'
'BLAH'
'bla'
'BLA'

See Also :
Template method