
继承的问题
继承是 C++ 面向对象很重要的特点之一,但是如果通过继承抽象类去实现提供不同能力的具体类,这会在编译期间绑定抽象类和具体类,使得抽象类和具体类无法独立的扩展和组合。
线程调度设计
上面的描述很抽象,先具体看看桥接模式是如何在线程调度类的设计中工作的。首先用继承的思想,设计如下:

线程调度策略有抢占式调度和时间片式调度,存在 windows 和 unix 操作系统,通过继承的方式,不算基类,最后会需要四个具体类。如果需要扩展一个操作系统,比如现在要添加 JAVA 虚拟机的实现,那么继承关系会变成下面这样:

如果有更多的操作系统类型和更多的线程调度策略,通过继承的方式,类的数量就会急剧扩大,导致可维护性很差。下面通过桥接模式来对线程调度进行设计,关系图入下:

这里主要的区别在于,调度策略和操作系统类型不再通过继承的方式绑定在一起(继承实际上是一种很强的耦合绑定),而是通过组合的方式。这里的组合是指,ThreadScheduler 会持有一个 ThreadScheduler_Implementation 的指针,这样调度策略和操作类型就能在运行时自由组合,两者之间的耦合度要远远小于继承的场景,同时对操作系统类型扩展,仅仅需要增加扩展的操作系统类,对调度策略进行增加,仅仅需要扩展 ThreadScheduler_Implementation 中的接口,扩展性更好。
示例代码
class ThreadScheduler
{
ThreadScheduler(ThreadScheduler_Implementation *pImpl)
: m_impl(pImpl)
{
}
...
virtual void schedule();
...
protected:
ThreadScheduler_Implementation *m_impl;
};
class PreemptiveScheduler
{
...
virtual void schedule()
{
m_impl->doPreemptive();
}
...
};
class TimeSlicedScheduler
{
...
virtual void schedule()
{
m_impl->doTimeSLiced();
}
...
};
class ThreadScheduler_Implementation
{
...
virtual void doPreemptive();
virtual void doTimeSLiced();
...
};
class Unix_Scheduler : ThreadScheduler_Implementation
{
...
void doPreemptive();
void doTimeSLiced();
...
};
class Windows_Scheduler : ThreadScheduler_Implementation
{
...
void doPreemptive();
void doTimeSLiced();
...
};
class JVM_Scheduler : ThreadScheduler_Implementation
{
...
void doPreemptive();
void doTimeSLiced();
...
};
int main()
{
ThreadScheduler_Implementation *pUnixImpl = new Unix_Scheduler();
ThreadScheduler *pUnixPreemptiveScheduler = new PreemptiveScheduler(pUnixImpl);
pUnixPreemptiveScheduler->schedule();
ThreadScheduler_Implementation *pWindowsImpl = new Windows_Scheduler();
ThreadScheduler *pWindowsTimeSlicedScheduler = new TimeSlicedScheduler(pWindowsImpl);
pWindowsTimeSlicedScheduler->schedule();
}
总结
下面情况可能需要桥接模式:
- 当你希望实现运行时绑定时。
- 当你面临一个接口与众多实现紧密耦合导致的类爆炸问题时。
使用桥接模式有以下特点:
- 将对象的接口与实现解耦。
- 提高了可扩展性(即你可以独立地扩展抽象层次和实现层次)。
- 对外隐藏实现细节。
关注公众号:C++学习与探索,有惊喜哦~
3084

被折叠的 条评论
为什么被折叠?



