【设计模式】桥接模式

概述

    之前学习的适配器模式一般常用在开发中后期,这里的桥接模式一般用在开发前期设计系统框架时。属于结构型模式,用抽象关联取代了传统的多层继承,将类之间的静态继承关系转换为动态的对象组合关系,使得系统更加灵活,并易于扩展,同时有效控制了系统中类的个数。
模式定义:
将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。
UML类图:
在这里插入图片描述
桥接模式包含的角色
    Abstraction:抽象类,其中定义了一个Implermentor(实现类)的对象并维护该对象,它与Implementor之间具有关联关系,它既可以包含抽象业务方法,也可以包含具体业务方法。
    RefinedAbstraction:扩充抽象类,实现Abstraction中的抽象方法。
    Implementor:实现类接口。
    ConcreteImplementor:具体的实现类接口,实现不同的操作方法。

代码体现:

//实现将不同类型的数据库中的数据转换成各种格式(txt,pdf...)

//抽象类
class sqlAbstraction
{
public:
    sqlAbstraction(Implementor* imp)
    {
        pImp = imp;
    }
    virtual void turnStyle() = 0;
private:
    Implementor* pImp;
};
//扩充抽象类(Mysql数据库)
class mysqlAbstraction : public sqlAbstraction
{
public:
    mysqlAbstraction(Implementor* imp)
    {
        pImp = imp;
    }
    void turnStyle()
    {
        cout<<"做了一些操作拿到了MySQL的数据"<<endl;
        //转换数据格式,转成什么格式取决于传入的实现类对象是什么
        pImp->turnMe();
    }
private:
    Implementor* pImp;
};
//扩充抽象类(Redis数据库)
class redisAbstraction : public sqlAbstraction
{
public:
    redisAbstraction(Implementor* imp)
    {
        pImp = imp;
    }
    void turnStyle()
    {
        cout<<"做了一些操作拿到了Redis的数据"<<endl;
        //转换数据格式,转成什么格式取决于传入的实现类对象是什么
        pImp->turnMe();
    }
private:
    Implementor* pImp;
};
//实现类接口
class Implementor
{
public:
    virtual void turnMe()=0;
};
//具体的实现类(txt格式)
class txtImplementor
{
public:
    void turnMe()
    {
        cout << "转换成txt格式"<<endl;
    }
};
//具体的实现类(pdf格式)
class txtImplementor
{
public:
    void turnMe()
    {
        cout << "转换成pdf格式"<<endl;
    }
};
//使用
int main()
{
    //要把MySQL数据转换成txt格式
    Implementor* imp = new txtImplementor();
    Abstraction* mysqlAbstraction = new mysqlAbstraction(imp);
    mysqlAbstraction->turnStyle();
    //MySQL数据库数据转换成pdf格式
    Implementor* imp1 = new pdfImplementor();
    Abstraction* mysqlAbstraction1 = new mysqlAbstraction(imp);
    mysqlAbstraction1->turnStyle();
    //Redis数据库数据转换成txt格式
    Implementor* imp2 = new txtImplementor();
    Abstraction* redisAbstraction = new redisAbstraction(imp);
    redisAbstraction->turnStyle();
    //Redis数据库数据转换成pdf格式
    Implementor* imp3 = new pdfImplementor();
    Abstraction* redisAbstraction1 = new redisAbstraction(imp);
    redisAbstraction1->turnStyle();
    return 0;
}

优缺点及适用场景
优点:
    1.分离抽象接口及其实现部分。让他们的子类排列组合从而获得多维度组合对象。
    2.在很多情况下,桥接模式可以取代多层继承方案,多层继承方案违背了“单一职责原则”,复用性较差,且类的个数非常多,桥接模式是比多层继承方案更好的解决方法,它极大减少了子类的个数。
    3.桥接模式提高了系统的可扩展性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统,符合“开闭原则”。

缺点:
    1.桥接模式的使用会增加系统的理解与设计难度,由于关联关系建立在抽象层,要求开发者一开始就针对抽象层进行设计与编程。
    2.桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性,如何正确识别两个独立维度也需要一定的经验积累。

适用场景:
    1.如果一个系统需要在抽象化和具体化之间增加更多的灵活性,避免在两个层次之间建立静态的继承关系,通过桥接模式可以使它们在抽象层建立一个关联关系。
     2.“抽象部分”和“实现部分”可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。
    3.一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展。
    4.对于那些不希望使用继承或因为多层继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
参考:https://blog.csdn.net/lovelion/article/details/7464208
ps:分享一个画UML类图的工具:https://www.processon.com/

