设计模式:桥接模式(c++实现案例)

2023-11-12

桥接模式

桥接模式是一种结构型设计模式, 可将业务逻辑或一个大类拆分为不同的层次结构, 从而能独立地进行开发。桥接模式通过将继承改为组合的方式来解决这个问题。

具体来说, 就是抽取其中一个维度并使之成为独立的类层次, 这样就可以在初始类中引用这个新层次的对象, 从而使得一个类不必拥有所有的状态和行为。

层次结构中的第一层 (通常称为抽象部分) 将包含对第二层 (实现部分) 对象的引用。
抽象部分将能将一些 (有时是绝大部分) 对自己的调用委派给实现部分的对象。 所有的实现部分都有一个通用接口, 因此它们能在抽象部分内部相互替换。

桥接模式在处理跨平台应用、 支持多种类型的数据库服务器或与多个特定种类 (例如云平台和社交网络等) 的 API 供应商协作时会特别有用。

应用实例: 1、猪八戒从天蓬元帅转世投胎到猪,转世投胎的机制将尘世划分为两个等级,即:灵魂和肉体,前者相当于抽象化,后者相当于实现化。生灵通过功能的委派,调用肉体对象的功能,使得生灵可以动态地选择。 2、墙上的开关,可以看到的开关是抽象的,不用管里面具体怎么实现的。

桥接模式实现步骤

1.提供一个抽象类(桥接类):提供高层控制逻辑,依赖实际底层对象

2.提供一个具体抽象类:拓展抽象类,更精确的抽象

3.提供具体实现抽象类:具体实现类的抽象通用接口

4.提供具体实现类:针对不同底层的通用接口实现


代码实现:

#include <iostream>
#include <string>
#include <vld.h>
using namespace std;

//1. 作为桥接实现的color类
class color
{
public:
	virtual ~color() {}
	virtual void FillColor() = 0;
};
//2.1 实现了color的具体类
class Red :public color
{
public:
	Red() :colorType("RED") {}
	~Red() {}
	void FillColor()override
	{
		cout << "填充颜色:" << colorType << endl;
	}
private:
	string colorType;
};
//2.2 实现了color的具体类
class Blue :public color
{
public:
	Blue() :colorType("BLUE") {}
	~Blue() {}
	void FillColor()override
	{
		cout << "填充颜色:" << colorType << endl;
	}
private:
	string colorType;
};

//3. 具体实现抽象类,提供实现接口定义
class Shape
{
public:
	virtual ~Shape() { if (m_color) { delete m_color; m_color = nullptr; } }
	virtual void showShape() = 0;
	virtual void setColor(color* color) = 0;
protected:
	virtual void drawColor() = 0;
	virtual void drawShape() = 0;
	color* m_color;
};

//4.1 具体实现类:实现接口
class Circle :public Shape
{
public:
	Circle() :shapeType("Circle") {}
	~Circle() { }
	void showShape()override
	{
		drawColor();
		drawShape();
	}
	void setColor(color* color)override
	{
		if (m_color) { delete m_color; m_color = nullptr; }
		this->m_color = color;
	}
private:
	void drawColor()override
	{
		this->m_color->FillColor();
	}
	void drawShape()override
	{
		cout << "绘制:" << shapeType << endl;
	}
	string shapeType;
};
//4.2 具体实现类:实现接口
class Rect :public Shape
{
public:
	Rect() :shapeType("Rect") {}
	~Rect() {}
	void showShape()override
	{
		drawColor();
		drawShape();
	}
	void setColor(color* color)override
	{
		if (m_color) { delete m_color; m_color = nullptr; }
		this->m_color = color;
	}
private:
	void drawColor()override
	{
		this->m_color->FillColor();
	}
	void drawShape()override
	{
		cout << "绘制:" << shapeType << endl;
	}
	string shapeType;
};

int main()
{
	Shape* circle = new Circle;
	circle->setColor(new Red);
	circle->showShape();
	circle->setColor(new Blue);
	circle->showShape();
	delete circle;
	circle = nullptr;

	Shape* rect = new Rect;
	rect->setColor(new Red);
	rect->showShape();
	rect->setColor(new Blue);
	rect->showShape();
	delete rect;


	return 0;
}

