如何写出优雅的代码

前言

《代码整洁之道》是鼎鼎大名的《敏捷软件开发:原则、模式与实践》作者Robert数十年的编码技艺心得。这是一本干货极多的不可多得的经典书籍,让你系统了解编码技艺提升的要点,让你理解OO中的许多重要概念,比如抽象层级、SRP、DRY、依赖导致、开放-闭合原则等等,是每一个OO开发者都必须阅读的经典书籍。本文主要总结了该书重要章节的核心思想,相信我,如果这些要点你能消化,必定会让你功力大增。?。

1.命名(变量、函数、类、包)

  • 代码90%的理解力来源于清晰明确的命名。( 放在第一章,重要性不言而喻。)
  • 好的命名就是最好的注释。或者说,好的命名的代码不需要注释。
  • 标准单词的合理利用,比如List,Set,Adatpter,Visitor,Queue等,这些专业词汇对于其他开发者具有特殊意义。
  • 命名不应太相似,差异应该很明显。另外,如小写的l和和大写的O在某些字体很容易造成误解,是数字还是字母呢,?。
  • info和data,a,the,variable,无意义的冗余的单词可以使命名不同,但是无法区分含义,模糊理解,是不行的。
  • 命名应该可以读出来,并可以用来口语交流。否则。。。如果变量名是ymdhms(年月日时分秒)。。。。
  • 哼,别用魔法数字,这会造成理解困难和错误难以排查。
  • 类名和对象名应该是名词或名词短语,类名不应当是动词。
  • 方法名应当是动词或动词短语。
  • 包名,类名,函数名都能够提供一个语境,使其内部的命名可以更加简洁易懂。

2.函数

  • 函数第一条规则应该是短小,第二条规则是要更短小(程序员的追求就是不一样?️)。20行封顶最佳。
  • if、else、while语句等,其中的代码应该只有一行。
  • 函数应该只做一件事。一个函数中的步骤,应该是同一抽象层级上步骤的拆解,这样就称为只做一件事。(核心中的核心,我要划重点)
  • 给函数取一个好名字,函数的功能越集中,就越便于取个好名字。
  • 最理想的参数数量是0,其次是1,再次是2,应尽量避免3个函数。(封装为dto)
  • 不要通过参数进行输出,这难以理解。
  • 函数要么做什么事,要么回答什么事(要么修改对象状态,要么返回对象的信息)。但二者不可兼得。
  • 使用异常代替错误码,可以避免深层次的嵌套结构。而且通过try..catch..可以将错误处理代码从主路径代码分离出来。将try...catch..抽离出来形成一个函数。
  • DRY原则,重复是软件中的一切邪恶的根源。尽可能将重复的代码抽离出来,提取到基类中,应用aop,cop等等都是这个目的。这样易于阅读,复用,修改。

3.注释

  • 注释是一种必须的恶。也就是说,我们尽量让代码讲述自己,只有我们用代码表达意图失败时,只有我们在写出糟糕代码时,才需要用注释。
  • 注释,不像代码那样总是被维护,所以注释会撒谎。
  • 合理注释的注释:法律信息,对代码意图的解释,代码关键处的警告(勿修改),todo,看起来不合理之物的合理之处(勿修改)
  • 不应留下被注释的代码,注释的代码就像狗皮膏药,删掉也不是,不删也不是?。

4.对象和数据结构

  • 将类的数据设置为私有,封装起来,并提供功能接口,这就是oop对数据结构的抽象。隐藏数据形态达到的抽象,可以不让其他人依赖这些数据,并且我们可以在需要的时候任意修改这些数据结构。
  • 面向过程编程,暴露数据结构,增加函数容易,增加数据结构难。
  • 面向对象编程,抽象数据结构,增加函数难(基类和实现类都得加),增加数据结构容易(创建一个新类吧)。
  • 得墨忒耳法则,只跟朋友谈话,不与陌生人谈话。面向对象编程,遵守这个约定可以极大减少耦合。(链式编程典型违反了得墨忒耳法则)
  • 最简练的数据结构就是dto,oo中豆结构(bean)更常见。