<think>好的,用户想了解桥接设计模式的概念、实现、使用场景和示例。我需要先回忆一下桥接模式的基本知识,然后结合提供的引用内容来组织回答。 首先,桥接模式属于结构型设计模式,主要目的是将抽象部分与其实现部分分离,使它们可以独立变化。根据引用[^1],桥接模式适用于需要多维度变化的场景,比如不同的系统平台和不同的视频格式组合。我需要解释清楚这种分离的好处,比如提高扩展性,避免类爆炸。 接下来是概念部分。桥接模式通过组合代替继承,这样抽象层和实现层可以独立扩展。引用[^3]中的例子提到DrawingAPI接口作为实现部分,Shape作为抽象部分,这可以帮助说明结构。需要明确抽象化和实现化的定义,以及它们如何通过组合连接。 然后是实现步骤。根据引用[^1]的示例,抽象部分如视频格式和系统平台,具体实现如FLV、MP4和Linux、Android。步骤应包括定义抽象类、扩充抽象类、实现接口和具体实现类。代码示例可能来自引用[^2]或[^3],比如跨平台图像浏览系统,但用户提供的引用中有视频格式和系统平台的例子,应该用这个更贴切。 使用场景部分,引用提到桥接模式适用于多个维度的变化,比如不同平台和文件格式。需要列举类似的情况,如不同数据库和操作系统,或者不同通知类型和发送方式。这部分需要强调两个独立变化的维度,以及避免多层继承的问题。 优缺点方面,优点包括解耦、扩展性好,缺点可能增加系统复杂性。引用的优缺点部分可能有帮助,但用户提供的引用中没有详细说明,需要根据一般知识补充。 最后生成相关问题,需要围绕桥接模式的应用、与其他模式的区别、实际案例等。参考用户之前的示例问题,可以问如何选择桥接模式与其他模式,或者具体实现中的注意事项。 需要确保回答结构清晰,分点说明,并正确引用提供的资料。例如,在代码示例部分引用中的视频格式和系统平台实现,以及引用中的DrawingAPI示例。同时注意使用中文,数学公式用$...$,但这个问题中可能用不到数学公式,但还是要检查是否有需要的地方。 现在组织回答的结构:概念、实现步骤、使用场景、示例代码、优缺点,最后相关问题。确保每个部分都有引用支持,比如概念部分引用和,示例部分引用和。可能需要将引用内容自然地融入回答中,例如在提到示例时标注引用来源。</think>### 桥接设计模式详解 #### 一、概念 桥接模式(Bridge Pattern)是一种**结构型设计模式**,其核心思想是将**抽象部分**与**实现部分**分离,使两者能独立变化。通过组合关系替代继承关系,避免多层继承导致的类爆炸问题。 - **抽象化(Abstraction)**:定义高层控制逻辑,依赖实现部分的对象。 - **实现化(Implementor)**:定义底层具体操作的接口,供抽象部分调用。 例如,视频播放器需要支持不同格式(如FLV、MP4)和不同系统平台(如Linux、Android)。桥接模式可将格式抽象与平台实现解耦,避免为每个组合创建独立类[^1]。 --- #### 二、实现步骤 1. **定义实现化接口**:声明底层操作(如系统平台的文件读取接口)。 2. **实现具体实现类**:针对不同平台(如Linux、Android)提供接口的具体实现。 3. **定义抽象化类**:包含对实现化接口的引用,定义高层逻辑(如视频格式解析)。 4. **扩展抽象化类**:细化抽象逻辑(如针对FLV、MP4格式的解析逻辑)。 **代码示例**(基于视频格式与系统平台的场景): ```java // 1. 实现化接口:系统平台 interface SystemPlatform { void playVideo(String format); } // 2. 具体实现类:Linux平台 class LinuxPlatform implements SystemPlatform { public void playVideo(String format) { System.out.println("Linux播放" + format + "视频"); } } // 3. 抽象化类:视频格式抽象 abstract class VideoFormat { protected SystemPlatform platform; public VideoFormat(SystemPlatform platform) { this.platform = platform; } abstract void parse(); } // 4. 扩展抽象化类:FLV格式 class FLVFormat extends VideoFormat { public FLVFormat(SystemPlatform platform) { super(platform); } public void parse() { platform.playVideo("FLV"); } } ``` --- #### 三、使用场景 1. **多维度变化**:如同时支持不同文件格式和不同操作系统。 2. **避免继承层级过深**:当子类可能因组合关系爆炸时(如$M \times N$个组合)。 3. **运行时切换实现**:例如动态更换数据库驱动或图形渲染API。 --- #### 四、优缺点 - **优点** - 解耦抽象与实现,提高扩展性 - 符合开闭原则,新增维度无需修改原有代码 - **缺点** - 增加系统复杂度,需预先设计抽象层次 --- #### 五、与其他模式的关系 - **与适配器模式**:适配器用于兼容已有接口,桥接模式用于设计阶段解耦[^2]。 - **与抽象工厂模式**:抽象工厂可配合桥接模式创建不同实现的对象[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值