好代码 ,坏代码:你的代码和其他工程师的代码

news2024/11/13 9:40:29

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

为了说明这一点,想象你在一家运营在线杂志的公司工作,用户可以在该杂志上查找和阅读文章。你的任务是编写文本摘要功能,在用户查找阅读内容时为其提供文章的摘要。你最后写出了我们在第2章中看到的代码——包含TextSummarizer和相关的几个类。(如果你不记得确切的代码或者跳过了第2章,无须担心。)图3-1展示了你编写并最终在软件中使用的文本摘要代码。可以看到,你的代码依赖于其他工程师编写的低层次代码,其他工程师反过来依靠你的代码解决更高层次的问题。还可以看到,你的代码在多项功能中得到重用。你最初可能只预计到它在文章摘要上的用途,但其他工程师继续重用它(或者它的一部分)来摘要评论和估计文章的阅读时间。

另外值得注意的重要问题是,需求一直都在变化和发展:优先考虑的事项发生变化、需要增加新功能、系统有时需要采用新技术等。这意味着,代码和软件也总是在变化。图3-1展示了软件的快照,软件不太可能在一年甚至几个月内完全保持这种面貌。

图3-1 你编写的代码很少是与世隔绝的。它依赖于其他工程师编写的代码,相反,其他工程师编写的代码也可能依赖于你的代码

一组工程师在持续修改代码库,使其成为一个热闹的地方。与任何热闹的地方一样,脆弱的东西很容易被打破。当你举办一场大型聚会的时候,有理由把精美的玻璃器具收起来,同样,体育馆的栏杆用金属制成,并固定在地板上:脆弱的东西不适合于热闹的地方。

为了经受住其他工程师的这种“踩踏”,代码必须鲁棒且易于使用。编写高质量代码时的主要考虑因素之一就是理解和预判在其他工程师做出更改或者必须与你的代码打交道时,可能出现什么不良状况,你又该如何应对这些风险。除非你在只有一位工程师的公司工作,而且从来不会忘记任何事情,否则要编写出高质量代码就不可能不考虑其他工程师。

编写代码时,考虑如下3件事是很有帮助的(后面的内容将详细探讨):

〓● 对你来说显而易见,但对其他人并不清晰的事情;

〓● 其他工程师无意间试图破坏你的代码;

〓● 过段时间,你会忘记自己的代码的相关情况。

3.1.1 对你来说显而易见,但对其他人并不清晰的事情

当你着手编写代码时,可能已经花了几个小时甚至几天的时间考虑所要解决的问题。你可能经历了设计、用户体验测试、产品反馈或缺陷报告等多个阶段,对其中的逻辑十分熟悉,一切看起来似乎都是显而易见的,你几乎不需要思考情况为何是这样的,或者你为何要这样解决问题。

但请记住,在某个时间,其他工程师可能需要与你的代码打交道,对其进行修改或者改变代码所依赖的因素。他们不可能像你那样花费大量时间去理解问题、思考解决方案。在你编写代码的时候觉得显而易见的事情,对他们来说很可能不那么明显。

始终考虑这一点,并确保你的代码能够解释其使用方法、功能和开发这些功能的原因。正如你在本章及随后的章节中将要学到的,这并不意味着写一大堆注释。使代码易于理解、不言自明往往是更好的办法。

3.1.2 其他工程师无意间试图破坏你的代码

假设其他工程师无意间试图破坏你的代码,这看起来似乎过于悲观,但正如我们刚刚看到的,你的代码并不存在于真空中,它可能依赖于多个其他代码段,而这些代码段又依赖于更多的代码段,同时,可能也有更多的代码段依赖于你的代码。由于其他工程师添加功能、重构和修改,有些代码段将一直处于变化中。所以,你的代码远非在真空中,实际上处在不断变化中,而以它为基础构建的部件也在不断变化。

对你来说,你的代码可能就是全世界,但公司中其他大部分工程师可能对它并没有太多的了解,当他们偶然看到这段代码时,也不一定预先知道它存在的理由和功能。其他工程师很可能在某个时间添加或修改一些代码,无意间破坏或误用了你的代码。

正如我们在第1章中所见到的,工程师通常对代码库的本地副本进行修改,然后将其提交到代码库。如果代码没有编译或者测试失败,就不可能提交他们的更改。如果其他工程师的更改破坏或者误用了你的代码,你应该确保在他们修复所引发的问题之前,更改不会提交到代码库。只有两种可靠的方法能做到这一点:在发生破坏时,要么停止编译代码,要么测试失败。围绕高质量代码编写的许多考虑因素,最终都是为了确保出现破坏时能发生上面的两种情况之一。

