C++学习笔记----5、重用之设计(一)---- 重用的哲学

2024-08-25 20:36

本文主要是介绍C++学习笔记----5、重用之设计(一)---- 重用的哲学,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        设计的代码你和其他的程序员应该都可以重用。这条规则不但适用于让其他程序员特别使用的库与框架,也适用于任何类、子系统或者为程序设计的部件。一定要记住如下的格言:

  • 一次编写,多次使用。
  • 尽量避免重复代码
  • 不要重复你自己。

原因如下:

  • 很少有代码只在一个程序中使用。要确信你的代码不管怎么样都会被再次使用,所以一开始就要正确地进行设计。
  • 设计重用的代码可以节省时间与金钱。如果你设计的代码不考虑未来的使用,当你碰到 类似功能的需求时,就会花费大量的时间重新造轮子。
  • 其他程序员一定能够使用你写的代码。你不会一个人在一个项目中工作。同事会感激你提供的良好设计,打包功能的库以及代码的努力。重用的设计也可以被叫做合作编码。
  • 缺乏重用就会有代码重复;代码重复就会造成维护梦魇。如果在一个重复的代码中发现了bug,就需要在它重复的所有地方进行修复。如果你发现自己在复制粘贴代码,就必须至少要考虑一下是否可以提炼到一个函数或类中。
  • 你是自己工作最大的受益者。有经验的程序员从来不会摒弃代码。随着时间的推移,他们建立了一个不断演化的个人库。你永远不会知道将来你会需要类似功能的代码。

        当然了,我喜欢这么说,对于重用,不可避免地会涉及到知识产权的问题。这个问题其实与我们学习C++编程无关,是另外一个领域的话题,我只是要说明,为公司干的工作成果,其知识产权是公司的,离职后对这些代码的重用一定要基于合法的前提。但与我们要讲的重用之哲学其实不矛盾,你不这么认为么?

如何设计可重用的代码

        可重用的代码完成如下两个目标:

  • 首先,是要对稍微不同的目的或者在不同的应用域中一般够用。特定应用的带有细节的部件在其它程序中重用是困难的。
  • 其次,可重用的代码也是易用的。不需要花费太长的时间去理解其接口与功能。程序员必须能够逐渐将其整合进他们的应用。

        将库交付给用户的方式也很重要。可以以源代码的方式交付,客户只需要将你的源代码整合进他们的项目中即可。另一种方式就是以静态库的方式交付二进制代码,链接进他们的应用,或者是用动态库的方式,在Windows环境下是.dll文件,在Linux环境下是.so文件。不同的交付方式对于如何设计可重用的代码的限制是不一样的。

        设计可重用的代码最重要的策略就是抽象。

使用抽象

        抽象的关键就是将接口与实现进行了隔离。实现就是你要写的代码,去完成你要完成的任务。接口就是其他人使用你的代码的方式。在C中,头文件揭示了你要在接口中写的库的函数声明。在面向对象的程序设计中,可以公开访问的类成员函数与类属性就是类的接口。然而,一个好的接口应该只包含公共的成员函数。类的属性永远不要变成公共的,但是可以通过公共的成员函数来向外部暴露。公共成员函数也叫做get()与set()。

        以前我们介绍过抽象的原则,讲过一个真实世界中的对于电视的分析,你可以在不理解其内部是如何工作的情况下通过接口赤使用。同样的,在设计代码时,也要将实现与接口清楚地分开。这种分隔使代码易于使用,主要是因为用户不需要理解内部实现的细节就可以使用其功能。

        使用抽象对你与使用你的代码的用户都有好处。用户有好处是因为他们不需要担心实现细节;可以在不理解代码怎么干活的情况下利用其功能。这样的话,就可以不要求用户改变其使用的情况下升级你的代码。对于动态链接库,用户甚至不需要重新构建其可执行程序。最后,对双方都有好处是因为,对于你,库作者,可以指定接口,按照你想要的交互,以及你想要的支持功能来指定。对于接口与实现的隔离或以防止用户以你不想要的方式来使用库,因为这种使用方式可能会引起不可预知的行为和问题。

        设计接口时,不要向用户暴露实现细节。

        有时候库会要求用户代码保留从一个接口返回的信息并将其传递给另一个。这种信息有时候会叫做一个句柄,常用于在不同的调用之间跟踪特定实例的状态。真实世界的例子就是OpenGL,一个2D/3D优化库。OpenGL的许多函数返回句柄,操作句柄,以GLuint的类型出现。例如,如果你要用OpenGL函数glGenBuffers()来生成一个缓存,它返回GLuint句柄。任何时候你要调用另一个函数来结这个缓存进行操作的时候,都必须把GLuint句柄传递给那个函数。

        如果你的库设计需要一个句柄,不要暴露其内部。使其成为一个透明的类,程序员无法访问其内部数据成员,不管是直接还是通过get()与set(),都不行。不要要求用户代码在句柄内部调整变量。不好的设计例子就是要求在一个假定透明的句柄中指定特定结构成员的值,比如为了打开错误日志。

        不幸的是,C++对于类的抽象原则很不友好(当然了,从另一个角度来说,它提供了方便性)。语法要求你将public接口与non-public(private或者protected)数据成员和成员函数放到一个类定义中,这样的话,就会把类的实现细节暴露给了用户。

        抽象是如此重要,以至于它要在整个设计中对你进行指导。你所做出的每一个决定,都要问问你自己,你的选择是否遵从了抽象的原则。站在用户的角度来决定是否在接口中包含了内部实现的知识细节。可能,很偶尔地,你会破坏这个规则。

        当使用抽象原则进行可重用代码设计时,应该侧重于以下几点:

  • 首先,必须正确结构化代码。要使用什么样的类层次结构?要用模板吗?如何将代码分成子系统?
  • 其次,要设计接口,该接口就是进入库进行你提供的功能访问的入口。

好了,我们今天讨论的内容不少了,上面的这两个主题我们以后继续聊。

这篇关于C++学习笔记----5、重用之设计(一)---- 重用的哲学的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1106591

相关文章

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ

C++中RAII资源获取即初始化

《C++中RAII资源获取即初始化》RAII通过构造/析构自动管理资源生命周期,确保安全释放,本文就来介绍一下C++中的RAII技术及其应用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、核心原理与机制二、标准库中的RAII实现三、自定义RAII类设计原则四、常见应用场景1. 内存管理2. 文件操

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五

C++作用域和标识符查找规则详解

《C++作用域和标识符查找规则详解》在C++中,作用域(Scope)和标识符查找(IdentifierLookup)是理解代码行为的重要概念,本文将详细介绍这些规则,并通过实例来说明它们的工作原理,需... 目录作用域标识符查找规则1. 普通查找(Ordinary Lookup)2. 限定查找(Qualif

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

MyBatis设计SQL返回布尔值(Boolean)的常见方法

《MyBatis设计SQL返回布尔值(Boolean)的常见方法》这篇文章主要为大家详细介绍了MyBatis设计SQL返回布尔值(Boolean)的几种常见方法,文中的示例代码讲解详细,感兴趣的小伙伴... 目录方案一:使用COUNT查询存在性(推荐)方案二:条件表达式直接返回布尔方案三:存在性检查(EXI

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

C/C++ chrono简单使用场景示例详解

《C/C++chrono简单使用场景示例详解》:本文主要介绍C/C++chrono简单使用场景示例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友... 目录chrono使用场景举例1 输出格式化字符串chrono使用场景China编程举例1 输出格式化字符串示