当前位置:   article > 正文

【19】c++设计模式——>桥接模式_c++桥接模式

c++桥接模式

桥接模式的定义

C++的桥接模式(Bridge Pattern)是一种结构型设计模式,它将抽象部分与实现部分分离,使得它们可以独立地变化。桥接模式的核心思想是利用组合关系代替继承关系,将系统划分成多个独立的、功能不同的类层次结构,并通过桥接类将它们连接起来。
在桥接模式中,有两个重要的概念:抽象化(Abstraction)和实现化(Implementation),它们分别对应了系统的抽象部分和实现部分。抽象化负责定义接口,并维护一个指向实现化对象的指针;实现化则负责定义具体的实现方法。

使用场景

关于桥接模式的使用对应的场景有很多,比如:
1.空调、电视等和他们对应的遥控器:空调、电视机是抽象,遥控器是实现;
2.手机品牌和手机软件:手机品牌是抽象,手机软件是实现;
3.跨品台的GUI在不同平台上运行:程序的GUI层是抽象,操作系统API是实现。
4.假设我们正在开发一个图形绘制应用程序,支持多种图形和不同的绘制渲染方式。其中,图形包括圆形、矩形等,渲染方式包括使用直线绘制、使用虚线绘制等。这两个维度的变化都可能会在未来进行扩展和修改。
就是说将具体的图形和具体的渲染桥接在一起,实现图形和渲染方式之间的解耦,我们可以在客户端代码中使用桥接模式,通过实例化具体的图形对象和具体的渲染实现对象,将它们桥接在一起,并进行绘制:

#include <iostream>

// Abstract Render API
class RenderAPI {
public:
    virtual void renderCircle() = 0;         // 抽象的渲染圆形方法
    virtual void renderRectangle() = 0;      // 抽象的渲染矩形方法
};

// Concrete Line Renderer
class LineRenderer : public RenderAPI {
public:
    void renderCircle() override {
        std::cout << "Render Circle with lines." << std::endl;     // 使用线条渲染圆形
    }

    void renderRectangle() override {
        std::cout << "Render Rectangle with lines." << std::endl;  // 使用线条渲染矩形
    }
};

// Concrete Dashed Line Renderer
class DashedLineRenderer : public RenderAPI {
public:
    void renderCircle() override {
        std::cout << "Render Circle with dashed lines." << std::endl;    // 使用虚线渲染圆形
    }

    void renderRectangle() override {
        std::cout << "Render Rectangle with dashed lines." << std::endl; // 使用虚线渲染矩形
    }
};

// Abstract Shape
class Shape {
protected:
    RenderAPI* renderAPI;

public:
    Shape(RenderAPI* api) : renderAPI(api) {}

    virtual void draw() = 0;   // 抽象的绘制方法,具体的形状类将实现这个方法
};

// Concrete Circle
class Circle : public Shape {
public:
    Circle(RenderAPI* api) : Shape(api) {}

    void draw() override {
        renderAPI->renderCircle();   // 调用渲染API的渲染圆形方法来绘制圆形
    }
};

// Concrete Rectangle
class Rectangle : public Shape {
public:
    Rectangle(RenderAPI* api) : Shape(api) {}

    void draw() override {
        renderAPI->renderRectangle();   // 调用渲染API的渲染矩形方法来绘制矩形
    }
};

