代码整洁之道精华——第十七章 味道与启发

阅读本文有两种原因:第一,你是个程序员;第二,你想成为更好的程序员。你如果想成为更好的程序员,那就请细细品味文章内容,它绝不会让你失望。
代码整洁之道教给大家如何编写整洁的代码,而不仅仅是能运行的代码,这对于编程者而言很重要。我在读这本书的第一遍时没什么感觉,但在读第二遍时觉得它确实挺不错的,如果有机会的话我会读第三遍。下面是我在读书过程中摘录的精华内容,希望大家认真对待。各位看官如果读完本文觉得书中的精华内容挺合自己的胃口,那就可以抽出时间认真地读一下这本书。

1、代码应该有正确行为。这话看似明白,问题是我们很少能明白正确的行为有多复杂。开发着常常写出他们以为能工作的函数,信赖自己的直觉,而不是努力去证明代码在所有的角落和边界情况下真能工作。
没有什么可以代替谨小慎微。每种边界条件、每种极端情形、每个异常都代表了某种可能搞乱优雅而直白的算法的东西。别信赖直觉,追踪每种边界条件,并编写测试。
2、创建分离较高层级一般性概念与较低层级细节概念的抽象模型,这很重要。有时我们创建抽象类来容纳较高层级概念,创建派生类来容纳较低层级概念。这样做的时候,需要确保分离完整。所有较低层级概念放在派生类中,所有较高层级概念放在基类中。
这条规则对于源文件、组件和模块也适用。良好的软件设计要求分离位于不同层级的概念,将他们放到不同的容器中。有时这些容器是基类或派生类,有时是源文件、组件或模块。无论哪种情况,分离都要完整,较低层级概念和较高层级概念不应混在一起。
3、如果看到基类提到派生类的名称,就可能发现了问题。通常来说,基类对派生类应该一无所知。
当然也有例外,有时派生类数量严格固定,而基类中拥有在派生类之间选择的代码。在有限状态机的实现中这种情形很多见,在那种情况下,派生类和基类紧密耦合,总是在同一个jar文件中部署。一般情况下,我们会把派生类和基类部署到不同的jar文件中,确保基类jar文件对派生类jar文件的内容一无所知,我们就能把系统部署为分散和独立的组件。修改了这些组件时,不必重新部署基组件就能部署它们。这意味着修改产生的影响极大地降低了,而维护系统也变得更加简单。
4、设计良好的模块有着非常小的接口,让你事半功倍。设计低劣的模块有着广阔、深入的接口,让你不得不事倍功半。设计良好的接口并不提供许多需要依靠的函数,所以耦合度也较低。设计低劣的接口提供大量你必须调用的函数,耦合度较高。
优秀的软件开发人员应该学会限制类或模块中暴露的接口数量。类中的方法越少越好,函数知道的变量越少越好,类拥有的实体变量越少越好。
隐藏你的数据,隐藏你的工具函数,隐藏你的常量和临时变量。不要创建拥有大量方法或大量实体变量的类,不要为子类创建大量受保护的变量和函数。尽力保持接口紧凑,通过限制信息来控制耦合度。
5、类的方法只应对其所属类中的变量和函数感兴趣,不该垂青其他类中的变量和函数。当方法通过某个其他对象A的访问器和修改器来操作A对象的内部数据,则它就依恋于A对象所属类的范围。他期望自己在那个类里面,这样就能直接访问他操作的变量。
6、选择算子参数只是一种避免把大函数切分为多个小函数的偷懒做法。使用多个函数,通常好过向单个函数传递某些代码来选择函数行为。
7、函数名称应该表达其行为。
8、用命名常量代替迷之数字。
9、用多态替代if/else或switch/case
10、如果没有if或while语句的上下文,布尔逻辑就难以理解。应该把解释了条件意图的函数抽离出来。
例如:if(shouldBeDeleted(timer))要好于if(timer.hasExpired()&&timer.isRecurrent())
11、否定式要比肯定式难明白一些,所以尽可能将条件表示为肯定形式。
例如:if(buffer.shouldCompact())要好于if(!buffer.shouldNotCompact())
12、函数只该做一件事,函数只该做一件事,函数只该做一件事。
13、捕鱼之前先织网,织网之前先编绳,这三项活动的执行顺序(时序耦合)很重要。在程序中,每个函数都产生出下一个函数所需的结果,这样一来就没有理由不按顺序调用函数了。
14、封装边界条件
边界条件难以追踪,把处理边界条件的代码集中到一处,不要散落于代码中。我们不想四处见到+1和-1字样。
if(level+1 < tage.length){
  parts = new Parse(body,tage,level+1,offset+endTag);
  body = null;
}
注意level+1出现了2次,这是个应该封装到名为nextLevel之类的变量中的边界条件。
int nextLevel = level+1;
if(nextLevel < tage.length){
  parts = new Parse(body,tage,level+1,offset+endTag);
  body = null;
}
15、函数应该只在一个抽象级上
函数中的语句应该在同一抽象层级上,该层级应该是函数名所示操作的下一层。
16、名称的长度应与作用范围的广泛度相关。对于较小的作用范围,可以用很短的名称,而对于较大的作用范围就该用较长的名称。
17、整洁代码并非遵循一套规则写就,学习一系列启发并不足以让你成为软件匠人,专业性和技艺来自于驱动规程的价值观。

抛开所有细节不谈,代码整洁之道总体来说可以分为以下7点:

  • 运行所有测试
  • 减少重复代码
  • 提高表达力
  • 提早构建简单抽象发
  • 类和方法都只做好一件事
  • 尽量减少类和方法的数量
  • 努力,让营地比你来时更干净。努力,让世界比你来时更干净。努力,让代码比你签出时更干净。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

changuncle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值