热门问题
时间线
聊天
视角

橋接模式

来自维基百科,自由的百科全书

橋接模式
Remove ads

橋接模式軟件設計模式中最複雜的模式之一,它把事物對象和其具體行爲、具體特徵分離開來,使它們可以各自獨立的變化。

Thumb
橋接模式的UML類圖

概述

事物對象僅是一個抽象的概念,如「圓形」、「三角形」歸於抽象的「形狀」之下,而「畫圓」、「畫三角」歸於實現行爲的「畫圖」類之下,然後將事物對象與其行爲橋接起來,即由「形狀」調用「畫圖」,例如:「圓形」調用「畫圓」,而「三角形」調用「畫三角」。

結構

Thumb
橋接模式的樣例UML類圖和序列圖[1]
Abstraction
定義抽象的介面
該介面包含實現具體行爲、具體特徵的Implementor介面
Refined Abstraction
抽象介面Abstraction的子類,依舊是一個抽象的事物名
Implementor
定義具體行爲、具體特徵的應用介面
ConcreteImplementor
實現Implementor介面

示例

下列各語言的代碼都用於寫出兩個不同的圓的坐標和半徑。

C++

下面是C++的例子:

#include <iostream>
using namespace std;

/* Implementor*/
class DrawingAPI {
public:
    virtual void drawCircle(double x, double y, double radius) = 0;
    virtual ~DrawingAPI() {}
};

/* Concrete ImplementorA*/
class DrawingAPI1 : public DrawingAPI {
public:
    void drawCircle(double x, double y, double radius) {
        cout << "API1.circle at " << x << ':' << y << ' ' << radius << endl;
    }
};

/* Concrete ImplementorB*/
class DrawingAPI2 : public DrawingAPI {
public:
    void drawCircle(double x, double y, double radius) {
        cout << "API2.circle at " << x << ':' << y << ' ' <<  radius << endl;
    }
};

/* Abstraction*/
class Shape {
public:
    virtual ~Shape() {}
    virtual void draw() = 0;
    virtual void resizeByPercentage(double pct) = 0;
};

/* Refined Abstraction*/
class CircleShape : public Shape {
public:
    CircleShape(double x, double y,double radius, DrawingAPI *drawingAPI) :
	    m_x(x), m_y(y), m_radius(radius), m_drawingAPI(drawingAPI) {}
    void draw() {
        m_drawingAPI->drawCircle(m_x, m_y, m_radius);
    }
    void resizeByPercentage(double pct) {
        m_radius *= pct;
    }
private:
    double m_x, m_y, m_radius;
    DrawingAPI *m_drawingAPI;
};

int main(void)
{
    DrawingAPI1 dap1;
    DrawingAPI2 dap2;
    CircleShape circle1(1,2,3,&dap1);
    CircleShape circle2(5,7,11,&dap2);
    circle1.resizeByPercentage(2.5);
    circle2.resizeByPercentage(2.5);
    circle1.draw();
    circle2.draw();
    return 0;
}
Remove ads

Java

下面是Java的例子:

/** "Implementor" */
interface DrawingAPI {
     public void drawCircle(double x, double y, double radius);
}

/** "ConcreteImplementor" 1/2 */
class DrawingAPI1 implements DrawingAPI {
     public void drawCircle(double x, double y, double radius) {
         System.out.printf("API1.circle at %f:%f radius %f\n", x, y, radius);
    }
}

/** "ConcreteImplementor" 2/2 */
class DrawingAPI2 implements DrawingAPI {
    public void drawCircle(double x, double y, double radius) { 
        System.out.printf("API2.circle at %f:%f radius %f\n", x, y, radius);
    }
}

/** "Abstraction" */
interface Shape {
    public void draw();                             // low-level
    public void resizeByPercentage(double pct);     // high-level
}

/** "Refined Abstraction" */
class CircleShape implements Shape {
    private double x, y, radius;
    private DrawingAPI drawingAPI;
    public CircleShape(double x, double y, double radius, DrawingAPI drawingAPI) {
        this.x = x;  this.y = y;  this.radius = radius; 
        this.drawingAPI = drawingAPI;
    }

    // low-level i.e. Implementation specific
    public void draw() {
        drawingAPI.drawCircle(x, y, radius);
    }   
    // high-level i.e. Abstraction specific
    public void resizeByPercentage(double pct) {
        radius *= pct;
    }
}

/** "Client" */
class BridgePattern {
    public static void main(String[] args) {
        Shape[] shapes = new Shape[2];
        shapes[0] = new CircleShape(1, 2, 3, new DrawingAPI1());
        shapes[1] = new CircleShape(5, 7, 11, new DrawingAPI2());

        for (Shape shape : shapes) {
            shape.resizeByPercentage(2.5);
            shape.draw();
        }
    }
}
Remove ads

C#

在下面的C#例子中,泛型形式的CircleShape<T>,通過T來接受接口IDrawingAPIstruct形式的繼承者。

using System;
 
/** "Implementor" */
interface IDrawingAPI {
    void DrawCircle(double x, double y, double radius);
}
 
/** "ConcreteImplementor" 1/2 */
struct DrawingAPI1 : IDrawingAPI {
    public void DrawCircle(double x, double y, double radius) {
        System.Console.WriteLine("API1.circle at {0}:{1} radius {2}", x, y, radius); 
    }
}
 
/** "ConcreteImplementor" 2/2 */
struct DrawingAPI2 : IDrawingAPI {
    public void DrawCircle(double x, double y, double radius) { 
        System.Console.WriteLine("API2.circle at {0}:{1} radius {2}", x, y, radius); 
    }
}
 
 /** "Abstraction" */
interface IShape {
    void Draw();                             // low-level (i.e. Implementation-specific)
    void ResizeByPercentage(double pct);     // high-level (i.e. Abstraction-specific)
}
 
/** "Refined Abstraction" */
class CircleShape<T> : IShape
    where T : struct, IDrawingAPI {
    private double x, y, radius;
    private static IDrawingAPI drawingAPI = new T();
    public CircleShape(double x, double y, double radius) {
        this.x = x;  this.y = y;  this.radius = radius;
    }
    // low-level (i.e. Implementation-specific)
    public void Draw() { drawingAPI.DrawCircle(x, y, radius); }
    // high-level (i.e. Abstraction-specific)
    public void ResizeByPercentage(double pct) { radius *= pct; }
}
 
/** "Client" */
class BridgePattern {
    public static void Main(string[] args) {
        IShape[] shapes = new IShape[2];
        shapes[0] = new CircleShape<DrawingAPI1>(1, 2, 3);
        shapes[1] = new CircleShape<DrawingAPI2>(5, 7, 11);
 
        foreach (IShape shape in shapes) {
            shape.ResizeByPercentage(2.5);
            shape.Draw();
        }
    }
}
Remove ads
Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.

Remove ads