SDSU CS 635 Advanced Object-Oriented Design & Programming
Spring Semester, 2001
Bridge
Previous    Lecture Notes Index    Next    
© 2001, All Rights Reserved, SDSU & Roger Whitney
San Diego State University -- This page last updated 24-Apr-01

Contents of Doc 19, Bridge



References
Design Patterns: Elements of Resuable Object-Oriented Software, Gamma, Helm, Johnson, Vlissides, Addison Wesley, 1995 pp. 151-162

Advanced C++: Programming Styles and Idioms, James Coplien, 1992, pp. 58-72


Doc 19, Bridge Slide # 2

Bridge


Decouple the abstraction from its implementation

This allows the implementation to vary from its abstraction

The abstraction defines and implements the interface

All operations in the abstraction call method(s) its implementation object



Doc 19, Bridge Slide # 3
What is Wrong with Using an Interface?


Make Abstraction a pure abstract class or Java interface

In client code:

Abstraction widget = new ConcreteImplA();
widget.operation();

This will separate the abstraction from the implementation

We can vary the implementation!



Doc 19, Bridge Slide # 4

Applicability


Use the Bridge pattern when







Doc 19, Bridge Slide # 5

Binding between abstraction & implementation


In the Bridge pattern:





Doc 19, Bridge Slide # 6

Hide implementation from clients


Using just an interface the client can cheat!

   Abstraction widget = new ConcreteImplA();
   widget.operation();
   ((ConcreteImplA) widget).concreteOperation();

In the Bridge pattern the client code can not access the implementation

Java uses Bridge to prevent programmer from accessing platform specific implementations of interface widgets, etc.

Peer = implementation

   public synchronized void setCursor(Cursor cursor) {
      this.cursor = cursor;
      ComponentPeer peer = this.peer;
      if (peer != null) {
         peer.setCursor(cursor);
      }
   }


Doc 19, Bridge Slide # 7

Abstractions & Imps independently subclassable


Start with Widow interface and two implementations:


Now what do we do if we need some more types of windows: say IconWindow and DialogWindow?



Doc 19, Bridge Slide # 8
Or using multiple inheritance



Doc 19, Bridge Slide # 9
The Bridge pattern provides a cleaner solution



IconWindow and DialogWindow will add functionality to or modify existing functionality of Window

Methods in IconWindow and DialogWindow need to use the implementation methods to provide the new/modified functionality

This means that the WindowImp interface must provide the base functionality for window implementation

This does not mean that WindowImp interface must explicitly provide an iconifyWindow method


Doc 19, Bridge Slide # 10

Share an implementation among multiple objects


Example use is creating smart pointers in C++


String contains a StringRep object

StringRep holds the text and reference count

String passes actual string operations to StringRep object

String handles pointer operations and deleting StringRep object when reference count reaches zero

String a( “cat”);
String b( “dog”);
String c( “mouse”);

a = b;

a = c;



Doc 19, Bridge Slide # 11
C++ Implementation from Coplien
class StringRep   {
   friend String;
      
   private:
      char *text;
      int refCount;
         
      StringRep()   { *(text = new char[1] = '\0'; }
         
      StringRep( const StringRep& s )   {
         ::strcpy( text = new char[::strlen(s.text) + 1, s.text);
      }
         
      StringRep( const char *s)   {
         ::strcpy( text = new char[::strlen(s) + 1, s);
      }
         
      StringRep( char** const *r)   {
         text = *r;
         *r = 0;
         refCount = 1;;
      }
         
      ~StringRep()   { delete[] text; }
         
      int length() const   { return ::strlen( text ); }
         
      void print() const   { ::printf("%s\n", text ); }
   }

Doc 19, Bridge Slide # 12
class String   {
   friend StringRep
   
   public:
      String operator+(const String& add) const {
         return *imp + add;
      }
   
      StringRep* operator->() const   { return imp; }
   
      String()   { (imp = new StringRep()) -> refCount = 1;   }
   
      String(const char* charStr)   {
         (imp = new StringRep(charStr)) -> refCount = 1;
      }
   
      String operater=( const String& q)   {
         (imp->refCount)--;
         if (imp->refCount <= 0 &&
             imp != q.imp )
            delete imp;
   
         imp = q.imp;
         (imp->refCount)++;
         return *this;
      }
   
      ~String()   {
         (imp->refCount)--;
         if (imp->refCount <= 0 ) delete imp;
      }
   
   private:
      String(char** r)  {imp = new StringRep(r);}
      StringRep *imp;
};

Doc 19, Bridge Slide # 13
Using Counter Pointer Classes

int main() {
   String a( “abcd”);
   String b( “efgh”);
   printf( “a is “);
   a->print();
   printf( “b is “);
   b->print();
   printf( “length of b is %d\n“, b-<length() );
   
   printf( “ a + b “);
   (a+b)->print();
}


Doc 19, Bridge Slide # 14
Bridge and Other Patterns

Adapter


State?

Strategy?


Copyright ©, All rights reserved.
2001 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.

Previous    visitors since 24-Apr-01    Next