设计模式(十四):桥接模式
定义:
·抽象类和其派生类分离,各自实现自己的对象。若系统可以从多角度分类,且每种分类都可能变化,则把多角度分离独立出来,降低耦合。
·涉及到一个作为桥接的接口,使实体类的功能独立于接口实现类。这两种类型的类结构化改变而互不影响。
主要解决:
·对象的继承关系编译时已确定,所以无法在运行时修改从父类继承的实现,由于紧耦合,父类中任何的改变必然会导致子类发生变化。
·当需要服用子类时,但继承下来的方法不合适时,必须重写父类或用其他类替代。
如何解决:
·抽象类依赖实现类
以代码为例:
类图关系如下
·有一个解释很形象:
猪八戒投胎,灵魂在河的一边,河对面有两个肉体,ConcreteImplementorA、B;灵魂需要过桥,选择红猪的肉体或者绿猪的肉体完成投胎。以上面类图为例,红猪和绿猪就是ConcreteImplementorA 和 ConcreteImplementorB,灵魂就是RedinedAbstraction类,而那座桥就是Implementor 这个接口。
一、定义Implementor类
定义实现类的接口,这里Iimplementor类即为桥接的接口
#include <iostream>
class Implementor
{
public:
virtual ~Implementor() {}
virtual void action() = 0;
// ...
};
二、定义ConcreteImplementA、B类
实现Implementor接口并定义具体实现
class ConcreteImplementorA : public Implementor
{
public:
~ConcreteImplementorA() {}
void action()
{
std::cout << "Concrete Implementor A" << std::endl;
}
// ...
};
class ConcreteImplementorB : public Implementor
{
public:
~ConcreteImplementorB() {}
void action()
{
std::cout << "Concrete Implementor B" << std::endl;
}
// ...
};
三、定义Abstraction
定义抽象的接口
class Abstraction
{
public:
virtual ~Abstraction() {}
virtual void operation() = 0;
// ...
};
四、定义RefineAbstraction
扩展Abstraction定义的接口
class RefinedAbstraction : public Abstraction
{
public:
~RefinedAbstraction() {}
RefinedAbstraction(Implementor *impl) : implementor(impl) {}
void operation()
{
implementor->action();
}
// ...
private:
Implementor *implementor;
};
五、main函数调用
int main()
{
Implementor *ia = new ConcreteImplementorA;
Implementor *ib = new ConcreteImplementorB;
Abstraction *abstract1 = new RefinedAbstraction(ia);
abstract1->operation();
Abstraction *abstract2 = new RefinedAbstraction(ib);
abstract2->operation();
delete abstract1;
delete abstract2;
delete ia;
delete ib;
return 0;
}
运行结果:
Concrete Implementor A
Concrete Implementor B
这样就简单实现了一个桥接模式
桥接模式的优缺点
优点:
1、抽象和实现的分离。 2、优秀的扩展能力。 3、实现细节对客户透明。
缺点:
1、桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
注意事项:
·如果抽象和实现两者做不到独立地变化,就不算桥接模式。
`遵循了组合/聚合复用原则