《C++编程规范:101条规则、准则与最佳实践》——第2章设计风格设计风格 C++编程规范:101条规则、准则与最佳实践 复杂性啊,愚人对你视而不见,实干家受你所累。 有些人避而远之。惟智者能够善加消除。 ——Alan Perlis 我知道,但是却又忘记了Hoare的至理名言:不成熟的优化是程

第2章设计风格

C++编程规范:101条规则、准则与最佳实践
复杂性啊,愚人对你视而不见,实干家受你所累。

有些人避而远之。惟智者能够善加消除。

——Alan Perlis

我知道,但是却又忘记了Hoare的至理名言:不成熟的优化是程序设计中的万恶之源。

——Donald Knuth[1]

The Errors of TeX[Knuth89]

完全区分设计风格与编码风格是非常困难的。我们将一般在实际编写代码时才用得到的条款留到下一部分介绍。

本部分集中讨论适用面比一个特定的类或者函数更广的原则和实践。比较典型的包括:简单和清晰之间的平衡(第6条),避免不成熟的优化(第8条),避免不成熟的劣化(第9条)。这三个条款不仅适用于函数编写的层次,而且适用于类和模块设计权衡的更大范围,适用于更深的应用程序架构决策。(它们也适用于所有程序员。如果你不以为然,请重读上面Knuth的话,注意其中的引用部分。)

紧接其后,本部分和下一部分的其他条款讨论的都是依赖性管理的各个方面。依赖性管理是软件工程的一个基础,也是贯穿本书不断出现的主题。停下来,任意选择一个优秀的软件工程技术(任何好的技术都行),思考一下。无论选择哪一个,都将发现,它都是在想尽办法减少依赖性。继承?是为了使所编写的代码使用不依赖于实际派生类的基类。尽量减少全局变量?是为了减少因可见范围太大的数据所产生的远距离依赖。抽象?是为了消除处理概念的代码和实现它们的代码之间的依赖。信息隐藏?是为了使客户代码不依赖实体的实现细节。依赖性管理的一个相关问题还反映在避免使用共享状态(第10条)中,反映在应用信息隐藏(第11条),以及更多的其他条款中。

本部分中我们选出的最有价值条款是第6条:正确、简单和清晰第一。因为这些要求真地太必需了。

2.1一个实体应该只有一个紧凑的职责

摘要
一次只解决一个问题:只给一个实体(变量、类、函数、名字空间、模块和库)赋予一个定义良好的职责。随着实体变大,其职责范围自然也会扩大,但是职责不应该发散。

讨论
人们常说,好的商业理念能够一言以敝之。同样,每个程序实体也应该只有一个明确的目的。

如果一个实体有几个不同的目的,那么其使用难度往往会激增,因为这种实体除了会增加理解难度、复杂性和各部分中的错误外,还会导致其他问题。这种实体不仅更大(常常毫无合理理由),而且更难以使用和维护。此外,这种实体经常会为自身的一些特定用途提供有问题的接口,因为各个功能领域之间的部分重叠,会影响干净利落地实现每个功能所需的洞察力。

具有多个不同职责的实体通常都是难于设计和实现的。“多个职责”经常意味着“多重性格”——可能的行为和状态的各种组合方式。应该选择目的单一的函数(见第39条),小而且目的单一的类,以及边界清晰的紧凑模块。

应该用较小的低层抽象构建更高层次的抽象。要避免将几个低层抽象集合成一个较大的低层次抽象聚合体。用几个简单的行为来实现一个复杂的行为,比反其道而行之更加容易。

示例
例1 realloc。在标准C语言中,realloc是一个臭名昭著的不良设计。这个函数承担了太多的任务:如果传入的指针参数为NULL就分配内存空间,如果传入的大小参数为0就释放内存空间,如果可行则就地重新分配,如果不行则移到其他地方分配。这个函数不易于扩展,普遍认为它是一个目光短浅的失败设计。

例2 basic_string。在标准C++语言中,std:: basic_string是另一个臭名昭著的不良设计——巨大的类设计。在一个臃肿的类中添加了太多“多多益善”的功能,而这只是为了试图成为容器但却没有做到,在用迭代还是索引上犹豫不决,还毫无道理地重复了许多标准算法,而为扩展所留的裕度又很小(见第44条的示例)。

参考文献
[Henney02a] ● [Henney02b] ● [McConnell93] §10.5 ● [Stroustrup00] §3.8, §4.9.4, §23.4.3.1 ● [Sutter00] §10, §12, §19, §23 ● [Sutter02] §1 ● [Sutter04] §37-40

第条 正确、简单和清晰第一

时间: 2024-09-12 02:24:46

《C++编程规范:101条规则、准则与最佳实践》——第2章设计风格设计风格 C++编程规范:101条规则、准则与最佳实践 复杂性啊,愚人对你视而不见,实干家受你所累。 有些人避而远之。惟智者能够善加消除。 ——Alan Perlis 我知道,但是却又忘记了Hoare的至理名言:不成熟的优化是程的相关文章

《C++编程规范:101条规则、准则与最佳实践》——2.4不要进行不成熟的优化

