一、什么是桥接模式
二、为什么需要桥接模式
-
解耦抽象和实现:桥接模式可以将抽象和实现部分分离,使它们可以独立地变化。这样一来,如果需要修改抽象部分或实现部分的代码,就不会影响到另一部分的代码。
-
支持多维度变化:桥接模式可以支持多维度的变化,即抽象部分和实现部分可以独立地进行扩展。例如,如果有多个不同类型的抽象和多个不同类型的实现,可以通过桥接模式将它们组合起来,形成多种组合的可能性。
-
提高可扩展性:由于桥接模式将抽象和实现分离,因此可以很方便地对其进行扩展。如果需要新增一种抽象或实现,只需要添加相应的类即可,而不需要修改已有的代码。
-
降低耦合度:桥接模式可以降低系统中各个类之间的耦合度。通过将抽象和实现分离,可以使它们之间的关系变得松散,从而减少类之间的依赖关系。
三、桥接模式实现原理
-
定义抽象部分(Abstraction):抽象部分定义了高层逻辑,它包含一个指向实现部分的引用,并且定义了抽象方法或者具体方法。
-
定义实现部分(Implementor):实现部分定义了低层逻辑,它提供了具体的实现方法。
-
创建具体的抽象类(RefinedAbstraction):具体的抽象类继承了抽象部分,并且实现了抽象方法。
-
创建具体的实现类(ConcreteImplementor):具体的实现类继承了实现部分,并且提供了具体的实现方法。
-
在客户端中使用桥接模式:客户端通过抽象部分来调用具体的实现部分,从而实现了抽象部分与实现部分的解耦。
四、桥接模式的应用范围
-
操作系统和文件系统之间的桥接:在操作系统中,不同的文件系统可能有不同的实现方式,通过桥接模式可以将操作系统和文件系统解耦,使得它们可以独立地变化。例如,Windows操作系统可以支持NTFS文件系统和FAT32文件系统,而Linux操作系统可以支持EXT4文件系统和XFS文件系统。
-
图形界面库的桥接:在图形界面库中,不同的图形界面元素(如按钮、文本框等)可能有不同的实现方式,通过桥接模式可以将图形界面元素和其具体实现解耦。例如,一个按钮可以有不同的样式(如平面样式、立体样式),通过桥接模式可以将按钮和样式之间的关系抽象出来。
-
数据库驱动程序的桥接:在数据库驱动程序中,不同的数据库(如MySQL、Oracle)可能有不同的实现方式,通过桥接模式可以将数据库和驱动程序解耦。例如,一个数据库驱动程序可以支持多种数据库,通过桥接模式可以将数据库和驱动程序之间的关系抽象出来。
-
远程控制器的桥接:在远程控制器中,不同的设备(如电视、音响)可能有不同的控制方式,通过桥接模式可以将设备和控制方式解耦。例如,一个远程控制器可以支持多种设备,通过桥接模式可以将设备和控制方式之间的关系抽象出来。
五、桥接模式的应用举例
量化交易系统中的应用
抽象部分:交易策略
在量化交易系统中,交易策略是根据市场行情和投资者的需求制定的一套规则和算法。不同的交易策略可能包括趋势跟踪、均值回归、套利等。通过桥接模式,可以将不同的交易策略抽象出来,定义一个统一的接口。
实现部分:交易执行方式
在量化交易系统中,交易执行方式包括实时交易、延迟交易、模拟交易等。不同的交易执行方式可能使用不同的技术和接口。通过桥接模式,可以将不同的交易执行方式实现部分抽象出来,定义一个统一的接口。
桥接连接
桥接模式通过将抽象部分和实现部分进行桥接连接,实现了两者的解耦。在量化交易系统中,可以通过桥接模式将不同的交易策略和交易执行方式进行组合,从而实现灵活的交易组合。例如,可以将趋势跟踪策略与实时交易方式进行桥接连接,将均值回归策略与延迟交易方式进行桥接连接,从而实现不同策略和不同执行方式的组合。
六、桥接模式的代码实现
//+------------------------------------------------------------------+
//| structure |
//+------------------------------------------------------------------+
//
//|Client|
// |
// +-->| Abstraction |----------------->| Implementor |
// |----------------| |--------------|
// |Operation() | |OperationImp()|
// | imp.Operation()| ^
// ^ |
// | +----------+----------+
// | | |
// |RefinedAbstraction| |ConcreteImplementorA| |ConcreteImplementorB|
// |--------------------| |--------------------|
// |OperationImp() | |OperationImp() |
//
// 定义实现类的接口
// 实现者接口只提供基本操作
// 抽象定义了基于这些基元的更高级别的操作
interface Implementor
{
void OperationImp();
};
// 定义抽象的接口
// 维护对类型为implementer的对象的引用
class Abstraction
{
public:
virtual void Operation();
Abstraction(Implementor*);
Abstraction();
~Abstraction();
protected:
Implementor* implementor;
};
void Abstraction::Abstraction()
{
}
//
void Abstraction::Abstraction(Implementor*i):implementor(i)
{
}
//
void Abstraction::~Abstraction()
{
delete implementor;
}
//
void Abstraction::Operation()
{
implementor.OperationImp();
}
//+------------------------------------------------------------------+
//| participants |
//+------------------------------------------------------------------+
class RefinedAbstraction:public Abstraction
// extends the interface defined by abstraction
{
public:
RefinedAbstraction(Implementor*);
void Operation();
};
void RefinedAbstraction::RefinedAbstraction(Implementor*i):Abstraction(i) {}
void RefinedAbstraction::Operation() {Abstraction::Operation();}
// 实现实现者接口
// 定义其具体实现
class ConcreteImplementorA:public Implementor
{
public:
void OperationImp();
};
void ConcreteImplementorA::OperationImp(void) {Print("Implementor A");}
//
class ConcreteImplementorB:public Implementor
{
public:
void OperationImp();
};
//
void ConcreteImplementorB::OperationImp(void)
{
Print("Implementor B");
}
//
interface ClientInterface
{
string Output();
void Run();
};
//+------------------------------------------------------------------+
//| participants |
//+------------------------------------------------------------------+
class Client:public ClientInterface
{
public:
string Output();
void Run();
};
string Client::Output(void) {return __FUNCTION__;}
// 抽象将客户端请求转发到其实现者对象
void Client::Run(void)
{
Abstraction *abstraction;
//---
abstraction=new RefinedAbstraction(new ConcreteImplementorA);
abstraction.Operation();
delete abstraction;
//---
abstraction=new RefinedAbstraction(new ConcreteImplementorB);
abstraction.Operation();
delete abstraction;
}
//
void Run(ClientInterface* client)
{
printf("---\n%s",client.Output());
client.Run();
delete client;
}
//
void OnStart()
{
Run(new Structural::Bridge::Client);
}
//+------------------------------------------------------------------+
//| output |
//+------------------------------------------------------------------+
// Structural::Bridge::Client::Output
// Implementor A
// Implementor B
//+------------------------------------------------------------------+