Skip to content

桥接模式

将抽象部分与实现部分分离,使它们都可以独立地变化。

适合的场景

有时候你会遇到这样的问题:

  • 有多个抽象层(比如不同图形形状)

  • 有多种实现方式(比如不同渲染API)

  • 如果用继承,类会爆炸式增长(组合爆炸)

  • 希望抽象和实现能独立演进,不互相影响

桥接模式帮你拆分这两者,类的个数不会疯狂暴涨,维护更灵活

“抽象和实现分家住,随时换搭配,灵活又优雅!”

基本结构

  1. 抽象类(Abstraction):持有一个实现接口的引用,定义高层操作。

  2. 实现接口(Implementor):定义具体实现方法。

  3. 具体实现(ConcreteImplementor):实现实现接口。

  4. 扩展抽象(RefinedAbstraction):继承抽象类,扩展行为。

示例

csharp
// 实现接口
public interface IRenderer
{
    void RenderCircle(float x, float y, float radius);
}

// 具体实现A
public class OpenGLRenderer : IRenderer
{
    public void RenderCircle(float x, float y, float radius)
    {
        Console.WriteLine($"OpenGL渲染圆形,坐标({x},{y}), 半径{radius}");
    }
}

// 具体实现B
public class DirectXRenderer : IRenderer
{
    public void RenderCircle(float x, float y, float radius)
    {
        Console.WriteLine($"DirectX渲染圆形,坐标({x},{y}), 半径{radius}");
    }
}

// 抽象部分
public abstract class Shape
{
    protected IRenderer renderer;

    protected Shape(IRenderer renderer)
    {
        this.renderer = renderer;
    }

    public abstract void Draw();
}

// 扩展抽象
public class Circle : Shape
{
    private float x, y, radius;

    public Circle(float x, float y, float radius, IRenderer renderer) : base(renderer)
    {
        this.x = x;
        this.y = y;
        this.radius = radius;
    }

    public override void Draw()
    {
        renderer.RenderCircle(x, y, radius);
    }
}

// 使用
IRenderer renderer = new OpenGLRenderer();
Shape circle = new Circle(10, 20, 5, renderer);
circle.Draw();

renderer = new DirectXRenderer();
circle = new Circle(15, 25, 10, renderer);
circle.Draw();

GDScript示例

gdscript
# 实现接口
class Renderer:

    func render_circle(x: float, y: float, radius: float) -> void:
        pass

# 具体实现A
class OpenGLRenderer extends Renderer:
    func render_circle(x: float, y: float, radius: float) -> void:
        print("OpenGL渲染圆形,坐标(%f, %f),半径%f" % [x, y, radius])

# 具体实现B
class DirectXRenderer extends Renderer:
    func render_circle(x: float, y: float, radius: float) -> void:
        print("DirectX渲染圆形,坐标(%f, %f),半径%f" % [x, y, radius])

# 抽象类
class Shape:

    var renderer: Renderer

    func _init(renderer: Renderer) -> void:
        self.renderer = renderer

    func draw() -> void:
        pass

# 扩展抽象
class Circle extends Shape:
    var x: float
    var y: float
    var radius: float

    func _init(x: float, y: float, radius: float, renderer: Renderer) -> void:
            self.x = x
            self.y = y
            self.radius = radius
            self.renderer = renderer

    func draw() -> void:
        renderer.render_circle(x, y, radius)

# 使用
func _ready():
    var renderer = OpenGLRenderer.new()
    var circle = Circle.new(10, 20, 5, renderer)
    circle.draw()
    
    renderer = DirectXRenderer.new()
    circle = Circle.new(15, 25, 10, renderer)
    circle.draw()