int main() {
    // 创建一个圆形对象,并设置使用线条渲染的渲染API
    Shape* circleShape = new Circle(new LineRenderer());
    // 创建一个矩形对象,并设置使用虚线渲染的渲染API
    Shape* rectangleShape = new Rectangle(new DashedLineRenderer());

    // 绘制圆形
    circleShape->draw();
    // 绘制矩形
    rectangleShape->draw();

    delete circleShape;
    delete rectangleShape;

    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80

海贼王实例

对于海贼王中来说,有海军,有海贼团,不论是海军还是海贼团,他们都有自己的船,海军的船叫军舰,海贼团的船叫海贼船,因此,我们需要将船和团队分开;
船+海贼团 -->海贼船
船+海军—>军舰
对于一个海贼团或者一支海军部队来说,光有船是不完整的,船只是这个团队的抽象,如果想要让它鲜活起来就必要要有由人组成的团队,也就是抽象的具体实现。所以,在这个抽象类中包含了一个团队对象,船和团队二者之间的关系可以看做是聚合关系。
我们以草帽海贼团和斯摩格海贼团为例:

#include <iostream>
#include<string>
#include<map>
using namespace std;

//不论是哪艘船上的船员肯定都是由一些个人的身份信息,为了将这些信息记录下来,先定一个存储数据的类:
//人员信息
struct Person
{
	Person(string name, string job, string ability, string reward, string beizhu=string())
	{
		this->name = name;
		this->job = job;
		this->ability = ability;
		this->reward = reward;
		this->beizhu = beizhu;
	}
	~Person()
	{
		cout << name << "被析构了..." << endl;
	}
	string name;     //姓名
	string job;      //工作
	string ability;  //能力
	string reward;   //赏金
	string beizhu;   //备注
};
//关于团队的成员组成可以是海贼,也可以是海军,所以先定义一个团队的抽象类
class AbstractTeam
{
public:
	AbstractTeam(string name):m_teamName(name) {}
	//获取团队姓名
	string getTeamName()
	{
		return m_teamName;
	}
	//给团队添加成员,用map保存,键是姓名,值是Person类
	void addMember(Person* p)
	{
		m_infoMap.insert(make_pair(p->name,p));
	}
	//打印成员信息
	void show()
	{
		cout << m_teamName << ":" << endl;
		//遍历map
		for(const auto & item:m_infoMap)
		{
			cout << "【Name: " << item.second->name
				<< ", Job: " << item.second->job
				<< ", Ability: " << item.second->ability
				<< ", MoneyReward: " << item.second->reward
				<< ", BeiZhu: " << item.second->beizhu
				<< "】" << endl;
		}
	}
	//执行任务函数,海军和海贼的任务不同,因此是纯虚函数,子类中重写
	virtual void executeTask() = 0;
	//虚析构函数,释放类时,将m_infoMap保存的团队所有成员都析构掉
	virtual ~AbstractTeam()
	{
		for (const auto& item : m_infoMap)
		{
			delete item.second;
		}
	}
protected:
	string m_teamName = string();
	//该团队的所有成员
	map<string, Person*> m_infoMap;
};
//具体的团队类,路飞的草帽海贼团和斯摩格的海军团
//草帽海贼团
class CaoMaoTeam :public AbstractTeam
{
public:
	using AbstractTeam::AbstractTeam;//继承基类的构造函数,而不用子类重新实现相同的构造函数
	void executeTask() override
	{
		cout << "在海上冒险,找到 ONE PIECE 成为海贼王!" << endl;
	}
};
//斯摩格海军团队
class SmokeTeam :public AbstractTeam
{
public:
	using AbstractTeam::AbstractTeam;
	void executeTask()override
	{
		cout << "为了正义,先将草帽一伙一网打尽!!!" << endl;
	}
};
//船类
/*不论是海军还是海贼在大海上航行都需要船,虽然他们驾驶的船只不同,
但是有很多属性还是一致的,所以我们可以先定义一个船的抽象类*/
class AbstructShip
{
public:
	AbstructShip(AbstractTeam* team) :m_team(team) {} //团队+船
	void showTeam()
	{
		m_team->show();
		m_team->executeTask();
	}
	virtual string getName() = 0;
	virtual void feature() = 0; //纯虚函数描述船的特点,在不同的子类中都需要重写
	virtual~AbstructShip() {}
protected:
	AbstractTeam* m_team = nullptr; //这里将团队和船绑定在一起了
};
//梅丽号
class Merry :public AbstructShip
{
public:
	using AbstructShip::AbstructShip;
	string getName() override
	{
		return string("前进梅丽号");
	}
	void feature()override
	{
		cout << getName() << "--船首为羊头,在司法岛化身船精灵舍己救下草帽一伙" << endl;
	}
};
//海军无敌战舰
class HaiJunJian :public AbstructShip
{
public:
	using AbstructShip::AbstructShip;
	string getName()override
	{
		return string("无敌海军号");
	}
	void feature() override
	{
		cout << getName() << " -- 船底由海楼石建造, 可以穿过无风带的巨大炮舰!" << endl;
	}
};
int main()
{
	//草帽海贼团
	CaoMaoTeam* caomao = new CaoMaoTeam("草帽海贼团");
	Person* luffy = new Person("路飞", "船长", "橡胶果实能力者", "30亿贝里", "爱吃肉");
	Person* zoro = new Person("索隆", "剑士", "三刀流", "11亿1100万贝里", "路痴");
	Person* sanji = new Person("山治", "厨师", "隐形黑", "10亿3200万贝里", "好色");
	Person* nami = new Person("娜美", "航海士", "天候棒+宙斯", "3亿6600万贝里", "喜欢钱");
	caomao->addMember(luffy);
	caomao->addMember(zoro);
	caomao->addMember(sanji);
	caomao->addMember(nami);
	Merry* sunny = new Merry(caomao);
	sunny->feature();
	sunny->showTeam();
	//斯摩格
	SmokeTeam* smoke =  new SmokeTeam("斯摩格海军团");
	Person* smoker = new Person("斯摩格", "中将", "冒烟果实能力者", "", "爱吃烟熏鸡肉");
	Person* dasiqi = new Person("达斯琪", "大佐", "一刀流", "", "近视");
	smoke->addMember(smoker);
	smoke->addMember(dasiqi);
	HaiJunJian* ship = new HaiJunJian(smoke);
	ship->feature();
	ship->showTeam();

	delete caomao;
	delete sunny;
	delete smoke;
	delete ship;
	return 0;

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/823021
推荐阅读
  

闽ICP备14008679号