外部化内部类

要定义一个新的名字空间,将一个类内部的类提到外部,目的是降低类的耦合度和复杂度,这通常可以通过 外部化内部类 来实现。通过这种方式,可以将复杂的实现细节分离到一个单独的名字空间中,让外部类的接口保持简洁。接下来我们会详细讲解这个方法,并给出具体示例。

如何实现

假设你有一个类,其中包含了多个内部类。你希望将这些内部类移到外部的名字空间中,从而使得外部类变得更加简洁,并降低原本的耦合度和复杂度。

步骤

  1. 识别和提取内部类:首先,你需要识别内部类的设计是否合适提取到外部。通常,内部类可能是对外部类的某种细节封装,但如果它们本身也具有独立的职责和功能,应该考虑将它们提取到外部名字空间。

  2. 创建新的名字空间:将提取出来的类放入一个新的名字空间。新名字空间的引入使得这些类不会直接依赖于外部类的实现,减少了它们之间的耦合。

  3. 移除类之间的依赖关系:确保外部类和提取出来的类之间的依赖关系尽可能松散。这样,外部类可以保持清晰简洁。

  4. 调整接口:外部类的接口不再直接暴露复杂的内部实现,外部类只需要引用这些提取到名字空间的类,而不需要将它们嵌套在自己内部。

示例:

假设我们有一个类 Car,它内部有一个复杂的内部类 Engine。现在我们希望将 Engine 提取到一个新的名字空间 CarParts 中,从而减少 Car 类的复杂度。

原始设计(带内部类)
#include <iostream>
#include <string>class Car {
public:Car(const std::string& model) : model_(model) {engine_ = Engine(4, "V8");}void start() {std::cout << "Starting car: " << model_ << std::endl;engine_.ignite();  // 内部类的使用}private:class Engine {public:Engine(int cylinders, const std::string& type): cylinders_(cylinders), type_(type) {}void ignite() {std::cout << "Engine with " << cylinders_ << " cylinders and type " << type_ << " is starting!" << std::endl;}private:int cylinders_;std::string type_;};std::string model_;Engine engine_;
};int main() {Car myCar("Toyota");myCar.start();return 0;
}

在上面的代码中,Car 类包含了一个内部类 EngineEngine 类和 Car 类的耦合度较高,而且 Engine 类的实现细节对外部类 Car 来说是不可见的。为了降低 Car 类的复杂度,我们将 Engine 类提取到一个新的名字空间。

