Handle - Body Design pattern and it's uses

Discussion in 'C++' started by Mridula, Mar 3, 2009.

  1. Mridula

    Mridula New Member

    Joined:
    Mar 5, 2008
    Messages:
    316
    Likes Received:
    19
    Trophy Points:
    0
    Occupation:
    S/w proffessional
    Location:
    Bangalore

    Introduction



    This article talks about Handle-Body pattern and it's uses.

    Background



    Though, C++ provides private and public access specifiers to differntiate implementation and interface parts of a class, down the line any changes to the private data or member functions implementation would lead to re-compile the whole class.

    So instead, it is useful to put interface (public section of a class) and implemntation (private section of a class) details in a 2 seperate classes named as "Handle" and "Body" respectively. And provide a pointer of "Body" class to the "Handle" class. Then make "Handle" forwarding function calss to "Body".

    Then provide only the interface class to clients.

    Uses:

    Here any changes to the implmentation class can be made safely without disturbing or re-compiliing the interface class and thus reducing the compilation time.

    Also here the implementation becomes more hidden to the clients and thus achiving more encapsulation.

    Future maintainace will also be much easier (if you decide to add or remove any data in the implementation details, will not affect the client's code)

    Since the data here is kept seprately with the implemetation class, this pattern is well suited to provide reference-counting facility and thus reliveing developers with the task of memory management as well.

    Here is a sample code of Handle and Body class.

    The code


    Code:
    
    // ********* body.h - Declares Body class ***********
    
    #include <iostream.h>
    
    class Body 
    {
      public:
        //   Body features:
       	int get_value () const;
       	void set_value (int val);
    
       	//   standard construction and destruction:
       	Body ();
       	Body (const Body&);
       	Body& operator = (const Body&);
       	~Body ();
       	//void swap (Body&);
    
      private:
       	int myVal;
    }; 
    
    // ********* End of body.h file **********
    
    // ********* body.cc - Implementation details of "Body" class *********
    
    #include "body.h" 
    
    Body::Body()
    {
      cout<<"Body::default constructor = \n";
    }
    
    Body::Body (const Body& rhs)
    {
      cout<<"Body::copy constructor = \n";
      myVal = rhs.myVal;
    }
    
    Body& Body::operator = (const Body &rhs)
    {
      cout<<"Body::operator = \n";
      if(this != &rhs)
      {
        myVal = rhs.myVal;
        return (*this);
      }
    }
    
    Body::~Body()
    {
      cout<<"Body::Destructor\n";
    }
    
    int Body::get_value() const
    {
      cout<<"Body::getValue- myValue = "<<myVal<<"\n";
      return (myVal);
    }
    
    void Body::set_value(int val)
    {
      myVal = val;
      cout<<"Body::set_value-myValue = "<<myVal<<"\n";
    }
    
    // ******** End of body.cc file **********
    
    // ******** handle.h - Declares Handle class *********
    
    class Body;    //   no #include, but forward declaration
       	     
    class Handle {
      public:
        //   Handle features:
        int get_value () const;
        void set_value (int val);
    
        //   standard construction and destruction:
        Handle();
        Handle(const Handle&);
        Handle& operator = (const Handle&);
        void swap (Handle&);
        ~Handle ();
    
      private:
        Body * rep_;  // pointer to "Body" class
    };  
    
    // ********  End of handle.h file ************
    
    // ********* handle.cc - Implementation details of Handle class ***********
    
    #include "handle.h"    //   get the interface
    #include "body.h"    //   get the implementation
    
    Handle::Handle () 
    {
      cout<<"Handle::default constructor = \n";
      rep_= new Body; 
    }
       	     
    Handle::Handle (const Handle& rhs) : rep_(0) 
    {
      cout<<"Handle::copy constructor = \n";
      rep_= new Body (*rhs.rep_); 
    }
       	     
    Handle& Handle::operator = (const Handle &rhs) 
    {
      cout<<"Handle::operator = \n";
      if (this != &rhs)
      {
        *(rep_) = *(rhs.rep_);
        return (*this);
      }
    }
       	     
    void Handle::swap (Handle& rhs) 
    {
      Body * tmp = rhs.rep_;
      rhs.rep_= rep_;
      rep_= tmp; 
    }
       	     
    Handle::~Handle () 
    {
      cout<<"Handle::Destructor\n";
      delete rep_; 
       rep_= 0; 
    }
    
            
    int Handle::get_value () const 
    {
      cout<<"Handle::getValue- myValue\n";
      return rep_->get_value (); 
    }
       	     
    void Handle::set_value (int val) 
    {
      rep_->set_value (val); 
      cout<<"Handle::set_value-myValue\n";
    }      
    
    // Here is client code, that uses Handle class 
     
    int main()
    {
      Handle h;
      h.set_value(10);
      h.get_value();
    
      return(0);
    }
    
    // *********** End of handle.cc file *************
    
    
     
  2. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    Nice Article
     
  3. Mridula

    Mridula New Member

    Joined:
    Mar 5, 2008
    Messages:
    316
    Likes Received:
    19
    Trophy Points:
    0
    Occupation:
    S/w proffessional
    Location:
    Bangalore
    thanks Shabbir. I have not introduced myself before, I should have been but. Anyway, I am frm Blr , working on C, C++ with 5 yrs exp. and new to this Forum and would like to share some of my learnings here. thanks.
     
  4. indiansword

    indiansword Security Expert

    Joined:
    Oct 19, 2008
    Messages:
    491
    Likes Received:
    37
    Trophy Points:
    0
    Occupation:
    Operation Planner for 3 Australia
    Home Page:
    http://www.Secworm.net
    shouldn't mridual have a girl's avtar in author's place? :P
     
  5. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    :no:
     
  6. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    Article of the month competition nomination started here
     
  7. asadullah.ansari

    asadullah.ansari TechCake

    Joined:
    Jan 9, 2008
    Messages:
    356
    Likes Received:
    14
    Trophy Points:
    0
    Occupation:
    Developer
    Location:
    NOIDA
    Good Article...Keep it posting...
    One thing in assignment operator you should write statement return *this out of if condition.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice