《The Art of Readable Code》学习笔记(一)

放寒假回家有些颓废,就是不想看书。但是已经大三了,春节过后就要找实习了。哎,快乐的大学生活终于要过去了。

先从简单的书看起吧!在图书馆借了本《The Art of Readable Code》,就是教你咋写好优雅的代码的,感觉还不错。整理一下学习心得。

书中总共分了四大部分,总共15个章节。我也打算边看边记下笔记,用四篇文章来记录一下学习心得。
如下:

  • 第一部分:初级的一些优化
  • 第二部分:简化循环和逻辑
  • 第三部分:重新组织你的代码
  • 第四部分:一些选定的主题

前戏

看原版书而不是翻译版的有个好处就是,英文的表达很精确。

整本书始终就围绕了一个主题来写的

Code Should Be Easy to Understand

什么样的代码才算好呢?
有一个判断的标准:缩短别人能看明白你代码的时间。这时候估计又有同学会问了,我写的就是给自己看的,或者团队里就我一个人,设计到实现到测试全是我一个人,要写给别人明白干什么?好吧,老实说,我之前也是这样想的。“别人”不一定是其他人,也可能是三个月后的你自己。

代码越短越好吗?
代码当然应该清晰易懂,这谁都知道,但是往往大牛们都不这么想。一些大牛认为代码越短越好,在leetcode上经常可以看见这样的话:Python One line Solution Beats 100% .确实只用了一行,但是往往读懂它却要用半天:(
还有三元运算符? :到底该不该用,简单的情况下是可以使用的,比如return max == -1 ? 0 : max可以不必用if else来代替了,但是有些情况下,如果为了把代码写到一行中而在三元运算符中添加复杂的逻辑,以至于别人为了看懂你这行代码,要去查一查其中运算符的优先级,那就不是好代码了。

第一部分 : 初级的一些优化

比如,取个好点的名字,写上必要的注释,格式化代码等等,它们影响了代码库中的每一行代码,虽然这些改变不破坏整体的逻辑,但是却能使代码更容易读懂。

A. 在名字中包含信息

Man-Eater plant(食人花)这个名字让人一看就懂。

  1. 使用特定的单词。比如def GetPage(url){...}这个就不够具体,get本身有很多种意思,你到底是要干啥?替换成具体的单词,FetchPage() DownLoadPage()都是可以的,让人一看就明白了。
  2. 避免使用通用的名字。像tmp,retval,我以前就喜欢这样写,为什么?还不是嫌取个名字太麻烦了,自己英文水平又不行,用拼音吧,也太low了。这种变量名字不能传达任何信息,尽量不要用。除非在某些情况下,比如,交换两个变量的值,这时候需要一个中间变量tmp,这个没问题,大家都也都能看明白。多重循环的时候,也避免使用i,j,k这样没有任何信息的变量名,可以使用club_i, members_i, users_i这样的,或者缩写ci,mi,ui防止搞混淆。
  3. 使用更详细的名字。尽量详细的将信息表达在名字中,ServerCanStart()相对于CanListenOnPort来说就很含糊。
  4. 添加额外的关键信息。比如时间单位,开始和结束时间,start_ms end_ms后面就可以加上单位,来防止在接下来遇到其他不同单位时间的变量中出错。
  5. 为大范围的变量起个长名字,小范围的变量可以取个短一点的名字。如果变量只存在于一个很小的范围中,比如只有几行,那么map<String, int> m这样就没毛病。但如果map存在一个很大的范围里面,m就不便于阅读了。
  6. 使用大写,下划线等去表达特定的信息。比如在C++中,类中的变量名以下划线结尾,比如offset_,这就说明它是一个类的成员变量,而不是局部变量。

B. 名字不能模棱两可

英语中有很多模棱两可的单词,比如filter,results = Database.all_objects.filter("years <= 2011")。那问题来了,results中到底是包含的<= 2012的还是not <= 2012
表达范围:如果要表示高低的范围,那么加上max_min_是很好的选择;如果要表示两个边界都包含在内,那么应该用firstlast;如果要左闭右开,那么应该选择beginend
命名一个布尔型变量的时候,要多使用ishas等使它表达的意思更明确。尽量不要使用负面的词汇,比如,不应该用boolean disable_ssl = false而是用boolean use_ssl = true
还有命名的时候要注意大家默认的习惯,比如会认为带有get的方法是一个代价很小的轻量级的方法,但你却用getMean()这个方法去计算了一个时间复杂度为O(n*n)的平均值,这时候就应该写成computeMean而不是getMean。

C.在代码中审美

这让我想起了云栖社区之前搞的一个活动"第83行代码",就是大家秀一秀自己写的代码。反正,我看一些大牛的代码,就感觉:哇塞!大牛就是大牛,写代码都感觉像是在创作,虽然看不懂写的啥吧,但是单单从审美上就让你震撼了。那么如何使自己代码看起来更优雅呢?

  • 如果有很多个代码块做的事相似,那么也给它们相同的风格,包括注释上下对齐,保持注释结构一致,保持代码的对齐等等。
  • 给多个变量赋值,选择有意义的排列顺序,并且始终保持这种排序。
  • 将许多个声明语句分成块,在相应的块上注释好大概的功能。
  • 给代码分段,每段前写上注释,段与段之间一个空格隔开。
  • 还有就是大括弧的问题
class Logger{
...
}
or
class Logger
{
...
}

这两种写法都没问题,但要选择一种,并且始终保持风格一致,不能混用。

D.学会去写注释

什么是好的注释?有一个判断标准:让读代码的人尽可能多地知道和写代码的人一样的信息。

  • 当然,注释不是什么都要地方都需要写的。一些能直接从变量名读出来的信息,那就不要画蛇添足了。
  • 也不要为了注释而注释。可能会觉得不写注释不妥,那就干脆写一个注释吧!但是注释中其实没有包含什么有用信息。
  • 也不要为了修正代码中糟糕的变量名来写注释,这时候应该直接去修改代码,而不是在注释中写明。
  • 注释也斜体文本可能就是直接的记录了你当时写代码的想法,这也ok。写出来或许对读代码的人有帮助。
  • 为代码中的一些缺点注释:比如
标记意思
TODO:我还没抽空去解决的事
FIXME:这里的代码有点问题
HACK:对于这个问题的解决方案有待改善
XXX:危险!重灾区。。
  • 给自己定义的常量注释
  • 给代码的关键部分,主要功能写注释。
  • 写总结性的注释,让读者不要纠结于一些小细节之中。可以宏观的角度看这些代码,而不是去计较每一行。

写注释反正对于我是蛮难的,一方面写的代码不多,感觉自己注释可能会很幼稚,一方面也觉得写好一个注释要花时间。看了这一章,以后写项目代码的时候,无论如何,也要适当的把注释加上。

E.使自己的注释精确、紧凑

感觉这个没什么好说的,谁都不喜欢听别人唠叨:)那就从我们写注释开始吧!

  • 避免使用它,这个,那个这样的代词,防止产生歧义
  • 润色一些那些“唠叨的话
  • 阐释你的方法的输入、输出时,用一些例子
  • 陈述你代码中和宏观的意图,而不是纠结于细节之中。
  • 用一些能表达更多信息的词,可能一个词就能说明你原来用一句话想说明的意思。

