概叙:桥接模式用一种巧妙的方式处理多层继承存在的问题,
用抽象关联取代了传统的多层继承,
将类之间的静态继承关系转换为动态的对象组合关系,
使得系统更加灵活,并易于扩展,
同时有效控制了系统中类的个数,桥接定义如下:
桥接模式:将抽象部分与它实现的部分分离,使它们都可用独立地变化。
它是一种对象结构模式,又称柄体模式(Handle and Body)或接口模式.
桥接模式的结构与其名称一样,存在一条连接两个继承等级结构的桥,
举例:
让我们通过一个更简单的例子来更深入地理解桥接设计模式以及它是如何解决问题的。考虑一个图形绘制的场景,有两个维度的变化:形状和颜色。在没有桥接模式的情况下,可能会考虑创建形状的子类和颜色的子类,然后通过组合它们来得到所有可能的组合。这会导致类的爆炸,因为每个形状都需要与每种颜色组合一次。
不使用桥接模式的情况:
// 不使用桥接模式的代码
class CircleRed extends Circle {
@Override
public void draw() {
System.out.println("Drawing red circle");
}
}
class CircleGreen extends Circle {
@Override
public void draw() {
System.out.println("Drawing green circle");
}
}
class RectangleRed extends Rectangle {
@Override
public void draw() {
System.out.println("Drawing red rectangle");
}
}
class RectangleGreen extends Rectangle {
@Override
public void draw() {
System.out.println("Drawing green rectangle");
}
}
// 客户端代码
public class WithoutBridgePatternExample {
public static void main(String[] args) {
CircleRed redCircle = new CircleRed();
redCircle.draw(); // Drawing red circle
CircleGreen greenCircle = new CircleGreen();
greenCircle.draw(); // Drawing green circle
RectangleRed redRectangle = new RectangleRed();
redRectangle.draw(); // Drawing red rectangle
RectangleGreen greenRectangle = new RectangleGreen();
greenRectangle.draw(); // Drawing green rectangle
}
}
上述代码存在的问题是,每增加一种形状或颜色的组合,都需要创建一个新的子类,导致类的数量呈指数级增长。
使用桥接模式的情况:
现在,我们使用桥接模式来解决这个问题:
// 使用桥接模式的代码
interface Color {
void applyColor();
}
class Red implements Color {
@Override
public void applyColor() {
System.out.println("Applying red color");
}
}
class Green implements Color {
@Override
public void applyColor() {
System.out.println("Applying green color");
}
}
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);
}
@Override
void draw() {
System.out.print("Drawing circle: ");
color.applyColor();
}
}
class Rectangle extends Shape {
public Rectangle(Color color) {
super(color);
}
@Override
void draw() {
System.out.print("Drawing rectangle: ");
color.applyColor();
}
}
// 客户端代码
public class WithBridgePatternExample {
public static void main(String[] args) {
Shape redCircle = new Circle(new Red());
redCircle.draw(); // Drawing circle: Applying red color
Shape greenRectangle = new Rectangle(new Green());
greenRectangle.draw(); // Drawing rectangle: Applying green color
}
}
在这个例子中,通过使用桥接模式,我们将形状(Circle
和 Rectangle
)和颜色(Red
和 Green
)分离开来。这样,每个维度的变化都可以独立进行扩展,而不需要创建大量的子类。如果需要新增一种颜色或形状,只需添加相应的类即可,不会导致类的爆炸。桥接模式使得系统更加灵活,易于扩展和维护。
比如新增一个颜色后的代码
假设我们要新增一种颜色,比如蓝色(Blue),我们只需添加一个实现Color
接口的Blue
类,并在客户端中创建一个新的Shape
对象,将这个新的颜色传递给它。
// 新增的蓝色类
class Blue implements Color {
@Override
public void applyColor() {
System.out.println("Applying blue color");
}
}
// 在客户端中使用新增的蓝色
public class AddNewColorExample {
public static void main(String[] args) {
Shape blueCircle = new Circle(new Blue());
blueCircle.draw(); // Drawing circle: Applying blue color
}
}
这里我们无需修改之前的形状类(Circle
)或其他颜色类,而是通过新增一个实现Color
接口的类来添加新的颜色。这就是桥接模式的灵活性体现之处。新增一个颜色并不会影响到其他部分的代码,保持了系统的可扩展性。