《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.pswp.cn/news/449689.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/449689.shtml
英文地址,請注明出處:http://en.pswp.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…