CS 635 Advanced Object-Oriented Design & Programming Spring Semester, 2001 Bridge |
||
---|---|---|
© 2001, All Rights Reserved, SDSU & Roger Whitney San Diego State University -- This page last updated 24-Apr-01 |
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
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!
Applicability
Use the Bridge pattern when
Binding between abstraction & implementation
In the Bridge pattern:
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); } }
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?
Or using multiple inheritance
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
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;
|
|
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 ); } }
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; };
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(); }
Bridge and Other Patterns
Adapter