版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/CL_YD/article/details/88061370
桥接模式
定义
桥接模式(Bridge Pattern
):将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body
)模式或接口(Interface
)模式。
场景
现在要开发一个报表系统,报表数据来源有很多,包括mysql数据库、mongodb、REST API等,报表输出的形式也很多,包括邮件、excel、html、mysql数据库等。以后可能会有新的数据源,也可能会有新的输出方式。
不同于其他设计模式,我们需要在数据源和输出方式这两个维度都支持扩展,到目前为止没有任何设计模式可以支持多个维度的扩展,适配器模式好像可以实现,但适配器模式并不适用于这种场景,因此可以使用另一种设计模式——桥接模式。
UML类图
代码
bridge
示例:
public class TestBridge {
@Test
public void test(){
Map<String,Object> configMap = new HashMap<>();
Output mail = new Mail();
Output html = new Html();
Output mysql = new github.clyoudu.dpinj.bridge.output.Mysql();
Output excel = new Excel();
Datasource mysqls = new Mysql(mail);
Datasource mongoDb = new MongoDb(html);
Datasource restApi = new RestApi(excel);
Datasource restApi1 = new RestApi(mysql);
System.out.println("----------mysql => mail------------");
mysqls.report(configMap);
System.out.println("\n----------mongodb => html------------");
mongoDb.report(configMap);
System.out.println("\n----------rest api => excel------------");
restApi.report(configMap);
System.out.println("\n----------rest api => mysql------------");
restApi1.report(configMap);
}
/*
----------mysql => mail------------
Query data list from mysql...
Send mail...
----------mongodb => html------------
Query data list from mongo db...
Generate html file...
----------rest api => excel------------
Query data list from REST API...
Generated excel file...
----------rest api => mysql------------
Query data list from REST API...
Save to mysql...
*/
}
总结
桥接模式将抽象和实现分离,可以说是多继承的一种替代方案(同时有Datasource
和Output
的功能,而且需要的功能都是已经实现好的),但又不像多继承那样讲对象关系绑定——多个功能可以在使用的时候自由组合,而不是为每种组合定义一个类。同时桥接模式符合开闭原则、单一职责原则,在两个变化维度中任意扩展一个维度,都不需要修改原有系统。桥接模式并不是只能在有两个维度能够单独变化的场景下使用,多个维度照样适用,按照桥接模式的主要思想扩展即可,比如一个维度可以由两个维度组成,在同一个维度中使用多个其他维度的抽象等。
桥接模式理解难度较高,设计时需要有足够的经验和抽象能力,如何准确确定两个变化的维度也非常有难度,实际场景中可能并不像本例中那么纯粹的变化。
桥接模式的使用场景如下:
- 需要在抽象和实现之间增加灵活度,而不是简单地继承;
- 抽象部分和实现部分可以单独的变化,特别是抽象部分和实现部分依赖的数据和中间数据都是相同的,只是对依赖数据和中间结果的处理方式不同;
- 业务场景中有两个或多个独立变化的维度,并且这些维度都是可以独立变化的;
- 重构时,因为多继承(Java有间接的多继承)导致系统急剧膨胀的场景,可以用桥接模式降低系统的复杂度。