Java学习-------桥接模式
在软件开发中,我们常常会遇到一个类存在多个维度的变化,如果处理不当,会导致类的数量急剧增加,代码变得臃肿且难以维护。桥接模式(Bridge Pattern)正是为解决这类问题而生,它通过将抽象部分与实现部分分离,使它们可以独立变化,从而提高系统的灵活性和可扩展性。
构型设计模式,它将抽象部分与它的实现部分分离,使它们都可以独立地变化。这里的 “抽象” 和 “实现” 并不是我们通常所理解的抽象类和实现类,而是指两个独立变化的维度。比如,在绘制图形时,图形有形状(如圆形、矩形)和颜色(如红色、蓝色)两个维度的变化。如果按照传统的方式,为每种形状和颜色的组合都创建一个类,像红色圆形、蓝色圆形、红色矩形、蓝色矩形等,当形状或颜色种类增多时,类的数量会呈几何倍数增长。而桥接模式就像一座桥梁,把形状和颜色这两个维度连接起来,让它们可以各自独立扩展,避免类的爆炸式增长。
桥接模式的核心原理是分离抽象与实现,通过组合而非继承来关联它们。它将系统分为两个独立的层次:抽象层和实现层。其基本结构包含以下几个部分:
(1)抽象化角色(Abstraction):定义抽象类的接口,它持有一个对实现化角色的引用,通过该引用调用实现化角色的方法。抽象化角色可以是抽象类或接口,它负责定义抽象的业务方法。
(2)扩展抽象化角色(Refined Abstraction):是抽象化角色的子类,它实现了抽象化角色中定义的抽象方法,并可以调用实现化角色中的具体方法。它可以对抽象化角色进行扩展。
(3)实现化角色(Implementor):定义实现类的接口,它是抽象化角色所依赖的接口,实现化角色不直接与抽象化角色交互,而是通过抽象化角色的引用被调用。
(4)具体实现化角色(Concrete Implementor):是实现化角色的子类,它实现了实现化角色中定义的接口,提供具体的业务实现。
抽象化角色通过持有实现化角色的引用,将自身的部分功能委托给实现化角色去完成,从而在抽象层和实现层之间搭建起一座 “桥梁”,使两者可以独立地变化和扩展。
桥接模式在软件开发中有着重要的作用,主要体现在以下几个方面:
(1)分离抽象与实现:将抽象部分和实现部分分开,使它们可以各自独立地进行修改和扩展,互不影响。当需要修改实现部分时,不会影响到抽象部分;反之,修改抽象部分也不会对实现部分造成影响。
(2)减少类的数量:避免了因多个维度变化而导致的类爆炸问题。如果不使用桥接模式,多个维度的组合会产生大量的类,而桥接模式通过将不同维度分离,大大减少了类的数量。
(3)提高系统灵活性:抽象层和实现层可以独立变化,我们可以根据需求灵活地组合不同的抽象和实现,从而实现不同的功能。例如,在图形绘制的例子中,可以很方便地将不同的形状与不同的颜色进行组合。
(4)便于系统扩展:当需要增加新的抽象或新的实现时,只需新增相应的类即可,不需要修改已有的代码,符合 “开闭原则”,有利于系统的扩展和维护。
桥接模式的优点主要有:
(1)提高系统可扩展性:抽象和实现可以独立扩展,新增抽象类或实现类都很方便,无需修改原有系统,能很好地应对变化。
(2)降低耦合度:抽象与实现之间通过桥接进行关联,而不是通过继承,减少了它们之间的依赖关系,降低了系统的耦合度。
(3)符合开闭原则:在扩展新的功能时,只需添加新的类,不需要修改已有的代码,保证了系统的稳定性。
(4)便于应对多维度变化:当一个类存在多个维度的变化时,桥接模式能很好地将这些维度分离,使每个维度可以独立变化,避免了类数量的急剧增加。
其缺点则主要为:
(1)增加系统复杂度:桥接模式引入了抽象层和实现层的分离,以及它们之间的关联关系,这会使系统的结构变得更加复杂,理解起来有一定的难度。
(2)需要正确设计抽象和实现:使用桥接模式需要准确地识别出系统中的抽象部分和实现部分,以及它们各自的变化维度,如果设计不当,可能无法达到预期的效果,甚至会使系统更加混乱。
(3)增加开发成本:由于系统结构变得复杂,开发人员需要花费更多的时间和精力去设计和实现,相对来说增加了开发成本。
下面通过一个绘制不同颜色和形状的图形的例子来演示桥接模式的实现。图形有形状(如圆形、矩形)和颜色(如红色、蓝色)两个维度的变化,我们可以使用桥接模式将这两个维度分离。
// 颜色接口(实现化角色)
interface Color {void applyColor();
}// 红色(具体实现化角色)
class Red implements Color {@Overridepublic void applyColor() {System.out.println("应用红色");}
}// 蓝色(具体实现化角色)
class Blue implements Color {@Overridepublic void applyColor() {System.out.println("应用蓝色");}
}
// 形状抽象类(抽象化角色)
abstract class Shape {protected Color color;// 通过构造方法注入颜色public Shape(Color color) {this.color = color;}abstract void draw();
}// 圆形(扩展抽象化角色)
class Circle extends Shape {public Circle(Color color) {super(color);}@Overridevoid draw() {System.out.print("绘制圆形,");color.applyColor();}
}// 矩形(扩展抽象化角色)
class Rectangle extends Shape {public Rectangle(Color color) {super(color);}@Overridevoid draw() {System.out.print("绘制矩形,");color.applyColor();}
}
public class Client {public static void main(String[] args) {// 红色圆形Shape redCircle = new Circle(new Red());redCircle.draw();// 蓝色矩形Shape blueRectangle = new Rectangle(new Blue());blueRectangle.draw();// 红色矩形Shape redRectangle = new Rectangle(new Red());redRectangle.draw();}
}
其运行结果为:
绘制圆形,应用红色
绘制矩形,应用蓝色
绘制矩形,应用红色
从代码和运行结果可以看出,我们将形状和颜色这两个维度分离开来,通过桥接模式将它们关联起来。当需要新增一种颜色或形状时,只需新增相应的实现类或抽象子类即可,无需修改已有的代码。例如,新增绿色,只需创建一个Green类实现Color接口;新增三角形,只需创建一个Triangle类继承Shape抽象类。这样就很好地体现了桥接模式让抽象与实现灵活分离、便于扩展的特点。