Differences between Bridge, Adapter and other patterns
- Adapter makes things work after they’re designed; Bridge makes them work before they are.
- Bridge is designed up-front to let the abstraction and the implementation vary independently. Adapter is retrofitted to make unrelated classes work together.
- State, Strategy, Bridge (and to some degree Adapter) have similar solution structures. They all share elements of the “handle/body” idiom. They differ in intent - that is, they solve different problems.
- The structure of State and Bridge are identical (except that Bridge admits hierarchies of envelope classes, whereas State allows only one). The two patterns use the same structure to solve different problems: State allows an object’s behavior to change along with its state, while Bridge’s intent is to decouple an abstraction from its implementation so that the two can vary independently.
- If interface classes delegate the creation of their implementation classes (instead of creating/coupling themselves directly), then the design usually uses the Abstract Factory pattern to create the implementation objects.
Example of Bridge as follows:
//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Bridge is part of Structural Patterns
//Structural Patterns deal with decoupling the interface and implementation of classes and objects
//Bridge separates an object's interface from its implementation
#include<iostream>
#include<string>
#include<list>
using namespace std;
//The 'Implementor' abstract class
class DataObject
{
public:
virtual void NextRecord()=0;
virtual void PriorRecord()=0;
virtual void AddRecord(string name)=0;
virtual void DeleteRecord(string name)=0;
virtual void ShowRecord()=0;
virtual void ShowAllRecords()=0;
};
//The 'ConcreteImplementor' class
class CustomersData : public DataObject
{
public:
CustomersData()
{
current_ = 0;
}
void NextRecord()
{
if(current_ < (int)(customers_.size() - 1))
current_++;
}
void PriorRecord()
{
if(current_ > 0)
current_--;
}
void AddRecord(string name)
{
customers_.push_back(name);
}
void DeleteRecord(string name)
{
list<string>::iterator it = customers_.begin();
while(it != customers_.end())
{
if(*it == name)
{
customers_.erase(it);
break;
}
++it;
}
}
void ShowRecord()
{
list<string>::iterator it = customers_.begin();
for(int i = 0; i < current_; i++, ++it);
cout<<*it<<endl;
}
void ShowAllRecords()
{
list<string>::iterator it = customers_.begin();
while(it != customers_.end())
{
cout<<*it<<endl;
++it;
}
}
private:
int current_;
list<string> customers_;
};
//The 'Abstraction' class
class CustomersBase
{
public:
CustomersBase(string group):group_(group){};
void SetDataObject(DataObject* value)
{
dataObject_ = value;
}
DataObject* GetDataObject(void)
{
return dataObject_;
}
virtual void Next()
{
dataObject_->NextRecord();
}
virtual void Prior()
{
dataObject_->PriorRecord();
}
virtual void Add(string customer)
{
dataObject_->AddRecord(customer);
}
virtual void Delete(string customer)
{
dataObject_->DeleteRecord(customer);
}
virtual void Show()
{
dataObject_->ShowRecord();
}
virtual void ShowAll()
{
cout<<"Customer Group : "<<group_<<endl;
dataObject_->ShowAllRecords();
}
protected:
string group_;
private:
DataObject* dataObject_;
};
//The 'RefinedAbstraction' class
class Customers : public CustomersBase
{
public:
Customers(string group) : CustomersBase(group) {};
//overriding
void ShowAll()
{
cout<<"\n------------------------------------"<<endl;
CustomersBase::ShowAll();
cout<<"------------------------------------"<<endl;
}
};
//Main
int main()
{
//Create RefinedAbstraction
Customers* customers = new Customers("London");
//Set ConcreteImplementor
CustomersData* customersData = new CustomersData();
DataObject* dataObject = customersData;
customersData->AddRecord("Tesco");
customersData->AddRecord("Sainsburys");
customersData->AddRecord("Asda");
customersData->AddRecord("Morrisons");
customersData->AddRecord("Lidl");
customersData->AddRecord("Co-op");
customers->SetDataObject(dataObject);
//Exercise the bridge
customers->Show();
customers->Next();
customers->Show();
customers->Next();
customers->Show();
customers->Add("M&S");
customers->ShowAll();
return 0;
}
The Output is as follows:
For more information see:
http://www.dofactory.com/Patterns/PatternBridge.aspx
http://sourcemaking.com/design_patterns/bridge
http://www.vincehuston.org/dp/bridge.html