Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4940453

RFE: Add compiler support for the Decorator design pattern

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 1.4.2
    • specification
    • x86
    • windows_2000



      Name: rmT116609 Date: 10/20/2003


      A DESCRIPTION OF THE REQUEST :
      The Decorator design pattern is a very usefull and very powerfull pattern. Java uses it itself in the I/O classes. The usual method of implementing it is to create an interface that defines the methods to be called, in addition to concrete implementations of that interface you also define a baseclass for all wrappers. That baseclass defines an implementation for each of the interface methods that simply calls the same method on another implementation of the interface that is passed into the base class' constructor. The decorators then subclass this baseclass overriding any methods they want changed and likely calling the baseclass' version of the method to call the method on the wraped object.

      The construction of this base class for decorators is a tedious and mechanical process. It has been discussed on the Usenet news groups that it would be nice if Java provided compiler level support for this and generated the tedious forwarding code for you. In other words it would be nice to have the decorator pattern supported directly in the compiler.

      I have thought more about it and think I have a workable proposal. The plan is to eliminate the need for the base class. The idea is that you could declare that a class is a wrapper for a certain interface.

      Ideally it would be nice to have a new keyword for this so that you could say something like:

      class MyWrapper wraps MyInterface {

      But realizing that adding keywords is costly I would suggest a way that does not introduce new keywords just inserts an existing one:

      class MyWrapper extends interface MyInterface {

      There could be other possibilities as well.

      So then what does this mean? It means that
      - MyWrapper will implement MyInterface
      - MyClMyWrapper ass will have a special hidden field that is a reference to an implementation of MyInterface. This is much like the hidden reference to the enclosing instance for superclasses.
      - MyWrapper can provide implementations for methods in MyInterface
      - If there are any methods of MyInterface that are not implemented in MyWrapper the compiler will automatically create methods that forward each call to the instance in the hidden field.
      - MyWrapper can also have other methods and constructors unrelated to MyInterface.

      Note that MyWrapper can also implement other interfaces, but can only extend or wrap one interface. Otherwise you basically have a similar situation to multiple inheritance and the diamond of death scenario all over again.

      I described that MyWrapper would have a hidden field that points to the wrapped object but left out two important details.

      First, how does the field get set? Instead of requiring such a pointer to be explicitly passed into a constructor, I propose that it is done just like inner classes can be associated with an enclosing instance, by using a qualified new such as in:

      Class Foo implements MyInterface { ... }

      Foo f;
      MyInterface wrappedF = f.new MyWrapper();

      Secondly, how does code within MyWrapper access the hidden field to get a reference to be able to call a method on it? I do not want the writer of the class to designate a name. It should be a standard mechanism. I think the best choice once again would be to borrow on the precedent of inner classes and use MyInterface.this. So for example if you want to add functionality to a method but still call the method:

      public void method()
      {
          doSomething();
          // Call the method on the wrapped object
          MyInterface.this.method();
      }


      JUSTIFICATION :
      The basic thing it save is tedious typing or cut and paste for the developer, when the compiler could generate the code for you automatically. But I think it also provides a usefull abstraction.
      (Incident Review ID: 216373)
      ======================================================================

            gbrachasunw Gilad Bracha (Inactive)
            rmandalasunw Ranjith Mandala (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: