程序员们有什么好的编程习惯?

news2024/12/25 12:46:52

优良的代码显然不是制作优秀软件的唯一要素,但是主要的要素之一。我们可能拥有世界上最好的产品和营销团队,部署了最好的平台,并以最好的框架来构建软件,但归根结底,一款软件所做的一切,都是因为有人写了一段代码才得以实现的。

孤立地看,工程师们每天编写代码时所做出的决策都很小,有时显得微不足道,但它们共同决定了软件的好坏。如果代码中包含了缺陷、配置错误或者无法恰当地处理错误情况,由此构建的软件就可能有许多缺陷,甚至无法正常工作。

代码质量的六大支柱如下:

● 编写易于理解(可读)的代码;

如果我们的代码可读性很差,其他工程师就不得不花费很多时间来解读它。他们很有可能错误地理解它的作用,或者遗漏一些重要的细节。如果发生这种情况,代码评审期间就不太可能发现缺陷,而在其他人修改我们的代码、添加新功能时,就有可能引入新缺陷。软件的功能都是基于代码来完成的。如果工程师无法理解代码的作用,也就几乎不可能确定软件能否正常工作。正如食谱一样,代码必须易于理解。

● 避免意外;

即便有着最好的意图,编写提供一些有用或者“聪明”功能的代码仍有造成意外的风险。如果代码做了某些意外的事情,使用代码的工程师不会知道也不会思考处理那种情况的方法。这往往会导致系统“跛行”,直到在远离问题代码的地方出现明显的古怪表现。或许,这只会产生一个有些恼人的缺陷,但也可能造成破坏重要数据的灾难性问题。我们应该提防代码中的意外情况,并尽可能避免。

〓● 编写难以误用的代码;

通过编写很难或不可能被误用的代码,我们可以最大限度地提高代码持续正常工作的概率。针对这个问题,有许多实用的解决方法。

〓● 编写模块化的代码;

软件系统和代码库与这些玩具非常相似。将代码分解为独立模块,其中两个相邻模块的交互发生在单一位置、使用明确定义的接口,往往是很有好处的。这有助于确保代码更容易适应变化的需求,因为一项功能的变化不需要对所有地方进行大量修改。

模块化系统通常也更容易理解和推演。因为系统被分解为容易控制的小功能块,各功能块之间的交互有明确的定义和文档。这增加了代码一开始就能正常工作,并在未来持续工作的可能性——因为工程师更不容易误解代码的作用。

〓● 编写可重用、可推广的代码;

编写可重用、可推广的代码,我们(和其他人)就可以在代码库的多个地方和场景中使用它们,解决不止一个问题。这能节约时间和精力,并使我们的代码更加可靠,因为我们往往重用已在外部经过考验的逻辑,其中的缺陷可能已经被发现和修复。

〓● 编写可测试的代码并适当测试。

如果代码不可测试,也就不可能对其进行“适当”测试了。为了确保我们编写的代码是可测试的,最好在编写代码时不断地问自己一个问题:“我们将如何测试这些代码?”因此,测试不应该是“马后炮”,而应该是编写代码各个阶段不可分割的基本组成部分。

其他工程师与代码契约

1、你的代码和其他工程师的代码

如果你以团队一员的身份编写代码,你所编写的代码很可能建立在其他工程师编写的代码层次的基础上,其他人也可能以你的代码为基础构建新的代码层次。如果你在工作期间解决了各种各样的子问题,并将其分解为清晰的抽象层次,其他工程师也有可能重用其中一些代码,去解决你可能没有考虑过的、完全不同的问题。

2、其他人如何领会你的代码的使用方法

当其他工程师需要利用你的代码或者修改一些对其有依赖的代码,就必须领会你的代码的使用方法及其功能。具体地说,他们必须理解如下要素:

〓● 在哪些场景下,他们应该调用你提供的各种函数;

〓● 你创建的类代表什么,应该在什么时候使用;

〓● 他们应该以什么值调用;

〓● 你的代码将执行什么操作;

〓● 你的代码可能返回什么值。

3、代码契约

工程师有时会发现,将关于代码契约的术语分成不同类别很有用。

〓● 先决条件——调用代码时应该满足的条件,例如系统应处在的状态和提供给代码的输入。

