设计模式 - 桥接模式
一、引入
当我们在设计软件时,有时会遇到一些情况,需要让不同的部分可以独立地变化,而又可以配合起来工作。桥接模式就是帮我们解决这个问题的一种方法。
比如,想象一下你在设计一个汽车系统,汽车有不同的品牌(比如宝马、奔驰、丰田等),而每个品牌又可以有不同的型号(比如宝马X5、宝马X3等)。如果我们直接把品牌和型号硬编码在一起,那么如果要添加新的品牌或者新的型号,就会非常麻烦。
桥接模式就是为了解决这个问题而存在的。它的核心思想是将抽象部分(比如汽车的品牌)和实现部分(比如具体型号)分开,使它们可以独立地变化,然后通过组合的方式来组装不同的组合。
举个例子,我们可以定义一个抽象的汽车类,其中包含一个品牌属性和一个型号属性。然后,我们可以定义不同的品牌和型号,它们分别实现了汽车的抽象接口。这样,我们可以随意组合不同的品牌和型号,而不需要修改已有的代码。
总的来说,桥接模式让我们可以更灵活地设计和组织软件,使各个部分可以独立变化,同时又能配合起来工作,提高了系统的可扩展性和可维护性。
二、概念
桥接模式(Bridge Pattern)是一种结构型设计模式,它将抽象部分与实现部分分离,使得它们可以独立变化,从而提高了系统的灵活性。
在桥接模式中,抽象部分指的是定义了一个接口或抽象类,它包含了对实现部分的引用,而实现部分指的是实现了抽象部分定义的接口或抽象类的具体类。
桥接模式的核心思想是将抽象和实现分离开来,使得它们可以独立变化。这样,可以在不修改抽象部分的情况下修改实现部分,也可以在不修改实现部分的情况下修改抽象部分。
三、基本结构
- 抽象部分(Abstraction):定义了高层操作,通常包含一个抽象类或接口。
- 扩充抽象部分(Refined Abstraction):继承自抽象部分,可以扩展抽象部分中定义的高层操作。
- 实现部分(Implementor):定义了低层操作,通常包含一个实现类或接口。
- 具体实现部分(Concrete Implementor):实现了实现部分定义的低层操作。
四、示例代码
// 实现部分:颜色
interface Color {
void applyColor();
}
//具体实现 : 红色
public class Red implements Color {
@Override
public void applyColor() {
System.out.println("红色");
}
}
//具体实现 : 蓝色
public class Blue implements Color {
@Override
public void applyColor() {
System.out.println("蓝色");
}
}
//抽象部分
public abstract class Shape {
protected Color color;
public Shape(Color color) {
this.color = color;
}
abstract void draw();
}
//抽象扩充部分 : 圆形
public class Circle extends Shape {
public Circle(Color color) {
super(color);
}
@Override
void draw() {
System.out.println("圆形");
color.applyColor();
}
}
//抽象扩充部分 : 长方形
public class Rectangle extends Shape {
public Rectangle(Color color) {
super(color);
}
@Override
void draw() {
System.out.println("长方形");
color.applyColor();
}
}
/**
* 客户端
*/
public class Client {
public static void main(String[] args) {
// 红色圆形
Red red = new Red();
Circle circle = new Circle(red);
circle.draw();
// 蓝色长方形
Blue blue = new Blue();
Rectangle rectangle = new Rectangle(blue);
rectangle.draw();
}
}
五、用途
在实际开发中,桥接模式常用于以下情况:
- 当一个类有多个变化维度时:比如一个类的变化可以分为两个维度,分别是抽象部分和实现部分,这时可以考虑使用桥接模式。
- 当一个类需要在运行时选择实现时:桥接模式可以让我们在运行时动态地选择抽象部分和实现部分,使得系统更加灵活。
- 当多个类共享同一个实现时:如果多个类需要共享同一个实现,而不希望它们之间产生紧耦合关系,可以考虑使用桥接模式。
- 在系统设计中需要独立管理抽象和实现部分时:桥接模式将抽象部分和实现部分分开,使得可以独立地对它们进行管理和扩展。
- 避免类的爆炸性增长:如果所有的实现都直接继承自抽象类,可能会导致类的层次结构变得庞大复杂,桥接模式可以避免这种情况。
具体应用桥接模式的例子包括:
- JDBC驱动程序:在Java中,不同数据库的JDBC驱动程序可以作为实现部分,而JDBC接口可以作为抽象部分,通过桥接模式来实现对不同数据库的访问。
- 图形用户界面工具包:比如Swing,不同的外观(Look and Feel)可以作为实现部分,而界面元素和布局可以作为抽象部分,通过桥接模式来实现不同风格的界面。
六、总结
优点:
- 分离抽象与实现:桥接模式可以将抽象部分和实现部分分离,使得它们可以独立变化。这样一来,对于抽象部分的修改不会影响到实现部分,反之亦然,使得系统更加灵活。
- 动态切换实现:桥接模式允许在运行时动态地选择抽象部分和实现部分,使得系统的行为可以根据需要进行动态调整。
- 共享实现:多个类可以共享同一个实现,避免了类的爆炸性增长,降低了代码的复杂度。
- 独立管理抽象和实现:桥接模式将抽象部分和实现部分分开,使得可以独立地对它们进行管理和扩展。
缺点:
- 增加了系统的复杂度:引入了桥接模式会增加一些额外的类和接口,可能会增加系统的复杂度。
- 增加了设计的抽象程度:对于简单的系统,引入桥接模式可能会显得过于繁琐,会增加代码的量。
- 增加了开发和维护的难度:在设计时需要仔细考虑抽象部分和实现部分的划分,需要对系统的整体架构有一个清晰的认识。
总的来说,桥接模式适用于那些需要在抽象部分和实现部分之间存在多对多关系的场景,能够提高系统的灵活性和可扩展性,但也需要在设计时仔细考虑抽象部分和实现部分的划分,避免引入过度的复杂性。