zoukankan      html  css  js  c++  java
  • 结构型模式之 桥接模式

    桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。

    设想如果要绘制矩形、圆形、椭圆、正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色、绿色、蓝色等,此时至少有如下两种设计方案:

    • 第一种设计方案是为每一种形状都提供一套各种颜色的版本。
    • 第二种设计方案是根据实际需要对形状和颜色进行组合

    对于有两个变化维度(即两个变化的原因)的系统,采用方案二来进行设计系统中类的个数更少,且系统扩展更为方便。设计方案二即是桥接模式的应用。桥接模式将继承关系转换为关联关系,从而降低了类与类之间的耦合,减少了代码编写量。

    优点: 1、抽象和实现的分离。 2、优秀的扩展能力。 3、实现细节对客户透明。

    缺点:桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。

    使用场景: 1、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。 2、对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。 3、一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。

    注意事项:对于两个独立变化的维度,使用桥接模式再适合不过了。

    //步骤 1 创建桥接实现接口
    class DrawAPI 
    {
    public:
        virtual void drawCirle(int radius, int x, int y) { }
        DrawAPI() {}
        ~DrawAPI() {}
        DrawAPI& operator=(const DrawAPI& e) 
        {
        }
    };
    
    //步骤 2 创建实现了 DrawAPI 接口的实体桥接实现类
    class RedCircle : public DrawAPI
    {
    public:
        int flag;
        RedCircle() { flag = 1; }
        ~RedCircle() {}
        void drawCirle(int radius, int x, int y)
        {
            cout << "Drawing Circle color: red, radius: " << radius << ", x: " << x << ", " << y << endl;
        }
    private:
    };
    class GreenCircle : public DrawAPI
    {
    public:
        int flag;
        GreenCircle() { flag = 2; }
        ~GreenCircle() {}
        void drawCirle(int radius, int x, int y)
        {
            cout << "Drawing Circle color: green, radius: " << radius << ", x: " << x << ", " << y << endl;
        }
    private:
    };
    //步骤 3 使用 DrawAPI 接口创建抽象类 Shape
    class Shape {
    public:
        DrawAPI* drawAPI;
        virtual void draw() { }
    
        Shape() { drawAPI = NULL; }
        ~Shape() {}
    };
    
    //步骤 4 创建实现了 Shape 接口的实体类
    class Circle :public Shape {
    private:
        int x, y, radius;
    
    public:
        Circle() {}
        Circle(int x, int y, int radius, DrawAPI* drawapit) {
            drawAPI = drawapit;
            x = x;
            y = y;
            radius = radius;
        }
        void draw() {
            drawAPI->drawCirle(radius,x,y);
        }
    };
    
    int main() 
    {
    
        GreenCircle greencircle;
        Circle c1(100, 100, 10, &greencircle);
        Shape* shape1 = &c1;
        RedCircle redcircle;
        Circle c2(100, 100, 10, &redcircle);
        Shape* shape2 = &c2;
    
        shape1->draw();
        shape2->draw();
    
        return 0;
    }
  • 相关阅读:
    读取文本文件中的中文打印到Eclipse控制台为何显示问号
    使用StringUtils需要引用的依賴
    Ajax跨域访问XML数据的另一种方式——使用YQL查询语句
    AngularJS快速入门指南15:API
    国外社交网站获取分享数量APIs
    AngularJS快速入门指南14:数据验证
    AngularJS快速入门指南13:表单
    AngularJS快速入门指南12:模块
    AngularJS快速入门指南11:事件
    AngularJS快速入门指南10:DOM节点
  • 原文地址:https://www.cnblogs.com/gardenofhu/p/8494151.html
Copyright © 2011-2022 走看看