〓● 后置条件——调用代码后应该成立的条件,例如系统被置于某个新状态或者返回某些值。

〓● 不变量——对比代码调用前后的系统状态时应该保持不变的事物。

即便你不是有意地采用契约式编程,甚至从未听说过这个术语,你编写的代码也肯定存在某种契约。如果你编写了一个有输入参数、返回某个值或修改一些状态的函数,就创建了一个契约,因为你在代码调用者身上加注了一项义务:建立某种状态或者提供输入(先决条件),并给予他们关于将要发生的事情或返回值的预期(后置条件)。

当工程师不知道代码契约的某些或者全部条款时,就会出现问题。在编写代码时,重要的是考虑契约的内容,以及如何确保使用代码的每个人都了解并遵循契约。

4、检查和断言

使用编译器强制代码契约的一种替代方法是使用运行时强制。这通常不像编译时强制那么健全,因为代码契约漏洞的发现取决于一项测试(或者一个用户)运行代码时遇到的问题。这与编译时强制形成了鲜明对比,后者从一开始就在逻辑上消除了违反契约的可能性。

尽管如此,在有些情况下,没有切合实际的手段能用编译器强制实施一个契约。发生这些情况时,以运行时检查强制实施契约好于没有强制手段。

以上内容摘自《好代码 ,坏代码》第一章,第三章。

好代码 ,坏代码

Google开发工程师从零讲解高质量代码,整合作者及团队多年的软件开发实践经验,通过50+条锦囊妙计、100+个案例,帮你轻松理解和掌握编程技能。

本书分享的实用技巧可以帮助你编写鲁棒、可靠且易于团队成员理解和适应不断变化需求的代码。内容涉及如何像高效的软件工程师一样思考代码,如何编写读起来像一个结构良好的句子的函数,如何确保代码可靠且无错误,如何进行有效的单元测试,如何识别可能导致问题的代码并对其进行改进,如何编写可重用并适应新需求的代码,如何提高读者的中长期生产力,同时还介绍了如何节省开发人员及团队的宝贵时间,等等。


养成好的编程习惯,一定要必备这两本程序员经典书。

重构:改善既有代码的设计(第2版)

本书是一本为专业程序员编写的重构指南。我的目的是告诉你如何以一种可控且高效的方式进行重构。你将学会如何有条不紊地改进程序结构,而且不会引入错误,这就是正确的重构方式。

按照传统,图书应该以概念介绍开头。尽管我也同意这个原则,但是我发现以概括性的讨论或定义来介绍重构,实在不是一件容易的事。因此,我决定用一个实例作为开路先锋。第1章展示了一个小程序,其中有些常见的设计缺陷,我把它重构得更容易理解和修改。其间你可以看到重构的过程,以及几个很有用的重构手法。如果你想知道重构到底是怎么回事,这一章不可不读。

第2章讨论重构的一般性原则、定义,以及进行重构的原因,我也大致介绍了重构面临的一些挑战。第3章由Kent Beck介绍如何嗅出代码中的“坏味道”,以及如何运用重构清除这些“坏味道”。测试在重构中扮演着非常重要的角色,第4章介绍如何在代码中构筑测试。

从第5章往后的篇幅就是本书的核心部分——重构名录。尽管不能说是一份巨细靡遗的列表,却足以覆盖大多数开发者可能用到的关键重构手法。

代码整洁之道

本书大致可分为3个部分。前几章介绍编写整洁代码的原则、模式和实践。这部分有相当多的示例代码,读起来颇具挑战性。读完这几章,就为阅读第2部分做好了准备。如果你就此止步,只能祝你好运啦!

第2部分最需要花工夫。这部分包括几个复杂性不断增加的案例研究。每个案例都清理一些代码——把有问题的代码转化为问题少一些的代码。这部分极为详细。你的思维要在讲解和代码段之间跳来跳去。你得分析和理解那些代码,琢磨每次修改的来龙去脉。

你付出的劳动将在第3部分得到回报。这部分只有一章,列出从上述案例研究中得到的启示和灵感。在遍览和清理案例中的代码时,我们把每个操作理由记录为一种启示或灵感。我们尝试去理解自己对阅读和修改代码的反应,尽力了解为什么会有这样的感受、为什么会如此行事。结果得到了一套描述在编写、阅读、清理代码时思维方式的知识库。

