Open main menu

CDOT Wiki β

Changes

Bridge

7,318 bytes added, 09:52, 11 June 2007
Consequences
The '''Bridge pattern''' allows you to decouple an abstraction from its implementation so both can vary independently. The Bridge pattern is also know as Handle/Body.<br/><br/>
 
__TOC__
== Introduction ==
The '''bridge pattern''' is a design pattern used in software developing, decouple an abstraction from its implementation so that the two can vary independently. It is also known as Handle or Body.
== UML Structure ==
== Applicability ==
The Bridge pattern is applicable when:
<ul><ul>
<li>we want to avoid a permanent binding between an abstraction and its implementation</li>
<li>both the abstractions and their implementations should be extensible by subclassing</li>
<li>we want to hide the implementation of an abstraction completely from clients</li>
<li>we want to share an implementation among multiple objects, and this fact should be hiddent from the client</li>
<li>useful in graphic and windowing systems that need to run over multiple platforms</li><li>useful any time we need to vary an interface and an implementation in different ways</li></ul></ul>
== Participants ==
The classes and/or objects participating in this pattern are:<br />
<ul>
<li>'''Abstraction'''</li>
<li>maintains a reference to an object of type Implementor</li>
</ul>
<li>'''Refined Abstraction'''</li>
<ul>
<li>extends the interface defined by Abstraction.</li>
<li>'''Implementor'''</li>
<ul>
<li>defines the interface for implementation classes. This interface does not have to correspond exactly to Abstraction's interface; in fact the two interfaces can be quite different. The Implementation interface provides only primitive operations, and Abstraction defines high-level operations based on these primitives. </li>
</ul>
<li>'''Concrete Implementor'''</li>
== Consequences Code Examples == ====PHP Java Bridge in Java Code====The following code is found on "Oregon State University Open Source Lab" which illustrate the Bridge pattern has . The following is a part of the code which allows user to vary the following consequenceclass loader. <br/>Source: http://gentoo.osuosl.org/distfiles/php-java-bridge_2.0.8.tar.bz2<br/>File: JavaBridge.java<ulbr/><lipre>'''Decoupling interface and implementation''' - inheritance tightly couples an abstraction with an implementation at compile timepackage php.java. bridge;  /** Bridge * A bridge pattern can be used which allows us to avoid vary the binding between abstraction and implementation and to select implenetation at class loader as run -time<. * The decision is based on whether we are allowed to use a dynamic * classloader or not (loader==null). * @see DynamicJavaBridgeClassLoader * @see java.lang.ClassLoader */public class JavaBridgeClassLoader {  DynamicJavaBridgeClassLoader cl = null; ClassLoader scl = null; private JavaBridge bridge;  public JavaBridgeClassLoader(JavaBridge bridge, DynamicJavaBridgeClassLoader loader) { this.bridge = bridge; this.cl = loader;  if(this.cl==null) this.scl = bridge.getClass().getClassLoader(); else cl.clear(); }  /li>** * Append the path to the current library path<li> * @param path A file or url list, separated by ';' * @param extensionDir Usually ini_get("extension_dir"); */ public void updateJarLibraryPath(String path, String extensionDir) { if(cl==null) { bridge.logMessage("You don'Improved extensibility''' - extend t have permission to call java_set_library_path() or java_require(). Please store your libraries in the lib folder within JavaBridge.war"); return; }  cl.updateJarLibraryPath(path, extensionDir); }  /** * Only for internal use * @return the classloader */ public ClassLoader getClassLoader() { if(cl!=null) return (ClassLoader)cl; return scl; }  /** * reset loader to the Abstraction and Implementor hierarchies independently<initial state */ public void reset() { if (cl!=null) cl.reset(); }  /li>** * clear all loader caches but<li>'''Hiding implementation detail from clients''' - shield clients from implentation details, like * not the sharing of implemntor objects and accompanying reference count merchanism<input vectors */ public void clearCaches() { if (cl!=null) cl.clearCaches(); }  /li>** * Load a class.<li>'''Interface and implementation can be varied independently''' - maintaining two different * @param name The class hierarchies , for interface and implementation entitles to vary one independent of example java.lang.String * @return the otherclass * @throws ClassNotFoundException */ public Class forName(String name) throws ClassNotFoundException { if(cl==null) return Class.forName(name, false, scl); return cl.loadClass(name); } }</lipre><li>'''Lossely coupled client ====Real-world Sample code''' in C#====This real- Abstraction separates world code demonstrates the client code Bridge pattern in which a BusinessObject abstraction is decoupled from the implementationin DataObject. The DataObject implementations can evolve dynamically without changing any clients. <br/li>Source: http://www.dofactory.com/Patterns/PatternBridge.aspx<lipre>'''Reduction in // Bridge pattern -- Real World example  using System;using System.Collections; namespace DoFactory.GangOfFour.Bridge.RealWorld{  // MainApp test application class MainApp { static void Main() { // Create RefinedAbstraction Customers customers = new Customers("Chicago");  // Set ConcreteImplementor customers.Data = new CustomersData();  // Exercise the number of sub classes'''bridge customers.Show(); customers.Next(); customers.Show(); customers.Next(); customers.Show(); customers.New("Henry Velasquez");  customers.ShowAll();  // Wait for user Console.Read(); } }  // "Abstraction"   class CustomersBase { private DataObject dataObject; protected string group;  public CustomersBase(string group) { this.group = group; }  // Property public DataObject Data { set{ dataObject = value; } get{ return dataObject; } }  public virtual void Next() { dataObject.NextRecord(); }  public virtual void Prior() { dataObject.PriorRecord(); }  public virtual void New(string name) { dataObject.NewRecord(name); }  public virtual void Delete(string name) { dataObject.DeleteRecord(name); }  public virtual void Show() { dataObject.ShowRecord(); }  public virtual void ShowAll() { Console.WriteLine("Customer Group: " + group); dataObject.ShowAllRecords(); } }  // "RefinedAbstraction"   class Customers : CustomersBase { // Constructor public Customers(string group) : base(group) { }  public override void ShowAll() { // Add separator lines Console.WriteLine(); Console.WriteLine ("------------------------"); base.ShowAll(); Console.WriteLine ("------------------------"); } }  // "Implementor"   abstract class DataObject { public abstract void NextRecord(); public abstract void PriorRecord(); public abstract void NewRecord(string name); public abstract void DeleteRecord(string name); public abstract void ShowRecord(); public abstract void ShowAllRecords(); }  // "ConcreteImplementor"   class CustomersData : DataObject { private ArrayList customers = new ArrayList(); private int current = 0;  public CustomersData() { // Loaded from a database customers.Add("Jim Jones"); customers.Add("Samual Jackson"); customers.Add("Allen Good"); customers.Add("Ann Stills"); customers.Add("Lisa Giolani"); }  public override void NextRecord() { if (current </li= customers.Count - 1) { current++; } }  public override void PriorRecord() { if (current >0) { current--; } }  public override void NewRecord(string name) { customers.Add(name); }  public override void DeleteRecord(string name) { customers.Remove(name); }  public override void ShowRecord() { Console.WriteLine(customers[current]); }  public override void ShowAllRecords() { foreach (string name in customers) { Console.WriteLine(" " + name); } } }} <li/pre>'''Cleaner code and Reduction  ====Sample Code in executable size'''Java====The following is an easier to follow example of the Bridge pattern:<br/li>Source: http://en.wikipedia.org/wiki/Bridge_pattern<pre>import java.util.*;/** "Implementor" */ul>interface DrawingAPI { public void drawCircle(double x, double y, double radius);} /** "ConcreteImplementor" 1/2 */class DrawingAPI1 implements DrawingAPI { public void drawCircle(double x, double y, double radius) { System.out.printf("API1.circle at %f:%f radius %f\n", x, y, radius); }} /** "ConcreteImplementor" 2/2 */class DrawingAPI2 implements DrawingAPI { public void drawCircle(double x, double y, double radius) { System.out.printf("API2.circle at %f:%f radius %f\n", x, y, radius); }} /** "Abstraction" */interface Shape { public void draw(); // low-level public void resizeByPercentage(double pct); // high-level}
== Implementation ==/** "Refined Abstraction" */class CircleShape implements Shape {When applying the Bridge pattern private double x, consider the following implementation issues:y, radius;<ul> private DrawingAPI drawingAPI;<li>Only one Implementor</li> public CircleShape(double x, double y, double radius, DrawingAPI drawingAPI) {<li>Creating the right Implementor object</li> this.x = x; this.y = y; this.radius = radius; <li>Sharing implementors</li> this.drawingAPI = drawingAPI;<li>Using multiple inheritance</li></ul> }
// low-level i.e. Implementation specific public void draw() { drawingAPI.drawCircle(x, y, radius); } // high-level i.e. Abstraction specific public void resizeByPercentage(double pct) { radius *== Code Examples ==pct; }}
/** "Client" */
class BridgePattern {
public static void main(String[] args) {
Shape[] shapes = new Shape[2];
shapes[0] = new CircleShape(1, 2, 3, new DrawingAPI1());
shapes[1] = new CircleShape(5, 7, 11, new DrawingAPI2());
for (Shape shape : shapes) {
shape.resizeByPercentage(2.5);
shape.draw();
}
}
}
</pre>
== References ==
<ul>
<li>[http://en.wikipedia.org/wiki/Bridge_pattern Wikipedia.com - Bridge pattern]</li>
<li>[http://www.developer.com/design/article.php/1502691 A Survey of Common Design Patterns]</li>
<li>[http://www.dofactory.com/Patterns/PatternBridge.aspx DoFactory.com - Bridge Design Pattern]</li>
<li>[http://home.earthlink.net/~huston2/dp/all_uml.html Design Class Diagrams - Bridge]</li>
<li>[http://gentoo.osuosl.org/distfiles/php-java-bridge_2.0.8.tar.bz2 Oregon State University Open Source Lab - JavaBridge.java]</li>
<li>Gamma, E., Helm, R., Johnson, R., Vlissides, J. (1995). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley. ISBN 0-201-63361-2 </li>
</ul>
1
edit