设计模式之桥接模式
Intro
桥接模式(Bridge),将抽象部分与它的实现部分分离,使得它们都可以独立地变化。
这里说到抽象与它的实现分离指的是抽象类和它的派生类用来实现自己的对象
还有另外一种理解方式,一个类存在两个(或多个)独立变化的维度,我们通过组合的方式,让这两个(或多个)维度可以独立进行扩展。
通过组合关系来替代继承关系,避免继承层次的指数级爆炸。这种理解方式非常类似于,我们之前讲过的“组合优于继承”设计原则。
Sample
internal abstract class Implementor
{
public abstract void Operation();
}
internal class ConcreteImplementorA : Implementor
{
public override void Operation()
{
Console.WriteLine("ImplementorA Operation");
}
}
internal class ConcreteImplementorB : Implementor
{
public override void Operation()
{
Console.WriteLine("ImplementorB Operation");
}
}
internal abstract class Abstraction
{
protected Implementor Implementor;
public void SetImplementor(Implementor implementor)
{
Implementor = implementor;
}
public abstract void Operation();
}
internal class RefinedAbstraction : Abstraction
{
public override void Operation()
{
Implementor.Operation();
Console.WriteLine("Invoke in RefinedAbstraction");
}
}
Abstraction ab = new RefinedAbstraction();
ab.SetImplementor(new ConcreteImplementorA());
ab.Operation();
ab.SetImplementor(new ConcreteImplementorB());
ab.Operation();
More
王争在他的极客专栏中以 jdbc 的实现举例说明桥接模式
我觉得 ADO.NET 中也有类似的设计,于是看了看 ADO.NET 的部分源码,与君分享一下
ADO.NET 是 .NET 里类似于 JDBC 用来进行数据库操作一套抽象 API,
而 JDBC 里的各种 driver 是用来连接数据库,提供数据库操作具体实现的,.NET 与之对应的是 DbProviderFactory
实际上,JDBC 本身就相当于“抽象”。注意,这里所说的“抽象”,指的并非“抽象类”或“接口”,而是跟具体的数据库无关的、被抽象出来的一套“类库”。具体的 Driver(比如,com.mysql.jdbc.Driver)就相当于“实现”。注意,这里所说的“实现”,也并非指“接口的实现类”,而是跟具体数据库相关的一套“类库”。JDBC 和 Driver 独立开发,通过对象之间的组合关系,组装在一起。JDBC 的所有逻辑操作,最终都委托给 Driver 来执行。
ADO.NET 提供了数据库操作的抽象,而具体的 System.SqlClient
/Microsoft.SqlClient
/MySql.Data
提供了具体的实现,ADO.NET 和 Driver 基本保持独立开发,通过对象的组合关系组装在一起,ADO.NET 的具体操作交由对应的实现完成。
具体实现细节可以参考文末的参考链接
Reference
- https://github.com/WeihanLi/DesignPatterns/tree/master/StructurePattern/BridgePattern
- https://referencesource.microsoft.com/#System.Data/fx/src/data/System/Data/Common/DbProviderFactoriesConfigurationHandler.cs,4ba4f3a32e06482d
- https://referencesource.microsoft.com/#System.Data/fx/src/data/System/Data/Common/DbProviderFactories.cs,54a4aed2ea64c166
- https://referencesource.microsoft.com/#System.Data/fx/src/data/System/Data/Common/DbProviderFactory.cs,daaf2f2e817b5fd8