提取后设计(外部类和名字空间)
#include <iostream>
#include <string>// 新名字空间
namespace CarParts {class Engine {public:Engine(int cylinders, const std::string& type): cylinders_(cylinders), type_(type) {}void ignite() const {std::cout << "Engine with " << cylinders_ << " cylinders and type " << type_ << " is starting!" << std::endl;}private:int cylinders_;std::string type_;};
}class Car {
public:Car(const std::string& model): model_(model), engine_(4, "V8") {}void start() {std::cout << "Starting car: " << model_ << std::endl;engine_.ignite();  // 现在引擎来自外部命名空间}private:std::string model_;CarParts::Engine engine_;  // 引用外部命名空间中的 Engine 类
};int main() {Car myCar("Toyota");myCar.start();return 0;
}

变化解析:

  1. 提取内部类到外部命名空间:我们将原来的 Engine 类提取到一个名为 CarParts 的新命名空间中。这样,Engine 类不再是 Car 类的内部类,而是一个独立的类,外部可以直接使用。

  2. 修改 Car:在 Car 类中,我们现在不再声明 Engine 类作为内部类,而是通过 CarParts::Engine 来引用外部命名空间中的 Engine 类。这使得 Car 类的接口更简洁,且没有被复杂的内部类所干扰。

  3. 减少耦合:通过将 Engine 类提取到一个新的命名空间中,Car 类和 Engine 类的耦合度降低了。Car 类不再关心 Engine 类的内部实现,只是通过接口来与 Engine 类交互。这增强了 Car 类的模块化,使得 Engine 类的修改不会直接影响 Car 类的代码。

优点:

  • 降低耦合度:将内部类提取到外部命名空间后,类之间的耦合度明显减少。Car 类不再直接管理 Engine 类的实现,可以更加专注于自身的功能。
  • 提高可维护性:如果将来需要修改 Engine 类的实现,修改 CarParts::Engine 代码时不需要直接修改 Car 类。这使得代码更加模块化,维护起来也更为方便。
  • 提高可扩展性Engine 类现在是独立的,可以在其他地方重复使用,而不依赖于 Car 类。这使得代码更加通用,便于扩展。

总结:

将类的内部类提取到外部命名空间是一种常见的设计模式,它能够有效地降低原来类的复杂度和耦合度。通过这种方式,可以使类的接口更加清晰和简洁,同时提高代码的可维护性和可扩展性。在 C++ 中,这种做法特别适用于将一些复杂的辅助类提取到外部,让它们更独立,减少对主类的影响。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/65138.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

创建仓颉编程语言的第一个项目

创建仓颉编程语言的第一个项目 安装仓颉编程语言编译器第一个仓颉项目 安装仓颉编程语言编译器 安装仓颉编程语言编译器&#xff0c;是一个需要非常强的动手能力的过程——有大量的命令行操作。这不是仓颉编程语言独有的特点。现在流行的编程语言&#xff0c;比如 kotlin、jav…

kong网关使用pre-function插件,改写接口的返回数据

一、背景 kong作为api网关&#xff0c;除了反向代理后端服务外&#xff0c;还可对接口进行预处理。 比如本文提及的一个小功能&#xff0c;根据http header某个字段的值&#xff0c;等于多少的时候&#xff0c;返回一个固定的报文。 使用到的kong插件是pre-function。 除了上…

计算机网络:IP地址相关知识总结

目录 一、IP地址的表现形式 1.1 十进制表示形式 1.2 二进制表示形式 1.3 转换示例介绍 二、IP地址的组成 2.1 网络ID 2.2 主机ID 2.3 示例 三、IP地址的分类 3.1 A类地址 3.2 B类地址 3.3 C类地址 3.4 D类地址 3.5 E类地址 四、常见的特殊IP地址 五、IP地址二进…

基础练习 Huffman树,C++,最小堆,STL

Description Huffman树在编码中有着广泛的应用。在这里&#xff0c;我们只关心Huffman树的构造过程。 给出一列数{pi}{p0, p1, …, pn-1}&#xff0c;用这列数构造Huffman树的过程如下&#xff1a; 1. 找到{pi}中最小的两个数&#xff0c;设为pa和pb&#xff0c;将pa和pb从{…

Java获取自身被调用点

1. 场景 打印日志的时候&#xff0c;需要获取是在哪个地方被调用了&#xff0c;把调用点的信息一并打印出来。 2. 获取自身被调用点的方法 可以通过获取线程的调用栈&#xff0c;遍历后找到调用点。 3. 代码实现 import java.text.SimpleDateFormat; import java.util.Dat…

vue3入门教程:teleport

一、基本语法 Teleport组件的基本语法如下&#xff1a; <Teleport to"目标选择器"><!-- 要传送的内容 --> </Teleport>其中&#xff0c;to属性指定了内容将被渲染到的目标位置&#xff0c;它可以是一个CSS选择器字符串&#xff08;如#some-id、.…

群晖Cloud Sync一键同步让数据管理变得简单

前言&#xff1a;在这个数字化爆炸的时代&#xff0c;数据管理和备份已经变得不可或缺。无论是个人用户还是企业&#xff0c;都需要一种既高效又可靠的方式来管理和备份分散在各种设备和云存储中的文件。而群晖的 **Cloud Sync** 套件正是为了解决这个问题而生。 Cloud Sync 是…

docker 部署mysql8

在Docker中部署MySQL 8是一个相对简单的过程。以下是基本的步骤&#xff1a; 拉取MySQL 8镜像&#xff1a; 使用Docker命令拉取最新的MySQL 8镜像&#xff1a; docker pull registry.openanolis.cn/openanolis/mysql:8.0.30-8.6创建并运行MySQL容器&#xff1a; 创建并运行MySQ…

Triple三倍

time limit per test 1 second memory limit per test 256 megabytes Given an array aa of nn elements, print any value that appears at least three times or print -1 if there is no such value. Input The first line contains an integer tt (1≤t≤1041≤t≤10…

GPIO+TIM(无PWM)实现呼吸灯功能

程序特点&#xff1a; 1、模块化&#xff0c;可快速移植&#xff0c;5分钟便可完成移植。 2、通过GPIO普通定时器&#xff0c;实现呼吸灯功能。 3、PWM周期为5ms&#xff0c;占空比调节时间为20ms&#xff0c;占空比为100等份&#xff0c;即呼吸灯从暗到亮需要20ms*1002s。 …

前缀树介绍

数风流人物&#xff0c;还看今朝&#xff01; 前缀树 Trie&#xff08;发音类似 "try"&#xff09;或者说 前缀树 是一种树形数据结构&#xff0c;用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景&#xff0c;例如自动补全和拼写检查。 前…

基于遥感与通信技术的灾害应急测绘

基于遥感与通信技术的灾害应急测绘研究评述与展望 摘要 本研究围绕基于遥感与通信技术的灾害应急测绘展开&#xff0c;深入探讨其在灾害管理中的重要性及当前发展现状。遥感技术凭借高分辨率、广覆盖的特性&#xff0c;已成为获取灾害信息的核心手段。结合5G通信与低轨卫星技术…

37 Opencv SIFT 特征检测

文章目录 Ptr<SIFT> SIFT::create示例 Ptr SIFT::create Ptr<SIFT> SIFT::create(int nfeatures 0,int nOctaveLayers 3,double contrastThreshold 0.04,double edgeThreshold 10,double sigma 1.6 );参数说明&#xff1a;nfeatures&#xff1a;类型&#x…

家政预约小程序数据库设计

目录 1 如何设计表结构1.1 用户表1.2 服务分类表1.3 服务表1.4 服务规格表1.5 订单表1.6 服务人员表1.7 评价表1.8 促销活动表1.9 投诉表1.10 年卡表1.11 派单表1.12 支付记录表1.13 通知记录表1.14 优惠券表1.15 用户优惠券表1.16 消息模板表1.17 积分记录表 经过一系列的设计…

kkfileview代理配置,Vue对接kkfileview实现图片word、excel、pdf预览

kkfileview部署 官网&#xff1a;https://kkfileview.keking.cn/zh-cn/docs/production.html 这个是官网部署网址&#xff0c;这里推荐大家使用docker镜像部署&#xff0c;因为我是直接找运维部署的&#xff0c;所以这里我就不多说明了&#xff0c;主要说下nginx代理配置&am…

扩散模型经典问题:训练Diffusion Models的Loss有什么特别之处?

AIGC算法工程师 面试八股文 Diffusion Loss的推导原理?训练Diffusion Models的Loss有什么特别之处?Diffusion Models的Loss下降趋势是什么样的?为什么训练Diffusion Models的Loss会有这样的特征? 目录 Diffusion Loss的推导原理 一般Diffusion Models训练Loss特征 Loss可…

【数据可视化案列】白葡萄酒质量数据的EDA可视化分析

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…

MyBatis 的一级缓存和二级缓存

MyBatis 提供了两种缓存机制&#xff0c;分别是 一级缓存 和 二级缓存。它们可以显著提高数据库操作的性能&#xff0c;通过减少数据库的访问次数&#xff0c;但它们的工作原理、作用范围以及使用方式有所不同。 一、一级缓存 1. 概述 一级缓存是 SqlSession 级别的缓存&…

压缩qcow2镜像带来的性能损失简单分析

本文拟对压缩qcow2镜像所带来的虚拟机性能损失进行简单分析 背景 生产中发现使用压缩镜像启动的虚拟机开机总是会慢一些。 qcow2镜像的压缩方式为&#xff1a;qemu-img convert -p -c -O qcow2 zero_disk.qcow2 compress_disk.qcow2 分析 qemu代码&#xff1a;https://down…

数据结构之栈,队列,树

目录 一.栈 1.栈的概念及结构 2.栈的实现 3.实现讲解 1.初始化栈 2.销毁栈 3.压栈 4.出栈 5.返回栈顶元素 6.返回栈内元素个数 7.判断栈内是否为空 二.队列 1.队列的概念及结构 2.队列的实现 3.实现讲解 1.初始化队列 2.销毁队列 3.单个成员入队列 4.单个成员…