优点

  • 你可以创建与平台无关的类和程序

  • 客户端代码仅与高层抽象部分互动, 不接触到平台详细信息

  • 开闭原则,可以新增抽象和实现, 且它们之间互不影响

  • 单一职责原则,抽象专注高层逻辑, 实现部分处理平台细节

缺点

  • 对高内聚的类使用该模式可能会让代码更加复杂
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

设计模式:桥接模式(c++实现案例) 的相关文章

  • 向进度条添加百分比文本 C#

    我有一个方法可以显示进程栏何时正在执行以及何时成功完成 我工作得很好 但我想添加一个百分比 如果完成 则显示 100 如果卡在某个地方 则显示更少 我在网上做了一些研究 但我无法适应我正在寻找的解决方案 这是我的代码 private voi
  • 如何将 protobuf-net 与不可变值类型一起使用?

    假设我有一个像这样的不可变值类型 Serializable DataContract public struct MyValueType ISerializable private readonly int x private readon
  • 如何将非静态类成员“std::bind”绑定到 Win32 回调函数“WNDPROC”?

    我正在尝试将非静态类成员绑定到标准WNDPROC http msdn microsoft com en us library ms633573 aspx功能 我知道我可以通过将类成员设为静态来简单地做到这一点 但是 作为一名 C 11 ST
  • 在 DataView 的 RowFilter 中选择 DISTINCT

    我试图根据与另一个表的关系缩小 DataView 中的行范围 我使用的 RowFilter 如下 dv new DataView myDS myTable id IN SELECT DISTINCT parentID FROM myOthe
  • MVC 在布局代码之前执行视图代码并破坏我的脚本顺序

    我正在尝试将所有 javascript 包含内容移至页面底部 我正在将 MVC 与 Razor 一起使用 我编写了一个辅助方法来注册脚本 它按注册顺序保留脚本 并排除重复的内容 Html RegisterScript scripts som
  • ClickOnce 应用程序错误:部署和应用程序没有匹配的安全区域

    我在 IE 中使用 FireFox 和 Chrome 的 ClickOnce 应用程序时遇到问题 它工作正常 异常的详细信息是 PLATFORM VERSION INFO Windows 6 1 7600 0 Win32NT Common
  • 使用 LINQ2SQL 在 ASP.NET MVC 中的各种模型存储库之间共享数据上下文

    我的应用程序中有 2 个存储库 每个存储库都有自己的数据上下文对象 最终结果是我尝试将从一个存储库检索到的对象附加到从另一个存储库检索到的对象 这会导致异常 Use 构造函数注入将 DataContext 注入每个存储库 public cl
  • 使用 Newtonsoft 和 C# 反序列化嵌套 JSON

    我正在尝试解析来自 Rest API 的 Json 响应 我可以获得很好的响应并创建了一些类模型 我正在使用 Newtonsoft 的 Json Net 我的响应中不断收到空值 并且不确定我的模型设置是否正确或缺少某些内容 例如 我想要获取
  • 使用接口有什么好处?

    使用接口有什么用 我听说它用来代替多重继承 并且还可以用它来完成数据隐藏 还有其他优点吗 哪些地方使用了接口 程序员如何识别需要该接口 有什么区别explicit interface implementation and implicit
  • 是否有实用的理由使用“if (0 == p)”而不是“if (!p)”?

    我倾向于使用逻辑非运算符来编写 if 语句 if p some code 我周围的一些人倾向于使用显式比较 因此代码如下所示 if FOO p some code 其中 FOO 是其中之一false FALSE 0 0 0 NULL etc
  • 标准化 UTF-8 到底是什么?

    The 重症监护室项目 http userguide icu project org transforms normalization 现在也有一个PHP库 http us php net manual en class normalize
  • 在一个平台上,对于所有数据类型,所有数据指针的大小是否相同? [复制]

    这个问题在这里已经有答案了 Are char int long 甚至long long 大小相同 在给定平台上 不能保证它们的大小相同 尽管在我有使用经验的平台上它们通常是相同的 C 2011 在线草稿 http www open std
  • 我可以使用 moq Mock 来模拟类而不是接口吗?

    正在经历https github com Moq moq4 wiki Quickstart https github com Moq moq4 wiki Quickstart 我看到它 Mock 一个接口 我的遗留代码中有一个没有接口的类
  • DbContext 和 ObjectContext 有什么区别

    From MSDN 表示工作单元和存储库模式的组合 使您能够查询数据库并将更改分组在一起 然后将这些更改作为一个单元写回存储 DbContext在概念上类似于ObjectContext 我虽然DbContext只处理与数据库的连接以及针对数
  • 如何禁用 fread() 中的缓冲?

    我正在使用 fread 和 fwrite 读取和写入套接字 我相信这些函数用于缓冲输入和输出 有什么方法可以在仍然使用这些功能的同时禁用缓冲吗 Edit 我正在构建一个远程桌面应用程序 远程客户端似乎 落后于服务器 我不知道可能是什么原因
  • 使用管道时,如果子进程数量大于处理器数量,进程是否会被阻塞?

    当子进程数量很大时 我的程序停止运行 我不知道问题是什么 但我猜子进程在运行时以某种方式被阻止 下面是该程序的主要工作流程 void function int process num int i initial variables for
  • 动态添加 ASP.Net 控件

    我有一个存储过程 它根据数据库中存储的记录数返回多行 现在我想有一种方法来创建 div 带有包含该行值的控件的标记 如果从数据库返回 10 行 则 10 div 必须创建标签 我有下面的代码来从数据库中获取结果 但我不知道如何从这里继续 S
  • 调用堆栈中的“外部代码”是什么意思?

    我在 Visual Studio 中调用一个方法 并尝试通过检查调用堆栈来调试它 其中一些行标记为 外部代码 这到底是什么意思 方法来自 dll已被处决 外部代码 意味着该dll没有可用的调试信息 你能做的就是在Call Stack窗口中单
  • 方法优化 - C#

    我开发了一种方法 允许我通过参数传入表 字符串 列数组 字符串 和值数组 对象 然后使用这些参数创建参数化查询 虽然它工作得很好 但代码的长度以及多个 for 循环散发出一种代码味道 特别是我觉得我用来在列和值之间插入逗号的方法可以用不同的
  • WebSocket安全连接自签名证书

    目标是一个与用户电脑上安装的 C 应用程序交换信息的 Web 应用程序 客户端应用程序是 websocket 服务器 浏览器是 websocket 客户端 最后 用户浏览器中的 websocket 客户端通过 Angular 持久创建 并且

