👋

学生エンジニアがリーダブルコードを読んで要約してみた

2024/10/19に公開

今回の参考書籍

https://amazon.co.jp/リーダブルコード-―より良いコードを書くためのシンプルで実践的なテクニック-Theory-practice-Boswell/dp/4873115655/ref=sr_1_1?adgrpid=56076398369&dib=eyJ2IjoiMSJ9.keiD6zn06Yn-URBgWNEGc4YP0alwXz0iInrppz9bKVmFlaS3I3BWupsJGJ6_nvMEbjTt2hvTPla-9ENKQsN8c-OzE2apLqqQbm1UcyvcTYJbNpgKkPfjnUPMLV5ljDhCn1NtU85DYJFtBwRWTQNqsndtaWj_hHjTseWoRAp2rUqXmVEPYJNgZ3nO5-3CCZfYcUrOl7NwkWuuDWGyloQeOsdLlSTTlL5Ob2e-UP4ygRsuWzomb0md9jDDmwsdwdu6Lj5JtpEbjdE3SEm9vn5eBHgcblfD8KVsWEr23CztVE4.6D2lgA5R4U9E1de1WS117aY5CSh1KlDW7HdG1cdmCpw&dib_tag=se&hvadid=665615776270&hvdev=c&hvlocphy=9198340&hvnetw=g&hvqmt=e&hvrand=612940983251280272&hvtargid=kwd-334758528225&hydadcr=27298_14701207&jp-ad-ap=0&keywords=リーダブルコード&qid=1729300720&sr=8-1

「良いコード」の定義とは

この書籍を読んでまず良いと思った点はこれから説明される「良いコード」という抽象的な概念を最初に定義していることだ。例えば、簡潔なコードのほうが良いコードとされることが多いが短さを求めるがあまり意味の伝わりづらい変数名を使用したり、改行を含んでいなかったとするとそれは短くても「良いコード」とは言えない。筆者曰く自分で書いたコードが「良いコード」かどうかの判断基準は「他人がコードリーディングをした時の理解にかかるまでの時間がいかに短いか」であると述べられていた。
この絶対的な原則をもとにここからは実際に良いコードを書くための手法が紹介されている。

1.名前に意味を持たせ、理解を助ける

変数名がわかりやすいかどうかというのはコードリーディングの速さに直結する。例えばプログラミング
で多用されるnumでもその場限り使用する変数であれば問題ないが、のちも使用するような「数値」を示す場合、それがどのような数値であるかという説明を加えてあげるだけで理解にかかる時間が大幅に削減できる。個人的にこの章を読んでいて変数の命名の指標となる原則は以下の3点だと感じた

・その変数名の役割を正確に、かつ余分な情報を含まない形で表す名前であるか
→例えばchange_to_stringはto_stringと変更しても読者が理解にかかるまでの時間に影響はない。この場合より短いto_stringのほうが良い変数名だと言える

・そのコードを初めて読んだ人でも理解できる名前か
→例えば社内のMarketing部門のBackEndDeveloperという意味を持つ変数をMBDeveloperと命名した場合、同じ会社のエンジニアであれば素早く意味を理解できる可能性があるが、新たに採用された社外から来たエンジニアにとっては理解をするために大幅な時間がかかる。また、コードを書いた人自身も1年もすればその変数名の意味を即座に理解できなくなる。「1年後の自分が理解できるコードであるか」を意識して書こう。

・スコープの範囲を意識した名前であるか
先ほども少し述べたが例えばある関数のなかでのみ使用されるようなスコープの狭い変数であればnumのような汎用性のある変数名を使用する方がむしろ好ましい。だが、スコープの広い、これから何度も使用されるような変数の場合は「1年後の自分」のために変数名から意味を推測できる名前にしよう。

2.コメントアウトの役割

コメントアウトをする目的もまた読者の理解を助けることにある。例えば以下のようなコードにはコメントアウトは必要ない。これはただそのコードの意味を日本語にしているだけであるし、むしろコメントアウトを読むよりコードをみた方が理解が早いだろう。

// nameの値がtaroだった場合以下の処理を行う
if name=="taro" {
    fmt.Printf("he is %s",name) //he is taroと出力
//そうでない場合は以下の処理を行う
} else {
    fmt.Printf("he is not taro,he is %s",name //taroでないことを出力
}

これは極端な例だが大学の授業の最初のほうはこんなことをしていた記憶が、、、
以下のようなコメントアウトは読者の理解を助けてくれる良いコメントアウトだと言えるだろう。

func ArticleListHandler(w http.ResponseWriter, req *http.Request) {
    //URLに含まれるクエリパラメータが正しい形か判断し、pageに値を格納する処理
	queryMap := req.URL.Query()

	var page int  

	if p, ok := queryMap["page"]; ok && len(p) > 0 {
		var err error
		page, err = strconv.Atoi(p[0])
		if err != nil {
			http.Error(w, "Invalid query parameter", http.StatusBadRequest)
			return
		}
	} else {
		page = 1
	}
	resString := fmt.Sprintf("Article List (page: %d)\n", page)
	io.WriteString(w, resString)
}

このコードはgoで書かれており、Queryメソッドなどについての知識がないと大まかにも何をしているのか検討がつきにくい。「大まかな概要」を処理単位で説明することで読者のコードリーディングの速度も早まる。
このほかにも良い変数名>悪い変数名+コメントアウトであることを意識して変数名を見直すということにも力を入れよう。

3.整列の大切さ

同じような処理が複数並んだコードは同じ変数が同じ場所にくるように整列してあげるだけでみやすさが大幅に向上する。

Discussion