C++ 设计模式之桥接模式

发布时间:2024年01月16日

【声明】本题目来源于卡码网(题目页面 (kamacoder.com)

【提示:如果不想看文字介绍,可以直接跳转到C++编码部分】


【简介】什么是桥接模式

????????桥接模式(Bridge Pattern)是?种结构型设计模式,它的UML图很像?座桥,它通过将【抽象部分】与【实现部分】分离,使它们可以独?变化,从?达到降低系统耦合度的?的。桥接模式的主要?的是通过组合建?两个类之间的联系,?不是继承的?式。
????????举个简单的例?,图形编辑器中,每?种图形都需要蓝?、红?、??不同的颜?,如果不使?桥接模式,可能需要为每?种图形类型和每?种颜?都创建?个具体的?类,?使?桥接模式可以将图形和颜?两个维度分离,两个维度都可以独?进?变化和扩展,如果要新增其他颜?,只需添加新的 Color ?类,不影响图形类;反之亦然。


【基本结构】

桥接模式的基本结构分为以下?个??:

  • 抽象Abstraction :?般是抽象类,定义抽象部分的接?,维护?个对【实现】的引?。
  • 修正抽象RefinedAbstaction :对抽象接?进?扩展,通常对抽象化的不同维度进?变化或定制。
  • 实现Implementor : 定义实现部分的接?,提供具体的实现。这个接?通常是抽象化接?的实现。
  • 具体实现ConcreteImplementor :实现实现化接?的具体类。这些类负责实现实现化接?定义的具体操作。

?

?????????再举个例?,遥控器就是抽象接?,它具有开关电视的功能,修正抽象就是遥控器的实例,对遥控器的功能进?实现和扩展,?电视就是实现接?,具体品牌的电视机是具体实现,遥控器中包含?个对电视接?的引?,通过这种?式,遥控器和电视的实现被分离,我们可以创建多个遥控器,每个遥控器控制?个品牌的电视机,它们之间独?操作,不受电视品牌的影响,可以独?变化。


【简易实现】

????????下?是实现桥接模式的基本步骤:(以Java代码作以说明)

1. 创建实现接口

interface Implementation {
    void operationImpl();
}

2. 创建具体实现类:实际提供服务的对象

class ConcreteImplementationA implements Implementation {
    @Override
    public void operationImpl() {
        // 具体实现A
    }
}
class ConcreteImplementationB implements Implementation {
    @Override
    public void operationImpl() {
        // 具体实现B
    }
}

3.?创建抽象接?:包含?个对实现化接?的引?。

public abstract class Abstraction {
    protected IImplementor mImplementor;

    public Abstraction(IImplementor implementor) {
        this.mImplementor = implementor;
    } 
   
    public void operation() {
        this.mImplementor.operationImpl();
    }
}

4. 实现抽象接?,创建RefinedAbstaction 类

class RefinedAbstraction implements Abstraction {
    private Implementation implementation;

    public RefinedAbstraction(Implementation implementation) {
        this.implementation = implementation;
    }

    @Override
    public void operation() {
        // 委托给实现部分的具体类
        implementation.operationImpl();
    }
}

5. 客户端使?

// 客户端代码
public class Main {
    public static void main(String[] args) {
    // 创建具体实现化对象
    Implementation implementationA = new ConcreteImplementationA();
    Implementation implementationB = new ConcreteImplementationB();
    // 使?扩充抽象化对象,将实现化对象传递进去
    Abstraction abstractionA = new RefinedAbstraction(implementationA);
    Abstraction abstractionB = new RefinedAbstraction(implementationB);
    // 调?抽象化的操作
    abstractionA.operation();
    abstractionB.operation();
    }
}

【使用场景】

?????????桥接模式在?常开发中使?的并不是特别多,通常在以下情况下使?:

  • 当?个类存在两个独?变化的维度,?且这两个维度都需要进?扩展时,使?桥接模式可以使它们独?变化,减少耦合。
  • 不希望使?继承,或继承导致类爆炸性增?

????????总体??,桥接模式适?于那些有多个独?变化维度、需要灵活扩展的系统


【编码部分】

1. 题目描述

????????小明家有一个万能遥控器,能够支持多个品牌的电视。每个电视可以执行开机、关机和切换频道的操作,请你使用桥接模式模拟这个操作。

2. 输入描述

????????第一行是一个整数 N(1 <= N <= 100),表示后面有 N 行输入。接下来的 N 行,每行包含两个数字。第一个数字表示创建某个品牌的遥控和电视,第二个数字表示执行的操作。其中,0 表示创建 Sony 品牌的电视,1 表示创建 TCL 品牌的遥控和电视;2 表示开启电视、3表示关闭电视,4表示切换频道。????????

3. 输出描述

????????对于每个操作,输出相应的执行结果。

4. C++编码实例

/**
* @version Copyright (c) 2024 NCDC, Servo。 Unpublished - All rights reserved
* @file BridgeMode.hpp
* @brief 桥接模式
* @autor 写代码的小恐龙er
* @date 2024/01/11
*/

#include <iostream>
#include <string>

using namespace std;

// 前置声明
// 实现化接口
class TV;
// ======== 第一个维度的扩充 ========

// 具体实现类1 -- Sony Tv
class SonyTv;
// 具体实现类2 -- TCL Tv
class TclTv;

// ----------------------------------

// 抽象化接口
class RemoteControl;
// ======== 第二个维度的扩充 ========

// 实现抽象化接口 -- 开机
class TurnOn;
// 实现抽象化接口 -- 关机
class TurnOff;
// 实现抽象化接口 -- 切换频道
class SwitchChannel;


// 实现化接口
class TV
{
    // 接口函数
public:
    virtual void TurnOnTV() = 0;
    virtual void TurnOffTV() = 0;
    virtual void SwitchTVChannel() = 0;
};

// 具体实现类1 -- Sony Tv
class SonyTv : public TV
{
 public:
 // 重载接口函数
    void TurnOnTV(){
        std::cout << "Sony TV is ON" << endl;
    }
    void TurnOffTV(){
        std::cout << "Sony TV is OFF" << endl;
    }
    void SwitchTVChannel(){
        std::cout << "Switching Sony TV channel" << endl;
    }
};

// 具体实现类2 -- TCL Tv
class TclTv : public TV
{
public:
 // 重载接口函数
    void TurnOnTV(){
        std::cout << "TCL TV is ON" << endl;
    }
    void TurnOffTV(){
        std::cout << "TCL TV is OFF" << endl;
    }
    void SwitchTVChannel(){
        std::cout << "Switching TCL TV channel" << endl;
    }
};


// 抽象化接口
class RemoteControl
{
// 抽象化接口类持有实现化接口类的实例
protected:
    TV *_tv;

public:
    // 重载构造函数
    RemoteControl(){}
    RemoteControl(TV *tv){
        this->_tv = tv;
    }
    
    // 提供抽象类接口函数
    virtual void OperationMode() = 0;
};

// 实现抽象化接口 -- 开机
class TurnOn : public RemoteControl
{
private:
    // 实现抽象接口类持有实现化接口类的实例
    TV *_tv;
    
public:
    // 重载构造函数 以便后续调用能传入抽象类
    TurnOn(TV *tv){
        this->_tv = tv;
    }
    
    // 重载抽象类接口函数
    void OperationMode() override {
        this->_tv->TurnOnTV();
    }
    
};
// 实现抽象化接口 -- 关机
class TurnOff : public RemoteControl
{
private:
    // 实现抽象接口类持有实现化接口类的实例
    TV *_tv;
    
public:
    // 重载构造函数 以便后续调用能传入抽象类
    TurnOff(TV *tv){
        this->_tv = tv;
    }
    
    // 重载抽象类接口函数
    void OperationMode() override {
        this->_tv->TurnOffTV();
    }
};

// 实现抽象化接口 -- 切换频道
class SwitchChannel : public RemoteControl
{
private:
    // 实现抽象接口类持有实现化接口类的实例
    TV *_tv;
    
public:
    // 重载构造函数 以便后续调用能传入抽象类
    SwitchChannel(TV *tv){
        this->_tv = tv;
    }
    
    // 重载抽象类接口函数
    void OperationMode() override {
        this->_tv->SwitchTVChannel();
    }    
    
};

int main()
{
   // 执行操作的数量
   int operationNum = 0;
   // 输入
   std::cin >> operationNum;
   // 创建实现化接口
   TV *tv = nullptr;
   RemoteControl *control = nullptr;
   // 遍历输入
   for(int i = 0; i < operationNum; i++)
   {
       // 电视机类型
       int tvType = -1;
       // 遥控器操作类型
       int controlType = -1;
       // 输入
       std:: cin >> tvType >> controlType;
       
       // 电视机类型
       if(!tvType){
           tv = new SonyTv();
       }
       else if(tvType == 1){
           tv = new TclTv();
       }
       else tv = nullptr;
       
       // 若输入指令错误则直接返回
       if(tv == nullptr) return 0;
       
       // 遥控器操作类型
       if(controlType == 2){
           control = new TurnOn(tv);
       }
       else if(controlType == 3){
           control = new TurnOff(tv);
       }
       else if(controlType == 4){
           control = new SwitchChannel(tv);
       }
       else control = nullptr;
       
       // 若输入指令错误则直接返回
       if(control == nullptr) return 0;
       
       // 执行操作
       control->OperationMode();
   }
    
    delete tv;
    tv = nullptr;
    delete control;
    control = nullptr;
    
    return 0;
}


......

To be continued.

文章来源:https://blog.csdn.net/K1_uestc/article/details/135538679
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。