随机推荐

  • 【python】实现list除以一个数

    文章目录 新建一个list 存放数据 使用numpy np divide list如何除以一个数 有如下两种方法 import random my list random randint 0 100 for x in range 10 pr
  • mysql 页和叶子页_一看就懂的:MySQL数据页以及页分裂机制,别在说不会了

    下面我们就一起看下 究竟什么是MySQL的数据页 数据区等概念 二 数据页长啥样 数据页长下面这样 image png 三 什么是数据区 在MySQL的设定中 同一个表空间内的一组连续的数据页为一个extent 区 默认区的大小为1MB 页
  • MySQL Flashback拯救手抖党

    MySQL Flashback拯救手抖党 2019 06 12 黄子程 黄子程 黄子程 网易游戏资深运维工程师 曾参与多款网易代理游戏产品的运营维护工作 后逐渐转向数据库管理维护领域 目前主要工作方向为网易游戏 Relational DBa
  • unity3d 对大图额外加载

    加载 UI 背景大图 lua 使用 if self findBack image nil then resMgr UnLoadBigImage self findBack image self findBack image nil self
  • 【华为云】E: You don‘t have enough free space in /var/cache/apt/archives/.

    目录 一 购买华为云系统盘空间 二 扩容前的准备 三 扩容 扩大已有MBR分区 起因 使用华为云服务器 在安装Xfce桌面环境时报错 E You don t have enough free space in var cache apt a
  • sql 数据库删除,修改,增加列语句

    ALTER TABLE 添加 修改 删除表的列 约束等表的定义 查看列 desc 表名 修改表名 alter table t book rename to bbb 添加列 alter table 表名 add column 列名 varch
  • [翻译&摘抄]ES6 中的元编程:Symbol

    原文地址 Metaprogramming in ES6 Symbols and why they re awesome 原文作者 Keith Cirkel 译文出自 掘金翻译计划 转自 https juejin im post 5a0e65
  • LM5118 DC-DC电源降压芯片带载能力不够问题

    1 现象 主机系统带载到2A时 系统反复重启 2 分析 示波器测量VCC 5V 稳压源一显示到2A VCC 5V就会掉到0V 把如下二极管断开 万用表测量电流到3 7A就是掉下 3 解决 查规格书可知电流检测电阻的计算 原来为0 03R 按
  • javascript解析XML生成树形结构

    前两天一个朋友去一家公司面试 面试题是用javascript解析一个XML 生成树形结构 今天闲着没事就试了试 源代码
  • Unity自带的相应事件

    Unity自带的相应事件 代码 条件 各个响应事件 鼠标移入移出 鼠标按下 抬起 点击 鼠标拖拽 选择事件接口 系统按键事件的接口 代码 using UnityEngine using UnityEngine EventSystems pu
  • 数据结构题目-哈希

    目录 A Hash表 线性探测法解决冲突 B 求3阶B 树的深度 C 输出3阶B 树的构造过程 D Hash表 链表法解决冲突 仅作储存代码使用 A Hash表 线性探测法解决冲突 include
  • Python当中reverse()函数

    Hello大家好 今天我想和大家分享一下Python当中的reverse 函数 reverse 函数顾名思义就是反转的意思 但是我们要注意反转的内容只能是python当中的列表 千万不要忘记了 例子如下 arr 1 2 3 4 5 6 ar
  • js数据类型之对象object类型(数组与自定义对象)

    对象object 数组与自定义对象 JavaScript 中的所有事物都是对象 字符串 数值 数组 函数 此外 JavaScript 允许自定义对象 JavaScript 提供多个内建对象 比如 String Date Array 等等 对
  • CoordinatorLayout+AppBarLayout+CollapsingToolbarLayout+Toolbar实现渐变透明的状态栏

    在之前的一篇博文里面我已经说明了CoordinatorLayout使用过程中遇到的问题 之后又发现结合CollapsingToolbarLayout使用时的另一个问题 CollapsingToolbarLayout里面的ImageView为
  • [架构之路-208]- 人人都是产品经理 - 什么是产品经理?产品经理具体是做什么的?

    目录 一 什么是产品经理 产品经理具体做什么 二 产品经理的岗位职责 三 产品经理的职业规划 一 什么是产品经理 产品经理具体做什么 在外行人看来 产品经理常常被误认为是 经理 其实产品经理只是一个岗位名称 并不是真正意义上的 经理 或者说
  • 深入浅出UML类图(五)

    实例分析3 售票机控制程序 某运输公司决定为新的售票机开发车票销售的控制软件 图I给出了售票机的面板示意图以及相关的控制部件 图I 售票机面板示意图 售票机相关部件的作用如下所述 1 目的地键盘用来输入行程目的地的代码 例如 200表示总站
  • python的几个重要基本概念

    1 整数 小数 布尔值和空值 整数 int类型 计算机中整数是有最大值的 与计算机的存储能力有关 即使是这样计算机中的整数值也是很大很大的 这一点基本上不需要担心的 小数 也称 浮点数 float类型 小数就是带小数点的数包括 1 0 等等
  • sqlite数据库-------清除数据,数据库文件大小不变解决方法

    现象 删除表格的全部数据 DELETE FROM Name 原因 当在sqlite中删除了大量数据后 数据库文件的大小还是那样 没有变 原因是 从Sqlite删除数据后 未使用的磁盘空间被添加到一个内在的 空闲列表 中用于存储你下次插入的数
  • IP协议号与传输层端口

    网络层 数据包的包格式里面有个很重要的字段叫做协议号 比如在传输层如果是tcp连接 那么在网络层ip包里面的协议号就将会有个值是6 如果是udp的话那个值就是17 传输层 传输层 通过接口关联 端口的字段叫做端口 应用层 协议号是存在于IP
  • 设计模式:桥接模式(c++实现案例)

    桥接模式 桥接模式是一种结构型设计模式 可将业务逻辑或一个大类拆分为不同的层次结构 从而能独立地进行开发 桥接模式通过将继承改为组合的方式来解决这个问题 具体来说 就是抽取其中一个维度并使之成为独立的类层次 这样就可以在初始类中引用这个新层