如果你在阅读第2部分的案例研究时没有好好用功,那么这套知识库对你来说可能所值无几。在这些案例研究中,每次修改都仔细注明了相关启示的标号。这些标号用方括号标出,如:[H22]。由此你可以看到这些启示在何种环境下被应用和编写。启示本身不值钱,启示与案例研究中清理代码的具体决策之间的关系才有价值。

如果你跳过案例研究部分,只阅读了第1部分和第3部分,那就不过是又看了一本关于写出好软件的“感觉不错”的书。但如果你肯花时间琢磨那些案例,亦步亦趋——站在作者的角度,迫使自己以作者的思维路径考虑问题,就能更深刻地理解这些原则、模式、实践和启示。这样的话,就像一个熟练地掌握了骑车的技术后,自行车就如同其身体的延伸部分那样;对你来说,本书所介绍的整洁代码的原则、模式、实践和启示就成为了本身具有的技艺,而不再是“感觉不错”的知识。

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

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

相关文章

LeetCode 49 字母异位词分组 | 解题思路分享

原题链接:49. 字母异位词分组 - 力扣(LeetCode) 题目难度:中等 题目描述 给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的字母得到的一个新单词…

分析快、易操作的数据分析工具推荐

数据分析工具发展这么多年,该有的技术功能都有了,该提高的数据分析效率、数据分析量等也都提高了,但很多长期奋战在一线的数据分析人员却总是抱怨数据分析工具响应慢、分析慢、越来越容易崩溃。为什么要找一款分析快、易操作的数据分析工具还…

Git入门学习笔记(10分钟速通)

一、Git概述 官网翻译: Git 是一个免费的开源 分布式版本控制系统,旨在快速高效地处理从小型项目到大型项目的所有内容。 Git易于学习, 体积小,性能快如闪电。它超越了 Subversion、CVS、Perforce 和 ClearCase 等 SCM 工具&am…

13_2、Java的IO流概述

一、Java IO原理1、I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于处理设备之间的数据传输。如读/写文件,网络通讯等。2、Java程序中,对于数据的输入/输出操作以“流(stream)” 的方式进行。3、java.io包下提供了各种“流…

kaggle平台学习复习笔记 | XGBoost、LightGBM and Catboost

这里写目录1.XGBoost官方文档介绍与使用2.LightGBM官方文档介绍与使用3.CatBoost官方文档介绍与使用对比数据预处理如下,下文不再重复 import lightgbm as lgb import xgboost as xgb from catboost import CatBoostRegressorfrom sklearn.model_selection import …

C#入门级——泛型、泛型类、泛型接口、泛型方法和泛型委托

目录 一、泛型(generic) 二、为什么需要泛型类 类型膨胀 成员膨胀 使用object类 三、泛型的定义 定义泛型类 使用泛型类 泛型接口​​​​​​​ 两种泛型接口的实现方法 泛型方法 成员膨胀 使用泛型 泛型委托 Action委托——只能引用没有…

有效的需求管理,需遵循四大原则。

1、需求管理必须与需求工程活动相整合 需求管理必须与需求工程的其他活动紧密整合,进行需求管理一定不能脱离需求工程,需求工程包括了需求获取、需求分析、需求描述、需求验证、需求管理,因而需求管理必须与前面的几个需求阶段保持密切相关。…

2023/1/9 Vue学习笔记-5-TodoList案例

1 静态组件 App.vue <template><div class"todo-container"><div class"todo-wrap"><UserHeader/><UserList/><UserFooter/></div></div> </template> <script>import UserHeader from &qu…

【计组】FPGA和ASIC--《深入浅出计算机组成原理》(七)

课程链接&#xff1a;深入浅出计算机组成原理_组成原理_计算机基础-极客时间 目录 一、FPGA &#xff08;一&#xff09;FPGA 的解决方案步骤 1、用存储换功能实现组合逻辑 2、对于需要实现的时序逻辑电路&#xff0c;在 FPGA 里面直接放上 D 触发器&#xff0c;作为寄存…

工业清洗企业资质证书

