2.2.1 模式意图:
在实际开发中,如果仅仅关注对象间的协作,随着系统的不断壮大,对象之间的耦合度会逐渐增大,维护成本也会随之增高。所以我们要从关注对象间的协作,转变为关注它们间的关系、及其组成模型所在的领域、领域间的边界。基于以上种种,运用面向接口编程则更利于系统的扩展,而桥接模式正式应对这种面向接口编程而形成的设计模式。
2.2.2 模式概念:
它属于结构型模式,通过桥接的接口,将抽象部分与它的实现部分分离,使它们都可以独立地变化。
2.2.3 模式元素:
- 元素抽象(ComputerBridgeBase)
- 元素细节(ComputerBridge)
- 元件抽象(IGraphicsCard、IMainboard)
- 元件细节
2.2.4 代码示例:
//显卡
public interface IGraphicsCard
{
void Play();
}
//主板
public interface IMainboard
{
void Play();
}
public interface IHHD
{
void Play();
}
public abstract class ComputerBridgeBase
{
public IGraphicsCard graphicsCard;
public IMainboard mainboard;
public IHHD HHD;
public ComputerBridgeBase(IGraphicsCard graphicsCard, IMainboard mainboard, IHHD HHD)
{
this.graphicsCard = graphicsCard;
this.mainboard = mainboard;
this.HHD = HHD;
}
public abstract void Play();
}
public class ComputerBridge : ComputerBridgeBase
{
public ComputerBridge(IGraphicsCard graphicsCard, IMainboard mainboard, IHHD HHD) : base(graphicsCard, mainboard, HHD)
{
}
public override void Play()
{
mainboard.Play();
HHD.Play();
graphicsCard.Play();
}
}
2.2.5 写法对比:
略
2.2.6 模式分析:
为什么要抽象Computer?
抽象的Computer确定了固定结构,实现的细节被转移到子类里面。比如在Play函数中,我们可以根据不同computer实现类实现不同元件play顺序的调用。为什么元件不用逐级的嵌套继承?
因为更灵活。如果用逐级继承的方式实现元件,后期有一种元件内部的结构发生了改变,势必会影响它对应的子类,牵一发而动全身。而且每种元件的内部独立工作,其它元件无需知道其对应的内部元素,接口的实现交给对应的实现类,这也是笔者以往提到的组合优于继承的原因。最后就是同种元件的不同品牌的更换会更独立,极大的降低耦合性。如何理解将抽象部分与它的实现部分分离?
抽象的Computer不仅把实现的细节分离,也把各元件的实现细节用组合的方式进行分离,通过接口这个“桥”进行松耦合的连接。
这样以来,不管是Computer 的具体实现,还是元件的更换都会更加的独立,也更符合开闭原则。面向接口编程其实就是用到了这种思想。
2.2.7 应用场景:
- 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
- 如需增加构件中抽象化与具体化角色之间的灵活性,使用桥接模式可以使它们在抽象层建立关系。
- 需要从继承或多重继承中简化结构,且应对频繁变动的需求
2.2.8 小结:
基于面向接口编程的桥接模式,对于系统的频繁需求变化,不管是从结构还是稳定性都是首选。