C# Design Patterns: #7 – Bridge

BridgeThe Bridge pattern is ideal for building cross-platform applications.  By completely separating the class interface from the implementation, programs can interchange the actual implementation of a particular subsystem without requiring any changes in other parts of the code.

Bridge combines two concepts – class abstraction and centralized initialization.  Class abstraction separates the definition of methods from their code (similar to the concept of C header files), and enables developers to switch out implementation libraries for different platforms.  Centralized initialization, on the other hand, instantiates the bridge in a central area, such as a Singleton, and makes it easy to switch out the implementation when necessary.

Below is an example of the Bridge pattern for a database library:

public class Program {
  public static void Main(){
    G.Instance.DB.ExecCommand("TEST_Insert");
  }
}
 
public class DBClient {
  public Dictionary<string,string> SQL = new Dictionary<string,string>();
  public virtual void ExecCommand(string sqlid){ throw new Exception("Not implemented."); }
  //object ExecScalar(string sqlid){ }
  //Dictionary<string,object> ExecRow(string sqlid){ }
  //List<Dictionary<string,object>> ExecTable(string sqlid){ }
}
 
public class DBSqlClient : DBClient {
  private string constring = "";
  public DBSqlClient(string _constring){
    constring = _constring;
    SQL["TEST_Insert"] = "insert into TEST values('TEST')";
  }
  public override void ExecCommand(string sqlid){
    using(SqlConnection con = new SqlConnection(constring)){
      con.Open();
      using(SqlCommand cmd = new SqlCommand(SQL[sqlid],con)){
        cmd.ExecuteNonQuery();
      }
    }
  }
}
 
public class G {
  //Singleton Declaration
  private static readonly G instance = new G();
  public static G Instance { get { return instance; } } //Global entry point
  static G() { }
  //Member variables
  public DBClient DB;
  //Constructor
  public G() { DB = new DBSqlClient("server=XXXXX;database=XXXXX;trusted_connection=yes;"); }
}

Using this set of classes, the database implementation is abstracted from the rest of the system.  The DBClient class defines the abstract interface, while DBSqlClient implements that interface for a SQL Server database.  The actual program itself is ignorant of the underlying database implementation.  The choice of database is controlled by the Singleton in a central area.

Although this is not a complete implementation, it shows the fundamental components of the Bridge pattern.  Further enhancements to this code would add parameters to the SQL statements, provide implementations of ExecScalar, ExecRow, and ExecTable, and add error-handling.

In addition to cross-platform compatibility, a database driver such as DBClient could be used to enable databases to be easily switched per installation.  Implementing a new database would simply require rewriting the DBClient driver and the program’s SQL statement array.  With all database-related code stored in a centralized location, the database is completely abstracted from the system without resorting to the structural complexity and inflexibility of object-relational mappers.

In a derivative implementation, instead of hard-coding the Bridge in the Singleton, the Bridge implementation could be dynamically loaded from a DLL, or loaded based on a value in an XML configuration file.  By using Reflection, the program would not require recompilation or re-linking in order to load an alternative library.

Structurally, the Bridge is similar to the previously covered Adapter pattern.  The noticeable difference, however, is that the Bridge is defined in a Singleton and is completely separate from the rest of the code.  This enables the Bridge to be switched out with an alternate implementation when necessary.  The Adapter, on the other hand, is instantiated on each use, and is built for a single Adaptee.

Whenever interfacing with a third-party system, it’s prudent to evaluation the possibility of using the Bridge pattern.  When it comes time to perform an upgrade in five or ten years, or to transition to a different platform, the time savings provided by the Bridge will be enormous.

Written by Andrew Palczewski

About the Author
Andrew Palczewski is CEO of apHarmony, a Chicago software development company. He holds a Master's degree in Computer Engineering from the University of Illinois at Urbana-Champaign and has over ten years' experience in managing development of software projects.
Google+

RSS Twitter LinkedIn Facebook Email

Leave a Reply

Your email address will not be published. Required fields are marked *