工业清洗在美国、日本、新加坡、西欧等国发展较早&#xff0c;已经建立起专业化程度很高的化学清洗体系。我国的工业清洗发展很快&#xff0c;目前已经初步形成了新兴的清洗产业网络&#xff0c;清洗技术也已达到国际先进水平&#xff0c;具备了清洗大型设备的能力和经验。 工业…

CANoe-诊断控制台实现同一个目标ECU的物理寻址和功能寻址

接触过UDS诊断的人应该知道,诊断通信有两种方式:物理寻址和功能寻址。那什么是物理寻址和功能寻址呢? 简单点说,物理寻址是单播,功能寻址是多播。具体来说,由于UDS诊断通信的C/S模式(客户端Tester/服务器ECU),物理寻址是Tester发送的诊断请求,只有一个目标ECU回复诊…

MySQL模块

目录 1.在项目中操作数据库的步骤 2.安装与配置 mysql 模块 1.安装模块 2.配置mysql模块 3.测试模块是否正常工作 3.使用 mysql 模块操作 MySQL 数据库 查询数据&#xff1a; 插入数据&#xff1a; 快捷插入数据&#xff1a; 更新数据&#xff1a; 快捷更新数据&am…

node.js(3)--线程和进程、node简介

目录 进程和线程 Node.js 简介 历史 进程和线程 进程 负责为程序的运行提供必备的环境就相当于工厂中的车间&#xff08;专门存放代码的地方&#xff09; 线程 计算机中最小的计算单位&#xff0c;线程负责进程中的程序就相当于工厂中的工人 单线程 JS是单线程 多线程 …

ansible (第三天)

2.6 lineinfile模块 lineinfile模块&#xff0c;确保"某一行文本"存在于指定的文件中&#xff0c;或者确保从文件中删除指定的"文本"&#xff08;即确保指 定的文本不存在于文件中&#xff09;&#xff0c;还可以根据正则表达式&#xff0c;替换"某一…

测牛学堂:软件测试python基础学习之数据类型详解(一)

python数据类型详解 为什么需要数据类型呢&#xff1f; 我们人脑可以轻松的区别不同类型的数据&#xff0c;比如看到1你就知道是数字&#xff0c;但是计算机做不到。 计算机工作的过程就是完成不同的类型的计算&#xff0c;例如做数学运算&#xff0c;做文件存储&#xff0c;逻…

【技术分享】Windows平台低延迟RTMP、RTSP播放器接口设计探讨

背景我们看过了太多介绍RTSP、RTMP播放相关的技术资料&#xff0c;大多接口设计简约&#xff0c;延迟和扩展能力也受到一定的局限&#xff0c;好多开发者希望我们能从接口设计的角度&#xff0c;大概介绍下大牛直播SDK关于RTMP、RTSP播放器开发设计&#xff0c;本文以Windows平…

redis 运维讲解02

一、数据持久化 1、为什么要持久化 redis 重启后&#xff0c;redis 存在内存数据中数据丢失&#xff0c;不管之前是多少G数据&#xff0c;秒丢&#xff0c;而且无法恢复&#xff0c;数据在内存中 [root86-5-master ~]# redis-cli -p 6379 127.0.0.1:6379> MSET k1 v1 k2…

浏览器相关知识

本文主要进行浏览器相关知识的整理总结。 一、浏览器的存储 浏览器的存储包括cookie&#xff0c;session&#xff0c;LocalStorage&#xff0c;sessionStorage&#xff0c;indexedDB。 作用cookiesessionsessionStorageLocalStorageindexedDB储存时间设置或不设置默认30分钟仅…

就只有这么简单?全自动加药装置远程维护解决方案

一、行业背景说起工业生产&#xff0c;给人们的普遍印象都是浓烟&#xff0c;废水&#xff0c;环境污染。尤其是石油、化工、发电厂等一些具有大型设备的地方&#xff0c;确实常常都会有浓烟和污水产出&#xff0c;让人看了恨不得离得越远越好&#xff01;但是随着现代科技的发…

java和vue开发的电子书系统自动检测敏感词小说网站

简介 电子书系统&#xff0c;注册用户上传txt&#xff0c;系统自动检测敏感词汇并且自动生成章节。管理员审核电子书&#xff0c;管理电子书分类和用户&#xff0c;评论等。注册用户可以搜索浏览电子书&#xff0c;在线阅读和下载电子书。 演示视频&#xff1a;https://www.b…