使用Bridge模式的好处:当给对象增加新的属性时只需要继承这个对象的抽象属性接口就行了,当给对象增加新的方法时只需要继承这个对象的抽象方法接口就OK了。这样就使用一个对象的属性与方法完成分开来了。
图表:
图表说明
在Bridge模式的结构图中可以看到,系统被分为两个相对独立的部分,左边是抽象部分,右边是实现部分,这两个部分可以互相独立地进行修改:例如上面问题中的客户需求变化,当用户需求需要从Abstraction派生一个具体子类时候,并不需要像上面通过继承方式实现时候需要添加子类A1和A2了。另外当上面问题中由于算法添加也只用改变右边实现(添加一个具体化子类),而右边不用在变化,也不用添加具体子类了。
例子1:
在机子上玩游戏为例来说明Bridge模式:
1.对象属性方面:
先创建一个抽象类来说明在什么系统下玩游戏
再创建具体的属性类如Windows98系统与windows2000系统
2.对象方法方面:
先创建一个抽象来来说明玩游戏
再创建具体的类来说明正在玩什么游戏
代码如下:
// 定义计算机类型的抽象类(接口)
class CComputerSystem
{
public:
virtual ~CComputerSystem() { }
virtual string GetSystemName() = 0;
};
// 定义Windows98操作系统
class CWindows98 : public CComputerSystem
{
public:
CWindows98() { }
~CWindows98() { }
public:
virtual string GetSystemName() { return string("Windows98"); }
};
// 定义Windows2000操作系统
class CWindows2000 : public CComputerSystem
{
public:
CWindows2000() { }
~CWindows2000() { }
public:
virtual string GetSystemName() { return string("Windows2000"); }
};
// 定义游戏抽象类(接口)
class CGame
{
public:
virtual ~CGame() { }
virtual void PlayGame() = 0;
};
// 定义游戏具体类:星际争霸
class CStartCarft : public CGame
{
public:
CStartCarft(CComputerSystem* pSystem) : m_pSystem(pSystem) { }
~CStartCarft() { }
public:
virtual void PlayGame()
{
string strSystemName = m_pSystem->GetSystemName();
string strText = "正在" + strSystemName + "系统下玩星际争霸";
printf("[CStartCarft] %s \n", strText.c_str());
}
private:
CComputerSystem* m_pSystem;
};
// 定义游戏具体类:帝国时代
class CAgeOfEmpire : public CGame
{
public:
CAgeOfEmpire(CComputerSystem* pSystem) : m_pSystem(pSystem) { }
~CAgeOfEmpire() { }
public:
virtual void PlayGame()
{
string strSystemName = m_pSystem->GetSystemName();
string strText = "正在" + strSystemName + "系统下玩帝国时代";
printf("[CAgeOfEmpire] %s \n", strText.c_str());
}
private:
CComputerSystem* m_pSystem;
};
测试代码:
void BridgeDemo()
{
CComputerSystem* pSystem = new CWindows98();
CGame* pGame = new CStartCarft(pSystem);
pGame->PlayGame();
delete pGame;
delete pSystem;
}
例子2:
* 任务叙述:我们现在要实现一个画图系统,这个系统的需求暂时来说有以下几个:
* 1、画圆、画长方形。(先实现画这两个形状)
* 2、已经有两个画图库了,这些画图库中定义了我们需要的操作,我们没必要重新去实现了
* 3、我们的系统能够决定使用哪个的画图库中的操作
// 画图库
class CDrawLib1
{
public:
void DrawCircle()
{
cout << "画圆操作" << endl;
}
void DrawRectangle()
{
cout << "画长方形操作" << endl;
}
void DrawTriangle()
{
cout << "画三角形操作" << endl;
}
};
// 画图库
class CDrawLib2
{
public:
void DrawCircle()
{
cout << "画圆操作" << endl;
}
void DrawRectangle()
{
cout << "画长方形操作" << endl;
}
void DrawTriangle()
{
cout << "画三角形操作" << endl;
}
};
// 建立一个实现操作的类:CShapeImp
class CShapeImp
{
public:
virtual void DrawCircle() = 0;
virtual void DrawRectangle() = 0;
};
class CShapeImp1: public CShapeImp
{
public:
virtual void DrawCircle()
{
_dLib.DrawCircle();
}
virtual void DrawRectangle()
{
_dLib.DrawRectangle();
}
private:
CDrawLib1 _dLib;
};
class CShapeImp2: public CShapeImp
{
public:
virtual void DrawCircle()
{
_dLib.DrawCircle();
}
virtual void DrawRectangle()
{
_dLib.DrawRectangle();
}
private:
CDrawLib2 _dLib;
};
class CShape
{
public:
virtual void Draw() = 0;
protected:
CShapeImp *_sImp;
};
class CCircle: public CShape
{
public:
CCircle(CShapeImp *imp)
{
_sImp = imp;
}
virtual void Draw()
{
_sImp->DrawCircle();
}
};
class CRectangle: public CShape
{
public:
CRectangle(CShapeImp *imp)
{
_sImp = imp;
}
virtual void Draw()
{
_sImp->DrawRectangle();
}
};
测试代码:
// 好了,我们利用上面的类结构来实现我们的画图系统
void main()
{
cout << "使用Bridge模式" << endl;
CShapeImp1 sImp1;
CShapeImp2 sImp2;
// 使用画图库
CCircle c1(&sImp1);
CRectangle r1(&sImp1);
c1.Draw();
r1.Draw();
// 使用画图库
CCircle c2(&sImp2);
CRectangle r2(&sImp2);
c2.Draw();
r2.Draw();
}
转:http://www.cnblogs.com/helimin19/archive/2005/03/07/114402.html