ok!刚看完了这本书的第一部分,万事开头难。寒假生活开始喽!
剩下的我会陆续更新哒~
希望对你有所帮助( ̄︶ ̄)↗ 

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

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

相关文章

文件基本处理

1 打开文件&#xff0c;将文件句柄赋值给一个变量 2 拿句柄对文件进行操作 3 关闭文件 将一个文件第一行写道另外一个文件 f open("test","r",encoding"utf-8") # open找的是系统的编码 x f.readlines() f.close() f1 open("test1"…

C++ ofstream和ifstream详细用法

ofstream是从内存到硬盘&#xff0c;ifstream是从硬盘到内存&#xff0c;其实所谓的流缓冲就是内存空间; 在C中&#xff0c;有一个stream这个类&#xff0c;所有的I/O都以这个“流”类为基础的&#xff0c;包括我们要认识的文件I/O&#xff0c;stream这个类有两个重要的运算符&…

如何将JAR包发布到Maven中央仓库?

将jar包发布到Maven中央仓库(Maven Central Repository)&#xff0c;这样所有的Java开发者都可以使用Maven直接导入依赖&#xff0c;例如fundebug-java&#xff1a; <!-- https://mvnrepository.com/artifact/com.fundebug/fundebug-java --> <dependency><grou…

SSH、SSL与HTTPS

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 关于加密 在解释SSH、SSL与HTTPS协议之前我先介绍一下非对称加密协议。在1976年以前&#xff0c;所有的加密都采用对称加密&#xff0c…

北向资金运作akshare

import pandas as pd import numpy as np import matplotlib.pyplot as plt %matplotlib inline from pylab import mpl mpl.rcParams[font.sans-serif][SimHei] mpl.rcParams[axes.unicode_minus]False#获取交易日历 import datetime def get_cal_date(start,end):dates ak.to…

网络性能测试工具iperf详细使用图文教程【转载】

原文&#xff1a;https://www.cnblogs.com/yingsong/p/5682080.html 转载于:https://www.cnblogs.com/luo30zhao/p/10512042.html

代码审查:程序员内炼之道

