Pattern Name:

Bridge Pattern

Short Description:

Separate implementation and object interfaces

Usage:

Sometimes used, useful to decouple an abstraction from its implementation and to be able to modify them independently.

Note that the Bridge pattern has nearly the same structure as the Adapter Pattern. But it is used when designing new systems instead of the Adapter pattern which is used in already existing systems.

Complexity:

1 / 5

UML Class Diagram:

image_thumb[1]

Explanation:

  • The abstract Repository class defines the interface that all inheriting refined Repository classes will use for object management purposes.
  • Note that the operations within the Repository classes define high-level operations.
    public abstract class Repository
{
public abstract void AddObject(DataObject dataObject);
public abstract void CopyObject(DataObject dataObject);
public abstract void RemoveObject(DataObject dataObject);

public void SaveChanges()
{
Console.WriteLine("Changes were saved");
}
}

  • The refined Repositories extend the basic functionalities and implement the execution code that uses the implementation classes. They should contain specializations which only apply to specific Repositories.
    public class ClientRepository : Repository
{
public override void AddObject(DataObject dataObject)
{
// Do repository specific work
dataObject.Register();
}

public override void CopyObject(DataObject dataObject)
{
// Do repository specific work
dataObject.Copy();
}

public override void RemoveObject(DataObject dataObject)
{
// Do repository specific work
dataObject.Delete();
}
}

public class ProductRepository : Repository
{
public override void AddObject(DataObject dataObject)
{
// Do repository specific work
dataObject.Register();
}

public override void CopyObject(DataObject dataObject)
{
// Do repository specific work
dataObject.Copy();
}

public override void RemoveObject(DataObject dataObject)
{
// Do repository specific work
dataObject.Delete();
}
}
  • The abstract DataObject class defines the interfaces of the implementation classes. Note that the abstract Repository and the abstract DataObject classes can have completely different interfaces.
  • The concrete DataObject implementations contain the code that executes all the low-level operations.
  • Note that the methods within the Repository class could also call multiple methods in the implementation classes (1 to * relationship).
    public abstract class DataObject
{
public abstract void Register();
public abstract DataObject Copy();
public abstract void Delete();
}

public class ClientDataObject : DataObject
{
public override void Register()
{
Console.WriteLine("ClientDataObject was registered");
}

public override DataObject Copy()
{
Console.WriteLine("ClientDataObject was copied");
return new ClientDataObject();
}

public override void Delete()
{
Console.WriteLine("ClientDataObject was deleted");
}
}

public class ProductDataObject : DataObject
{
public override void Register()
{
Console.WriteLine("ProductDataObject was registered");
}

public override DataObject Copy()
{
Console.WriteLine("ProductDataObject was copied");
return new ProductDataObject();
}

public override void Delete()
{
Console.WriteLine("ProductDataObject was deleted");
}
}
  • In the last step we add some code to test the software design and the Bridge implementation.
    public static void Bridge()
{
var clientRepository = new ClientRepository();
var productRepository = new ProductRepository();

var clientDataObject = new ClientDataObject();
clientRepository.AddObject(clientDataObject);
clientRepository.SaveChanges();

clientRepository.CopyObject(clientDataObject);

clientRepository.RemoveObject(clientDataObject);
clientRepository.SaveChanges();

var productDataObject = new ProductDataObject();
productRepository.AddObject(productDataObject);
clientRepository.SaveChanges();

productRepository.CopyObject(productDataObject);

productRepository.RemoveObject(productDataObject);
productRepository.SaveChanges();

Console.ReadKey();
}
  • When running the example you can see that everything is working as expected and that the correct classes are instantiated during runtime.

image_thumb[4]

Last edited Jul 18, 2011 at 2:31 PM by JasonOliveira, version 1

Comments

tzdvor Jul 30, 2014 at 1:38 PM 
In the method Bridge() below the line "productRepository.AddObject(productDataObject);" the next statement should IMHO be "productRepository.SaveChanges();"

codeowl Aug 25, 2012 at 5:11 AM 
Have loved reading all your articles here, can't wait for you to finish the rest mate ;-)