3.1.3 过段时间,你会忘记自己的代码的相关情况

现在,代码细节在你的脑海里如此新鲜和重要,以至于无法想象会忘记它们,但经过一段时间,它们不再新鲜了,你就会开始忘却。如果一年以后出现了新功能或者你被安排去解决一个缺陷,你可能不得不修改自己写的那段代码,或许再也记不清所有细节了。

3.1.1节和3.1.2节所说的情况——对其他人不是那么显而易见,或者其他人破坏你的代码——可能在某个时间适用于你。查看一两年前自己写的代码和查看其他人写的代码没什么两样。因此,必须确保你的代码即使对毫无背景知识的人来说也是容易理解的,并使其难以遭到破坏。你不仅要做有利于其他人的事情,也要做有利于未来的自己的事情。

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

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

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

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

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

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

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

正如你刚刚在3.1节中看到的,经过一年,你很有可能忘记了自己的代码的所有细节,因此,为了理解本书的所有内容,你可以从本质上将未来的自己当成其他查看你编写的代码的工程师。为了领会代码的使用方法,其他工程师可以做如下事情:

〓● 查看代码元素(函数、类、枚举类型等)的名称;

〓● 查看代码元素的数据类型(函数和构造程序参数类型与返回值类型);

〓● 阅读所有文档或函数/类级注释;

〓● 当面或通过聊天程序/电子邮件询问你;

〓● 查看你的代码(你所写的函数和类的实现细节)。

在后面的内容中我们将看到,上述方法中只有前3种切实可行,其中代码元素的名称和数据类型往往比文档更可靠。

3.2.1 查看代码元素的名称

在实践中,观察代码元素的名称是工程师领会新代码段使用方法的主要手段之一。包、类和函数的名称有点像书的目录:它们是查找解决子问题代码使用方法的便利、快捷手段。使用代码时,很难忽视元素名称:removeEntry()函数不容易与addEntry()函数混淆。

因此,恰当地命名代码元素是向其他工程师传达代码的使用方式的手段之一。

本文摘自《好代码 ,坏代码》

软件工程师在不断积累经验的过程中会发现,日常编程中所做出的决策对于软件的正常运行、工作的顺利开展以及其他人的维护有很大的影响。学习编写(从软件工程角度来看)优良代码需要花费许多年的时间。这些技能的获得过程往往很缓慢。工程师从自己的错误中吸取教训,或者不断从团队的资深工程师那里得到建议,以特定的方式得到这些技能。

本书旨在帮助刚入门的软件工程师获取这些技能。它将传授一些非常重要的经验教训和基础理论,帮助读者编写可靠的、易于维护且能够适应不断变化需求的代码。

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

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

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

相关文章

WebDAV之葫芦儿·派盘+百灵创作

百灵创作 支持webdav方式连接葫芦儿派盘。 心血来潮想写故事,于是进入了创作、码字状态,不写不知道一码吓一跳,这也太累了吧。 基于创作不易,码字辛苦。对文字,我始终怀有尊重与敬畏之心。不知有什么创作码字软件可以解决这些问题,提高写作效率呢?并且防止写好的文章…

spring框架源码十六、BeanDefinition加载注册子流程

BeanDefinition加载注册子流程时序图时序图1step0、new ClassPathXmlApplicationContextstep1、ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String)step2、ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String[],…

初识类和对象

即使是初学者应该对类和对象也不算陌生吧,是不是因为老有些人动不动就:你知道伐,Java是一款面向对象的语言……阿巴阿巴……我的老师告诉我Java难的一部分就是如何把一个对象给抽象出来,那阿涛不才,今天就先来会一会这…

超市售货统计程序

代码price{"牛奶":5.5,"可乐":6.7,"饼干":10,"糖果":10} day1{"day":"11.23","牛奶":10,"可乐":10,"饼干":10,"糖果":10} day2{"day":"11.24",&quo…

机器学习笔记之条件随机场(六)学习任务介绍(Learning)

机器学习笔记之条件随机场——学习任务介绍引言回顾:条件随机场求解边缘概率分布场景设计前向后向算法关于条件随机场的学习任务关于模型参数λ\lambdaλ求解梯度梯度求解梯度的简化过程总结引言 上一节介绍了使用前向后向算法求解基于链式条件随机场中某隐状态的边…

MySQL—优化数据库

优化MySQL数据库是数据库管理员的必备技能,通过不同的优化方式达到提高MySQL数据库性能的目的。本节将介绍优化的基本知识。 MySQL数据库的用户和数据非常少的时候,很难判断一个MySQL数据库性能的好坏。只有当长时间运行,并且有大量用户进行…

GoogLenet网络详解

GoogLenet VGG在2014年由牛津大学著名研究组vGG (Visual Geometry Group)提出,斩获该年lmageNet竞赛中Localization Task (定位任务)第一名和 Classification Task (分类任务)第二名。Classification Task (分类任务)的第一名则是GoogleNet 。GoogleNet是Google研发…

vue-router 使用与原理分析,测试结果来啦

简介 Vue Router 是Vue.js的官方路由。与Vue.js核心深度集成,让用Vue.js构建单页应用(SPA)变得更加简单。 对于开发和维护管理后台类的前端项目,页面结构和组合可能非常复杂,所以正确的理解和使用Vue Router就显得尤为…

[附源码]SSM计算机毕业设计ssm新冠疫苗预约接种信息管理JAVA

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

Spring事务管理

认识事务 可以把一系列(多条sql语句)要执行的操作称为事务,而事务管理就是管理这些操作要么完全执行,要么完全不执行(很经典的一个例子是:A要给B转钱,首先A的钱减少了,但是突然的数…

EMQX数据流转MySQL踩坑日记:EMQX VER 4.2.3

总结: (0)数据库报错问题,详细参考这篇文档,链接,ln -s 源 目标 https://blog.csdn.net/weixin_42110159/article/details/118945136 (1)数据库建立数据,要注意大小写&am…

数字化开采|AIRIOT智慧矿山自动化生产解决方案

由于矿山地形复杂,生产自动化水平低,安全监管技术落后,事故频发等很多因素对煤矿开采技术提出了数据化、可视化、智能化的要求。通过目前的煤矿开采现状可以发现煤矿开采过程中,在生产、监管、巡检、安全、效率等方面还存在许多有…

图文详解Linux基础经典教程(08)——CentOS安装MySQL数据库

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl 概述 之前,我们在CentOS中安装了JDK、Tomcat;接下来,我们在CentOS中采用YUM的方式安装MySQL5.6数据库。 安装前准备工作 在此&#xf…

面试常用算法归纳

最长子串、子序列 先说明下子串和子序列的问题:对于s “pwwkew"来说,其中一个子串为"wke”,而"pwke" 是一个子序列。 子序列:一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改…

基于Matlab通用视频处理系统的设计-含Matlab代码

⭕⭕ 目 录 ⭕⭕⏩ 一、引言⏩ 二、系统总体方案设计⏩ 2.1 方案设计⏩ 2.2 界面设计⏩ 三、实例分析⏩ 四、参考文献⏩ 五、Matlab程序获取⏩ 一、引言 随着信息技术的发展,基于视频图像中对感兴趣的目标提取,已经逐渐渗透到人们生活的方方面面&#x…

[附源码]SSM计算机毕业设计“拥抱爱心”公益网站管理系统JAVA

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

VMware Workstation 与 Device/Credential Guard 不兼容问题

系列文章目录 VMware Workstation 与 Device/Credential Guard 不兼容问题 VMware Workstation 与 Device/Credential Guard 不兼容问题系列文章目录一、原因二、解决办法2.1修改虚拟化安全设备为禁用2.2HV主机服务启动类型设置 为 “禁用”2.3关闭 Hyper-V 并且打开虚拟机平台…

CUDA By Example(六)——纹理内存

在本章中,我们将学习如何分配和使用纹理内存(Texture Memory)。和常量内存一样,纹理内存是另一种类型的只读内存,在特定的访问模式中,纹理内存同样能够提升性能并减少内存流量。虽然纹理内存最初是针对传统的图形处理应用程序而设…

Linux学习-43-挂载Linux系统外的文件mount和卸载文件系统umount命令用法

10.10 mount命令详解:挂载Linux系统外的文件 所有的硬件设备必须挂载之后才能使用(新硬盘先格式化后创建分区,再对分区进行挂载),只不过,有些硬件设备(比如硬盘分区)在每次系统启动…

记录一次我虚拟机好不容易连上后的配置

有一说一,看到这个响应,人都麻了 在此我记录一下我检查了哪些,做了哪些 一、Windows本地服务 这一块,有一个算一个,没起的启动,启动的重启 二、VMware的虚拟网络编辑器设置 因为我这次成功用的是NAT模式&a…