Appendix


introduction framework patterns components conclusions references appendix experience

Appendix


slide: Appendix

The Handle/Body Idiom


introduction framework patterns components conclusions references appendix experience
The handle/body class idiom  [Coplien,Eliens95,GOF,Stroustrup,Pree] separates the class defining a component's abstract interface (the handle class) from its hidden implementation (the body class). All intelligence is located in the body, and (most) requests to the handle object are delegated to its implementation. In order to illustrate the several idioms, we use the following class as a running example:
    class A { 
      public:
        virtual void f1()  { cout << "A::f1() "; f2(); }
        virtual void f2()  { cout << "A::f2()" << endl; }
    };
  
The implementation of A is straightforward and does not make use of the handle/body idiom. A call to the {\tt f1()} member function of A will print a message and make a subsequent call to {\tt f2()}. Without any modification in the behavior of A's instances, it is possible to re-implement A using the handle/body idiom. The member functions of class A are implemented by its body, and A is reduced to a simple interface class:
    class A {  // Handle class delegating to its body
      public:
        A();  // defined later
        virtual ~A() { delete body; }
        virtual void f1() { body->f1(); }
        virtual void f2() { body->f2(); }
      private: A* body;
      protected: A(int dummy);  // used by body
    };
  
Note that the implementation of A's body can be completely hidden from the application programmer. In fact, by declaring A to be the superclass of its body class, even the existence of a body class can be hidden. If A is a class provided by a shared library, new implementations of its body class can be plugged in, without the need to recompile dependent applications:
    class BodyOfA: public A { 
      public:
        BodyOfA();
        void f1()  { cout << "A::f1() "; f2(); }
        void f2()  { cout << "A::f2()" << endl; }
    };
  
In this example, the application of the idiom has only two minor drawbacks. First, in the implementation below, the main constructor of A makes an explicit call to the constructor of its body class. As a result, A's constructor needs to be changed whenever an alternative implementation of the body is required. The {\em Abstract Factory\/} pattern described in  [GOF]. may be used to solve this problem in a generic and elegant way. Another (esthetic) problem is the need for the dummy constructor to prevent a recursive chain of constructor calls:
    BodyOfA::BodyOfA(): A(911) { }  // Call dummy constructor of A
    A::A(int dummy) { body = 0; }   // to build an abstract instance of A
    A::A() { body = new BodyOfA; }  // to build a concrete instance of A