摘要&#xff1a;“关注并弄清楚桥梁修建细节&#xff0c;否则你建起来的桥梁有可能坍塌。”代码审查更重要的是一种技术分享或者代码共享。程序员如何提升自我修炼之道&#xff0c;欢迎来支招。 代码审查更重要的是一种技术分享或者代码共享。在审查过程中&#xff0c;通过被…

扎实的基础是成功的法宝

转载链接&#xff1a;https://baijiahao.baidu.com/s?id1610187127874738836&wfrspider&forpc好基础是好成绩的根本,无论做任何事情,基本功的训练是成功的前提:“还没有学会走,就想学跑,那不行,肯定会摔跟头。”这是成功人士的经验之谈。要建成高楼大厦,地基必须打好。…

发送qq邮件

import smtplib from email.mime.text import MIMEText from email.mime.image import MIMEImage from email.mime.multipart import MIMEMultipart from email.mime.application import MIMEApplication# 写成了一个通用的函数接口&#xff0c;想直接用的话&#xff0c;把参数…

排序代码(python,c++) 及 基本算法复杂度

0.导语 本节为手撕代码系列之第一弹&#xff0c;主要来手撕排序算法&#xff0c;主要包括以下几大排序算法&#xff1a; 直接插入排序 冒泡排序 选择排序 快速排序 希尔排序 堆排序 归并排序 1.直接插入排序 【算法思想】 每一步将一个待排序的记录&#xff0c;插入到前面…

TCP/IP四层模型与OSI参考模型

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 TCP/IP四层模型&#xff1a; 1.链路层&#xff08;数据链路层/网络接口层&#xff09;&#xff1a;包括操作系统中的设备驱动程序、计算…

Metal日记:使用步骤指南

本文参考资料&#xff1a; juejin.im/post/5b1e8f… xiaozhuanlan.com/topic/04598… developer.apple.com/videos/play… github.com/quinn0809/G… cloud.tencent.com/developer/a… devstreaming-cdn.apple.com/videos/wwdc… Metal处理逻辑 无论是CoreImage、GPUImage框架&…

还驾驭不了4核? 别人已模拟出百万核心上的并行

摘要&#xff1a;不管是台式机还是笔记本&#xff0c;四核双核都已经不是新鲜的事了。计算机领域的你可能已经认识到了给电脑选配4核的处理器完全是一种浪费&#xff0c;因为大多数的程序都不支持多核心的并行处理。然而斯坦福的计算机科学家最近公布&#xff0c;他们已经模拟出…

docker安装并运行ubuntu

拉取镜像 docker pull dorowu/ubuntu-desktop-lxde-vnc 运行容器&#xff1a; docker run -p 6080:80 dorowu/ubuntu-desktop-lxde-vnc 之后就可以http://localhost:6080/

Django内置权限扩展案例

当Django的内置权限无法满足需求的时候就自己扩展吧~ 背景介绍 overmind项目使用了Django内置的权限系统&#xff0c;Django内置权限系统基于model层做控制&#xff0c;新的model创建后会默认新建三个权限&#xff0c;分别为&#xff1a;add、change、delete&#xff0c;如果给…

Java 从入门到高级学习路线

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Java 从入门到高级学习路线《一》1.Jvm 部分Jvm 内存模型、Jvm 内存结构、Jvm 参数调优、Java 垃圾回收《二》Java 基础部分1.必须会使用…

Flutter Mac iOS 环境配置

官方文档&#xff1a;flutter.io/docs/get-st… 1.需要的命令行工具 bash curl git 2.x mkdir rm unzip which 2.SDK下载地址 flutter_macos_v1.0.0-stable.zip storage.googleapis.com/flutter_inf… 3.解压Flutter SDK cd ~/Flutter/SDK $ unzip ~/Downloads/flutter_macos_v…

多线程研究1

单线程&#xff1a; from urllib.request import urlretrieve import time import random starttime.time() fopen(E:\Python\py\web\hh.txt,r)#打开存放URL的文件 af.readlines() f.close() for i in a:brandom.randint(0,30)urlretrieve(i,%d.png%b) endtime.time() print(…

android viewpage预加载和懒加载问题

1、本人理解懒加载和预加载问题某种情况下可以归结为一类问题&#xff0c;下面我就说一下我遇到的预加载问题和懒加载问题及解决的相应方法&#xff1a; - [1 ] 预加载问题 描述&#xff1a;我用到了三个fragment、viewpage及tablayout实现点击切换、滑动切换。 …

大数据,且行且思

“大数据”概念于20世纪90年代被提出&#xff0c;最初只是对一些在一定时间内无法用传统方法进行抓取、管理和处理的数据的统称。随着时间的推移和科技的发展以及物联网、移动互联网、SNS的兴起&#xff0c;每年产生的数据量都以几何级数增长&#xff0c;《IDC Digital Univers…