2.4不要进行不成熟的优化 摘要拉丁谚语云,快马无需鞭策:不成熟优化的诱惑非常大,而它的无效性也同样严重.优化的第一原则就是:不要优化.优化的第二原则(仅适用于专家)是:还是不要优化.再三测试,而后优化. 讨论正如[Stroustrup00]§6开始所引用的优美名言说的那样: 不成熟的优化是万恶之源.--Donald Knuth (引用Hoare的话) 另一方面,我们不能忽视效率.--Jon Bentley Hoare和Knuth当然而且永远是完全正确的(见第6条和本条).Bentley亦然(见

玩无人机,机器和人差多远?

这是一场用实际数据说明,机器和人相差多远的比赛. (IROS 2017无人机竞速表演环节,荷代尔夫特理工大学选手在尝试FPV操作) 在雷锋网(公众号:雷锋网)看来,IROS 2017的无人机竞速比赛的"考题"要比IROS 2016要略简单一些,但仍然没有哪支队伍成功穿越全部13个门,最终的冠军队伍也不过穿过了9个门,成绩为3分11秒:而在正式比赛结束后的有操控表演中,一位带着VR眼镜的选手用46秒就穿越了全部13个门.而我们知道,FPV(First Person View)无人机视角要

RDS最佳实践(三)—如何制定相关的流程来规范RDS的使用

上一篇文章中,我们介绍了如何快速的把本地自建的数据库迁移入云,那是不是把数据库迁移到RDS后,用户就什么都不需要做了?比如RDS帮你的数据库做到了高可用,在主库出现down机后能够快速切换到备库,立刻恢复应用:每天会定时的备份数据和日志,如果出现误操作能够帮你恢复到任意时间点:如果担心黑客攻击或者sql注入漏洞,RDS能够帮助你进行sql注入的拦截:当数据库使用中出现bug时,后端有专业的源码和DBA团队帮助用户实例打上patch,让用户无后顾之忧:当实例的性能出现瓶颈的时候,可以进行快速的弹性

《OpenACC并行程序设计:性能优化实践指南》一 第1章 从串行编程到并行编程

第1章 从串行编程到并行编程 Rob Farber TechEnablement.com CEO/创始人 本章主要向读者介绍OpenACC,演示如何使用OpenACC编写运行在多核CPU和类似GPU加速器上的可移植并行程序,并展示如何在CPU和GPU上编译和运行OpenACC程序. 阅读本章后,读者将会理解以下内容: 如何创建.编译和运行OpenACC应用程序. 高性能OpenACC编程的三个准则. 数据并行和任务并行编程的基本概念. 理解大O表示法和Amdahl定律. 竞争条件.原子操作,以及

《编程珠玑(续)(修订版)》—第2章2.1节Awk中的关联数组

第2章 关联数组编程珠玑(续)(修订版)人类学家说,语言深刻地影响了世界观.一般把这个观察结果称为"Whorf假说"① ,也经常把它总结为"语言塑造了人的思想". 跟大多数程序员一样,我使用的Algol系列的语言塑造了我的计算思维.对于像我这样的程序员来说,PL/1.C和Pascal看起来都很相似,我们不难把这样的代码翻译成COBOL或Fortran的代码.用这些语言能轻易地表达我们旧的.习以为常的思维模式. 另外一些语言则挑战了我们对于计算的看法.我们感到惊奇的是

《易学Python》——第6章 类与面向对象编程 6.1 类是什么

第6章 类与面向对象编程 本章介绍如下内容: 一种看待类的更简单方式: 如何使用类来设计程序. 在本书前面,始终未涉及Python中组织程序的基本方式之一:类.类和面向对象编程通常被认为是一个庞大而吓人的主题,仅供真正的程序员用来编写程序,因此您可能认为,要正确地使用它们,需要大量的理论知识.没有比这种看法更离谱的了.在Python中,使用类和面向编程易如反掌. 在本章中,您将首先复习第2章为游戏Hunt the Wumpus编写的洞穴生成代码,并了解到使用类编写这些代码容易得多:然后,您将以此

《C++面向对象高效编程(第2版)》——第1章 什么是面向对象编程

第1章 什么是面向对象编程 C++面向对象高效编程(第2版)近年来,软件从业人员都将注意力转移到面向对象编程范式,甚至经理.主管和销售人员都对面向对象技术产生了浓厚的兴趣.面向对象软件俨然成为了万众瞩目的焦点,每个人孜孜以求的圣杯.面向对象到底是什么?它与我们已经使用了数十年的方法有何不同?软件开发者心存疑虑,他们认为,正是由于面向对象的出现,让他们历尽艰辛积累的技能再无用武之地.在这种情况下,理解下列内容会有所帮助: 面向对象软件开发究竟是什么?它的优点是什么?它与传统软件开发方法有何不同?它

《编程珠玑(续)(修订版)》—第1章1.1节计算素数

第1章 性能监视工具 编程珠玑(续)(修订版) 听诊器是一种简单工具,却给医生的工作带来了革命:它让内科医生能有效地监控病人的身体.性能监视工具(profiler)对程序起着同样的作用. 你现在用什么工具来研究程序?复杂的分析系统很多,既有交互式调试器,又有程序动画系统.正如CT扫描仪永远代替不了听诊器一样,复杂的软件也永远代替不了程序员用来监控程序的最简单工具--性能监视工具,我们用它了解程序各部分的执行频率. 本章先用两种性能监视工具来加速一个小程序(记住真正的目的是说明性能监视工具).后续

python 教程 第十九章、 图形界面编程

第十九章. 图形界面编程 import Tkinter top = Tkinter.Tk() hello = Tkinter.Label(top, text='Hello World!') hello.pack() quit = Tkinter.Button(top, text='QUIT',command=top.quit) quit.pack(fill=Tkinter.X, expand=1) Tkinter.mainloop()