案例:某公司的产品有智能仪表和智能网关,可供选择的处理器有AM3352、S3C2440和tiny4412,智能仪表可以选择这3种处理器之一,同样智能网关也可以。
最简单的实现方式:
class SmartGateway : public Product
{
public:
void product_soc()
{
std::cout << "Smart Gateway Soc: AM3352" << std::endl;
}
};
class SmartMeter : public Product
{
public:
void product_soc()
{
std::cout << "Smart Meter Soc: S3C2440" << std::endl;
}
};
显然,如果要新增处理器为非AM3352的SmartGateway,就需要再定义子类。随着组合的增多,子类也会增加,这不是一种好的设计思路。
不同的产品搭载的Soc,可以对产品进行抽象,产品的实现部分与抽象部分进行解耦合,使它们可以独立变化,中间再“桥接”起来,这便是桥接模式:
+------------+ 桥接 +--------------------------+
| 变化的产品 |========== | 变化的实现(构成行为不同) |
+------------+ +--------------------------+
引入桥接模式后,上述案例的UML图可为:
(1)产品抽象类:维护对实现部分的引用
(2)产品抽象类的子类:使用基类维护的实现部分的引用使自己可以生成对对象
(3)行为抽象类:定义行为的接口
(4)行为抽象类的子类:行为的接口的实现
class Soc //行为抽象类
{
public:
virtual void install_soc() = 0;
};
class AM3352 : public Soc //行为的具体实现,产品构成时需调用本类
{
public:
void install_soc() { std::cout << "Soc: AM3352!\n"; }
};
class S3C2440 : public Soc
{
public:
void install_soc() { std::cout << "Soc: S3C2440!\n"; }
};
class Tiny4412 : public Soc
{
public:
void install_soc() { std::cout << "Soc: Tiny4412!\n"; }
};
class Product //产品的抽象类
{
public:
Product(Soc *s) : m_Soc(s) {}
virtual void install_soc() = 0;
protected:
Soc *m_Soc;
};
//产品的具体实现类,需要调用行为类的相关函数以构成具体对象
class SmartGateway : public Product
{
public:
SmartGateway(Soc *s) : Product(s) {}
void install_soc()
{
std::cout << "Smart Gateway: " << std::endl;
m_Soc->install_soc();
}
};
class SmartMeter : public Product
{
public:
SmartMeter(Soc *s) : Product(s) {}
void install_soc()
{
std::cout << "Smart Meter: " << std::endl;
m_Soc->install_soc();
}
};
int main(void)
{
Soc* soc = new AM3352; //行为类
Product *p = new SmartGateway(soc); //将行为类传给产品类以组合成具体产品
p->install_soc();
delete p;
delete soc;
return 0;
}
编译运行: