IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 重读【代码整洁之道】 -> 正文阅读

[开发测试]重读【代码整洁之道】

520604fa9918a4faac830c028bfab9cd.png

一、前言

【代码整洁之道】很经典,但也有些过时,翻译上也有些啰嗦,但总体上是好书。通过对本书核心内容的摘抄,结合自己的经验,整理了一些精简的点,这样你就省的去啃那本400多页的书了。

软件质量 = 架构设计 + 项目管理 + 代码质量。

架构设计:像建筑师设计的一个宏伟建筑的设计图。

项目管理:专注于敏捷、快速的将产品推向市场。

代码质量:确保交付的产品稳定、持久的提供它的特性。

软件工程打造的数字化产品不同于传统的建筑、车辆等产品,他有极强的迭代、维护需求。代码是一个宏大产品的小细节,但东西方的很多寓言故事中都透露着,细节的重要性:

守小节者不亏大节

及时一针省九针

早起的鸟儿有虫吃

日事日毕

防病好过治病

还有扁鹊与蔡桓公的故事

关注细节深埋于人类壮丽的文化、智慧之下。但人性的弱点,往往让我们追求宏大的叙事,而忽视了细节的打磨。

插播一下,为什么大家最近经常谈内卷?为什么日本有工匠精神?

通过对比发达国家发展来看,经历了高速发展之后,低速发展阶段更注重质量的打磨,所以内卷不是毫无意义,而是低速发展时代的必经产物。

干净的代码,即在质量上较为可靠,也为后期维护、升级、扩展奠定了基础。

代码整洁之道提供了一条条规则,以提升代码质量。

认真对待每个命名,如同给孩子起名一样谨慎。

其他的还包括:命名、函数、注释、代码格式、对象、数据结构、错误处理、边界问题、单元测试、类、系统、并发编程等方面。

二、如何提高代码质量

有什么标准识别代码质量好坏?

WTF / min

dcfde4ec0040345b321bbb0f6e82c801.png? ? ?

通过两扇门后传出的脏话数量判断,右侧团队的代码质量应该很差。

写整洁代码很难,不是你掌握了原则和模式就可以写好。你得在上面花功夫,多实践,多看看别人如何绞尽脑汁做出决策,又是如何为错误付出代价的。琢磨某段代码好在什么地方、坏在什么地方。

写整洁代码,需要遵循大量的小技巧,写出有“代码感”的代码,“代码感”帮助程序员选出最好的方案。

  1. 没有“代码感”的程序员,看混乱是混乱,无处着手,走一步算一步;

  2. 有“代码感”的程序员,能从混乱中看到其他可能的变化;

怎么看待整洁代码?看看行业大牛怎么说

C++语言发明人Bjarne说:

代码逻辑应该直接了当,叫缺陷难以隐藏;尽量减少依赖关系,使之便于维护;通过某种分层战略约束错误处理代码。

Bjarne认为,整洁的代码读起来令人愉悦。

糟糕的代码想做的事太多,意图混乱、目标含混。

整洁的代码力求集中,每个函数、每个类、每个模块都专注于做一件事,而不会受到外围细节的干扰。

整洁代码注重表达力,小规模抽象

代码应该讲述事实,不引人猜测,应该更果断决绝。整洁的代码可读性更强,也便于其他人增补逻辑,有很好的易修改性。

没有测试的代码是不干净的。

代码块,越小越好。

有意义的命名,是体现表达力的一种方式,表达力还体现在方法是否想做的事情太多上。如果方法里面功能太多,那么需要抽取出来。

有意义的命名

略。。。

函数编码要求

第一原则:要短小。(20行最多)

不短小就不是函数了,那是类。

第二原则:只做一件事,且做好这件事。

函数中语句都要在同一个抽象层级上,函数如果杂糅不同抽象层级,往往让人迷惑。

长而具有描述性的名称,比短而令人费解的名称好。

第三原则:避免多参数,最理想是零个参数,其次是一个,再次是两个,尽量避免三个。

三个以上可能确实多了,可以通过重载方式实现。

bad case:向函数传入布尔值骇人听闻,里面让函数复杂起来,代表函数不只做一件事。

第四原则:try/catch代码块的处理,最好把代码块主体抽离出来,如下:

471862e152ce5592502dba730b371b0f.png

第五原则:不要重复自己。

第六原则:不要将null传递给方法,除非API要求。

单元测试

TDD要求,在编写生产代码之前,先编写单元测试。

类的原则

第一原则:类应该短小。

多小合适呢?对于函数我们可以要求代码行数,对于类来说,我们要求权责。

如果一个类里面有几十个函数,那它就是个bad class。5个方法不算多,这样类的权责也更可控。

第二原则:类名应该描述其权责。

一个类名是含糊的,它未来拥有的权责就会太多。比如Manager、Process、Super这种类名就太含糊。

遵照面向对象的“单一职能原则”,类模块有且只有一条加以修改的理由,是类权责的定义。

鉴别了类的权责,可以帮助我们做更好的类抽象。

类太多怎么办?用包组织起来。

第三原则:多个类之间,将类的构造与使用分开。

常量与枚举

enum可以拥有更多方法和字段,从而比常量提供更多的表达力和灵活性,所以在常量与枚举之间,如果需要更多的信息表达,推荐用枚举。

三、识别代码的坏味道

那如何识别系统中存在的坏味道呢?有个清单可以参考使用。

注释的坏味道

1)不恰当的信息:注释应只描述有关代码和设计的技术性信息。

2)废弃的注释:过时、无关、不正确的注释就是废弃的注释,废弃的注释应该及时被更新或删除。

3)冗余注释:注释应该谈及代码自身没提到的东西。

4)写值得写的注释:值得写、保持简洁。

5)注释掉的代码:被注释掉的代码,没人知道他的意义,看到注释掉的代码,就删除它。

函数的坏味道

1)过多的参数:函数的参数数量应该少,没参数最好,一个次之,两个、三个再次之。三个以上值得商榷,应该避免。

2)输出参数:参数用于输入而非输出,所以不要通过一个函数获取输入参数的变更,违反直觉。

3)布尔参数:如果参数是布尔值,这个函数就会不止做一件事,它令人迷惑,应该消灭。

4)死函数:不再被调用的函数应该丢弃,别害怕删除函数。

5)忽视安全:函数代码不要轻易挂了,必要的非空判断还是要有的。

6)重复:DRY原则,每次看到重复的代码,就代表了没有抽象,重构那些看起来一样的代码。

7)错误的抽象层次:代码可以简单的抽象成基类能力和细节能力,基类应该对细节(派生类)一无所知,这条规则适用于源文件、组件、模块与系统。良好的软件设计要求分离位于不同层级的概念。低层抽象概念和较高级抽象概念不应该混杂在一起。

af95a7e34faaaa1f8a490108b5ba84d6.png

8)信息过多:前面的很多原则体现了短、少的概念,如果一个类、函数信息过多,某种程度代表他是有问题的。设计良好的接口不提供许多需要依靠的函数,所以耦合度也较低。设计低劣的接口提供大量你必须调用的接口,耦合度也高。优秀的开发人员应该学会限制类或模块暴露的接口数量,类里面的方法越少越好,函数知道的变量越少越好,类拥有的实体变量越少越好。太多了说明你抽象的还不够。

9)垂直距离最短:变量和函数应该在靠近被使用的地方定义。本地变量应该正好定义在其首次被使用的位置上声明,确保定义与使用垂直距离最短,本地变量不应该放在其被使用之外的几百行以外声明。

10)人为耦合:不相互依赖的东西不应该耦合,两个没有直接相关的模块产生耦合的原因在于变量、常量、枚举、函数被临时放在了不正确的位置上,背后是偷懒行为。应该花时间研究在什么地方声明函数、常量、变量,不要随手放置。

11)依恋行为:类方法只应该对其所属类中的变量和函数感兴趣,不应该对其他类中的变量和函数产生依赖。

12)最小惊讶原则:代码应该放在读者自然而然期待他所在的地方,比如PI常量应该出现在声明三角函数的地方。

13)函数名称应表达其行为,如:

e16c534bf79984df2dd44c255df09b62.png

14)常量名代替魔术数。

15)封装条件,如:

3279510cbafc5ff20c33a393870d2e92.png

16)避免否定性条件,如:

dbe3f58033e6594f97bdc67a9ba5db3a.png

17)函数只做一件事:如果要做多件事,拆成更多的更小的函数,每个只做一件事。

18)调用顺序应该显而易见,如:

b00c9afd88ab51880c1c0e128f41e3c9.png

四、面向对象

行文至此,发现写好整洁代码,除了短、小、命名这些原则之外,面向对象原则同样非常重要。

面向对象是业务系统编码非常重要的思想,很多解决复杂业务问题的设计模式与设计思想都遵循面向对象思想,比如设计模式和领域驱动,你是不是都可以发现面向对象的影子呢?

五大基本原则(S.O.L.I.D)

1)单一职能原则SRP:一个类功能要单一,一个类负责一个职责,这个类被修改的原因是因为职责变化了;

2)开放封闭原则OCP:一个类要具有扩展性的开放,更改性的封闭,背后体现的是灵活性、重用性、可维护性,同样要求有很好的抽象能力,也就是面向接口编程,而不是面向实现编程,抽象是稳定的;

3)替换原则LSP:子类可以替换父类出现在父类能够出现的任何地方,这个原则是GOF倡导的面向接口编程,父类尽可能使用接口或抽象类实现,他非常好的价值在于,帮助我们看到继承关系的定义;

4)接口隔离原则ISP:使用专门的接口比简单单个接口要好很多,模块之间通过抽象接口进行通信,而不是通过类的强耦合;

5)依赖倒置原则DIP:高层模块不依赖底层模块,依托于很好的抽象能力,细节依赖具体;

五、最后

《代码整洁之道》聊的不只是代码,更多是程序员的职业素养。

程序员不应该仅仅满足于让代码能工作,还需要考虑到可读性、可扩展、可迭代。解决之道是保持代码持续的整洁与简单。

日常编码过程中不是简单的遵守这些实践,而是要思考下这样写有什么好处。

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-10-01 17:11:21  更:2021-10-01 17:11:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 0:36:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码