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

相关文章

Mysql中设计数据表的过程解析

《Mysql中设计数据表的过程解析》数据库约束通过NOTNULL、UNIQUE、DEFAULT、主键和外键等规则保障数据完整性,自动校验数据,减少人工错误,提升数据一致性和业务逻辑严谨性,本文介绍My... 目录1.引言2.NOT NULL——制定某列不可以存储NULL值2.UNIQUE——保证某一列的每一

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

C++中detach的作用、使用场景及注意事项

《C++中detach的作用、使用场景及注意事项》关于C++中的detach,它主要涉及多线程编程中的线程管理,理解detach的作用、使用场景以及注意事项,对于写出高效、安全的多线程程序至关重要,下... 目录一、什么是join()?它的作用是什么?类比一下:二、join()的作用总结三、join()怎么

C++中全局变量和局部变量的区别

《C++中全局变量和局部变量的区别》本文主要介绍了C++中全局变量和局部变量的区别,全局变量和局部变量在作用域和生命周期上有显著的区别,下面就来介绍一下,感兴趣的可以了解一下... 目录一、全局变量定义生命周期存储位置代码示例输出二、局部变量定义生命周期存储位置代码示例输出三、全局变量和局部变量的区别作用域

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

c++ 类成员变量默认初始值的实现

《c++类成员变量默认初始值的实现》本文主要介绍了c++类成员变量默认初始值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录C++类成员变量初始化c++类的变量的初始化在C++中,如果使用类成员变量时未给定其初始值,那么它将被

C++中NULL与nullptr的区别小结

《C++中NULL与nullptr的区别小结》本文介绍了C++编程中NULL与nullptr的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编... 目录C++98空值——NULLC++11空值——nullptr区别对比示例 C++98空值——NUL

C++ Log4cpp跨平台日志库的使用小结

《C++Log4cpp跨平台日志库的使用小结》Log4cpp是c++类库,本文详细介绍了C++日志库log4cpp的使用方法,及设置日志输出格式和优先级,具有一定的参考价值,感兴趣的可以了解一下... 目录一、介绍1. log4cpp的日志方式2.设置日志输出的格式3. 设置日志的输出优先级二、Window

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat