假设绘图软件支持多种图形(如圆形、矩形)和多种绘图工具(如普通画笔、喷枪)。桥接模式可以很好地将图形和绘图工具解耦,使得两者可以独立变化。
1. 定义实现接口(绘图工具)
public interface DrawingTool {
void draw(String shape);
}
1.1 实现具体绘图工具(普通画笔、喷枪)
public class PencilTool implements DrawingTool {
@Override
public void draw(String shape) {
System.out.println("使用普通画笔绘制: " + shape);
}
}
public class SprayTool implements DrawingTool {
@Override
public void draw(String shape) {
System.out.println("使用喷枪绘制: " + shape);
}
}
2. 定义抽象类(图形)
public abstract class Shape {
protected DrawingTool drawingTool;
public void setDrawingTool(DrawingTool drawingTool) {
this.drawingTool = drawingTool;
}
public abstract void draw();
}
2.1 实现具体图形(圆形、矩形)
public class Circle extends Shape {
@Override
public void draw() {
drawingTool.draw("圆形");
}
}
public class Rectangle extends Shape {
@Override
public void draw() {
drawingTool.draw("矩形");
}
}
3. 客户端代码
public class Main {
public static void main(String[] args) {
// 创建普通画笔工具
DrawingTool pencilTool = new PencilTool();
// 创建喷枪工具
DrawingTool sprayTool = new SprayTool();
// 创建圆形
Shape circle = new Circle();
circle.setDrawingTool(pencilTool);
circle.draw(); // 使用普通画笔绘制圆形
// 创建矩形
Shape rectangle = new Rectangle();
rectangle.setDrawingTool(sprayTool);
rectangle.draw(); // 使用喷枪绘制矩形
}
}
4. 输出结果
运行客户端代码,输出结果如下:
使用普通画笔绘制: 圆形
使用喷枪绘制: 矩形
5. 桥接模式的优点
- 分离抽象和实现:图形的抽象接口与绘图工具的具体实现分离,使得两者可以独立变化。
- 扩展性好:可以独立地添加新的图形或新的绘图工具,而无需修改现有代码。
- 减少子类数量:通过组合关系代替继承关系,减少了子类的数量,降低了系统的复杂度。
6. 适用场景
桥接模式适用于以下场景:
- 当一个类存在两个独立变化的维度时,一个维度是抽象部分,另一个维度是实现部分。
- 当需要对一个已有类进行扩展,但又不想使用继承时。
- 当需要在运行时动态地切换实现时。
通过桥接模式,可以清晰地分离图形的抽象接口和绘图工具的具体实现,使得代码更加模块化、易于维护和扩展。
下面是一个使用桥接模式实现的绘图软件 Python 程序。桥接模式非常适合这种需要处理多种形状和多种颜色的场景,它可以将抽象的形状操作与具体的颜色实现分离,使它们可以独立变化。
from abc import ABC, abstractmethod
# 实现接口:颜色
class Color(ABC):
@abstractmethod
def fill(self):
pass
# 具体实现:红色
class Red(Color):
def fill(self):
return "红色"
# 具体实现:蓝色
class Blue(Color):
def fill(self):
return "蓝色"
# 具体实现:绿色
class Green(Color):
def fill(self):
return "绿色"
# 抽象接口:形状
class Shape(ABC):
def __init__(self, color):
self.color = color
@abstractmethod
def draw(self):
pass
# 扩展抽象:圆形
class Circle(Shape):
def draw(self):
return f"圆形被填充为{self.color.fill()}"
# 扩展抽象:矩形
class Rectangle(Shape):
def draw(self):
return f"矩形被填充为{self.color.fill()}"
# 扩展抽象:三角形
class Triangle(Shape):
def draw(self):
return f"三角形被填充为{self.color.fill()}"
# 客户端代码
if __name__ == "__main__":
# 创建不同颜色
red = Red()
blue = Blue()
green = Green()
# 创建不同形状并使用不同颜色填充
red_circle = Circle(red)
blue_rectangle = Rectangle(blue)
green_triangle = Triangle(green)
# 绘制形状
print(red_circle.draw())
print(blue_rectangle.draw())
print(green_triangle.draw())
# 动态切换颜色(桥接模式的优势)
print("\n=== 更换颜色 ===")
red_circle.color = blue
print(red_circle.draw())
blue_rectangle.color = green
print(blue_rectangle.draw())
green_triangle.color = red
print(green_triangle.draw())
# 扩展场景:添加新形状
class Square(Shape):
def draw(self):
return f"正方形被填充为{self.color.fill()}"
yellow = Green() # 假设我们添加了黄色,但这里复用了绿色实现
yellow_square = Square(yellow)
print("\n=== 扩展形状 ===")
print(yellow_square.draw())
# 扩展场景:添加新颜色
class Yellow(Color):
def fill(self):
return "黄色"
yellow = Yellow()
yellow_circle = Circle(yellow)
print("\n=== 扩展颜色 ===")
print(yellow_circle.draw())
这个实现中,我们定义了:
- 实现接口(Color):定义了填充颜色的接口,具体实现由不同颜色类完成。
- 具体实现(Red、Blue、Green、Yellow):实现了具体的颜色填充逻辑。
- 抽象接口(Shape):定义了形状的基本操作,维护一个指向颜色的引用。
- 扩展抽象(Circle、Rectangle、Triangle、Square):扩展了抽象接口,实现了不同形状的特定行为。
通过这种设计,我们可以轻松地添加新的形状(如正方形、椭圆形)或新的颜色(如黄色、紫色),而不需要修改现有的代码结构。客户端只需要关心抽象的形状接口和颜色接口,不需要了解具体的实现细节。
桥接模式的核心优势在于将抽象和实现分离,使它们可以独立变化。在这个绘图软件中,形状和颜色是两个独立的变化维度,通过桥接模式,我们可以灵活地组合不同的形状和颜色,实现了系统的可扩展性和可维护性。