5.异常处理

  • 错误码会造成深层嵌套,使主路径代码晦涩难懂。而异常处理,却可以将错误处理代码从主路径代码中分离出来,将业务逻辑和错误处理代码进行良好的区隔。
  • 使用不可控异常(unchecked exception)更符合开放/闭合原则,而不是用可控异常(checked exception),因为这会导致异常声明的传递,以后一旦底层异常声明需要修改,就要层层传递进行修改,?ommmm....mygad...。
  • 对第三方打包(比如zookeeper)非常有用,这样你就降低了对它的依赖,不必帮死在特定厂商的api上,可以自己定义自己的api,未来你可以改用其他代码库。在你测试时,打包也有助于模拟第三方调用。也可以整合其异常处理。
  • 不要让异常打断你的业务逻辑,有时候可以用特例模式,客户代码就不用应付异常行为了。
  • 别返回null,null需要进行判断,增加深层嵌套,增加风险。不如抛出异常,或返回特例。(如果第三方返回了null,就包装它,在新方法中抛出异常或返回特例对象)


6.边界

  • 将第三方封装起来,隐藏起来,抽象起来,然后提供接口,这样可以减少第三方的依赖,将第三方边界清晰干净利落的整合到我们自己的代码中。
  • 对第三方api编写学习性测试(嗯。。。测试驱动学习),好处多多,不止可以了解api的功能,而且当其升级的时候,可以再跑一遍,查看新老版本的兼容性。
  • 未开发完的第三方项目,可以先包装起来,写伪代码,这样并不会影响我们的开发。还可以为测试提供极为方便的接缝。边界干净利落。

7.测试

  • 测试代码应该保持和生产代码一样的整洁。因为这是保证系统可扩展、可维护、可复用的前提。有了测试,你就不用担心对代码的修改带来的缺陷和风险。
  • 整洁的测试,应该含有构造-操作-检验的模式。

8.类

  • 类的第一条规则应该是短小,第二条规则是要更短小。(程序员的追求,嗯。。?)
  • 对于类我们用SRP来衡量其大小。SRP,类的单一权责,一个类只有一条修改的理由。这是oo设计中最为重要的概念之一。
  • 内聚性,当类中的方法操作越多的实体变量,就说这个类的内聚性越强,就越能说明该类的权责越集中。
  • 类的内聚性越强,组织性就越强,当修改时,所造成的破坏区域就越小。
  • 依赖倒置原则,依赖抽象,不要依赖具体,这样当具体的细节改变时,就会隔离细节改变的影响。
  • 针对接口编程,而不针对实现类,和上面异曲同工。

9.系统

  • 构造一个弹性灵活的系统的关键,就在于合理切分关注面。
  • 系统的初始化要和业务逻辑分离,可以用控制反转的思想,如工厂模式、依赖注入。
  • 系统的事物、安全、缓存等功能要和业务分离,可以用aop的思想,如代理模式、springaop、jbossaop框架、aspectj等来切分关注面。
  • 这样我们在pojo中就可以单纯的处理业务逻辑,并根据需要加入各种切面功能,拥有模块化关注面的pojo提供了敏捷能力,允许我们根据最新的业务要求作出优化的、时机刚好的决策。决策的复杂性被大大降低了。
  • 切面的系统结构对于系统没有侵害性,这样的架构更灵活,业务逻辑不会收到干扰,使缺陷更难隐藏,使用户故事更好实现。

10.迭进

  • 编写越多的测试,则越遵循DIP、SRP、DRY等原则,去运行所有的测试吧,向100%覆盖率的测试代码前进。
  • 不要重复代码,重复的代码都需要抽取出来。
  • 代码要清晰、明确的表达意图。去花更多时间去命名吧,相信我,收益远远大于付出。
  • 类和方法要短小,类要srp,方法要讲述一件事情的基础上,尽量减少类和方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值