46
誰にでも読みやすいコードを目指して ~ リーダブルコード 1.0

リーダブルコード 1.0

Embed Size (px)

Citation preview

Page 1: リーダブルコード 1.0

~ 誰にでも読みやすいコードを目指して ~

リーダブルコード 1.0

Page 2: リーダブルコード 1.0

出典

リーダブルコード – より良いコードを書くためのシンプルで実践的なテクニック

Amazonでは★4.5の好評価!

★★★★★ 初級者にも上級者にもおすすめ

★★★★★ スラスラ読める実践的なコーディング指針

★★★★★優れたコードを書く切欠を与えてくれる本

Page 3: リーダブルコード 1.0

リーダブルコードって何?

Page 4: リーダブルコード 1.0

• Readable code = 読みやすいコード

リーダブルコードとは、

”他の人が最短時間で理解できるように書かれているコード”

リーダブルコードって何?

Page 5: リーダブルコード 1.0

スパゲティコードなら知ってるよ?

Page 6: リーダブルコード 1.0

• スパゲティプログラムまたはスパゲティコードとは、制作したプログラマ以外にとって解読困難である事を表す俗語

• 例)– goto文の濫用

– 多重継承の濫用

– スコープが大きい

スパゲティコードって言葉は聞いたことあるなぁ

Page 7: リーダブルコード 1.0

• どちらの方が読みやすいですか?

if ((bucket = findBucket(key) ) || !backet.isOccupied()) {

}

bucket = findBucket(key);

if (bucket != null) {

assert(!bucket.isOccupied);

}

スパゲティコードじゃないけど

Page 8: リーダブルコード 1.0

• チームの他の人のため

• 未来のメンバーのため

• 未来の自分のため

何のため読みやすいコードを書くの?

Page 9: リーダブルコード 1.0

ここで思い出して下さい!

Page 10: リーダブルコード 1.0

自分の書いたコードってあなたはどのくらい覚えていますか?

Page 11: リーダブルコード 1.0

A「自分が書いたコードってどのくらい覚えているんですか?」

B「ほとんど覚えていないっすよ」

A「直すときどうするんですか?わからなくなっているじゃないですか」

B「忘れても見たら簡単にわかるように書いておくんですよ」

ふたりのプログラマの会話

Page 12: リーダブルコード 1.0

どうすればリーダブルになるか?

Page 13: リーダブルコード 1.0

1. 命名

2. コメント

3. 制御フロー

4. 処理の分割と構成

リーダブルにする4つのポイント

Page 14: リーダブルコード 1.0

1. 命名

Page 15: リーダブルコード 1.0

• 変数名、関数名は機能が一目瞭然でわかるものにする

– StartPage()

• Startは便利な単語だが、汎用的すぎて具体的ではない。作るのか?始めるのか?開くのか?わかりにくい

• 代替案– CreatePage, beginPage, openPage

• 他にもないか考えてみよう– Send, find, make, get, set …

命名1

Page 16: リーダブルコード 1.0

• tmpやretvalなどの汎用的な名前は避ける– 何をやっているか一目瞭然ではない

• 抽象的な名前より具体的な名前を使う– 「サーバー開始」より、サーバーのどの機能を開始するかを明示した方が良い

• 名前に情報を追加する– 時間でミリ秒を返すなら、begin_msのようにミリ秒を表す言葉を追加するとベター

命名2

Page 17: リーダブルコード 1.0

• 誤解されない明確な名前

– 他の意味と間違えられることはないだろうか?

• 限界値を求める場合、MAX, MINなどを頭につける

– MAX_VERTICAL_LENGTH、MIN_HORIZON_LENGTH

• 範囲を指定する場合first, lastなど使う

• 限定的な範囲だとbegin, endあたりも良い

• get*()はメンバの値を返すだけの軽量な関数である。あまり色々な処理をする関数の名前にふさわしくない。

最善の名前とは、誤解されない名前である。つまり、あなたのコードを読んでいる人が、君の意図を正しく理解できるということだ

命名3

Page 18: リーダブルコード 1.0

• send → deliver, dispatch(発送する), announce,

distribute(分配する), route

• find → search, extract, locate, recover

• start → launch, create, begin, open

• make → create, setup, build, generate(~を生む),

compose, add, new…

カラフルな単語を探してみよう

Page 19: リーダブルコード 1.0

• スコープの大きな変数には長い名前をつける、逆にスコープの小さな変数には短い名前であることが感覚的に良い

命名4

Page 20: リーダブルコード 1.0

• Date型をString型に変換する関数がある場合、どういう形式で返すのかわかるようにするのも、良い方法である。

• String toDateString(Date date);

• String toYYYYMMDD(Date date);

Page 21: リーダブルコード 1.0

• booleanの変数やメソッド名

• if (user.auth()) {

• // 著者は・・何してる?

• }

• if (user.hasAuthority()) {

• // is, has, canを頭につけると途端にわかりやすくなる

• }

Page 22: リーダブルコード 1.0

2. // コメント

Page 23: リーダブルコード 1.0

• コードを見てすぐわかることをコメントに書かない。

– setProfit(int profit) // profitに新しい値を設定する

• 価値の無いコメントを書かない// 与えられたsubtreeに含まれるnameとdepthに合致したNodeを見つける

findNodeInSubtree(Node subtree, String name, int depth);

コメント1

Page 24: リーダブルコード 1.0

• 読み手を意識して伝える

– 嵌りそうな罠、ここは紛らわしいので注意!とか

– 質問されそうなことを書いておく

– コードの欠陥にコメントをつける• // TODO: あとで手をつける

• // FIXME: 既知の不具合があるコード

• // HACK: あまり綺麗じゃない解決策

• // XXX 危険!大きな問題がある

コメント2

Page 25: リーダブルコード 1.0

• 曖昧な代名詞を避ける。

– 「これを」、「それを」等の表現は避ける

「データを」、「キャッシュを」・・・具体的に

• 歯切れの悪い文章を磨く

// 広告の使用に応じて優先度を変える

// 広告の使用頻度によって優先度を上げる

コメント3

Page 26: リーダブルコード 1.0

// このシステムは日本国内に限られているので

// 電話番号で国番号を入力する必要はない

または、実例で補足する

/**

** 平成和暦日付文字列を解析してDateとして返却する

** 例:

** 平成24年10月31日はOK

** H24.10.31はOK

** H24.1月2日はNG

*/

Page 27: リーダブルコード 1.0

◎コードの意図を読み手に理解してもらう

◎コメントは領域に対する情報の比率が高くなければならない

◎コードの意図は詳細レベルではなく、高レベルで記述する

コメントのポイント

Page 28: リーダブルコード 1.0

• 高レベル言語とは?

• 高級言語とは、プログラミング言語のうち、より自然語に近く、人間にとって理解しやすい構文や概念を持った言語の総称である。

• 高級言語は、主に英単語や記号などを組み合わせて命令を記述し、コンパイラやインタープリタなどで機械語に変換され、実行される。より機械語に近い言語で記述を行う低級言語(低水準言語)と比べて、言語の理解がしやすく、また汎用性が高いと

いう利点がある。

- IT用語辞典BINARYより抜粋

少しおさらい

Page 29: リーダブルコード 1.0

3. { 制御フロー }

Page 30: リーダブルコード 1.0

• 条件式の並び順

– 変化する方を左、固定値を右に配置する

if (10 < length) // こちらより

if (length > 10) // こちらの方が読みやすい

制御フロー1

Page 31: リーダブルコード 1.0

• if/elseブロックの並び順

– 条件は否定形より、肯定形を使う• if (!debug)ではなく、if (debug)を(なるべく)使う

– 関心を引く条件や目立つ条件を先に書く• 条件に応じて、否定を先に書くこともある

制御フロー2

Page 32: リーダブルコード 1.0

• ネストを浅くするif (条件1) {

// 処理1

if (条件4){

// 処理4

} else {

// 処理5

if (条件5) {

// 処理6

if (条件6){

// 処理7

if(条件7) {

// 処理9

} else {

// 処理10

if(条件8) {

// 処理11

} else {

// 処理12

}

}

}

} else {

// 処理8

}

}

}

} else if (条件2) {

//処理2

if(条件2) {

// 処理3

}

}

・・・これは以前の現場で私が出会ったコードです。

制御フロー3

Page 33: リーダブルコード 1.0

• ネストを深くするより、ガード節を作って、

早めにリターンすると読み手にとってはわかりやすい。

(ループでは、breakを使って早めにリターンする)

制御フロー4

Page 34: リーダブルコード 1.0

• 制御フローはできるだけ自然にする。コードの読み手が立ち止まったり、読み返したりしないように書く

制御フローのポイント

Page 35: リーダブルコード 1.0

4. 処理の分割と構成()

Page 36: リーダブルコード 1.0

• タスクを列挙して、処理を分割する

• コードはタスクを1つずつ行うようにする

• 一つのクラスにゴチャゴチャ機能を詰め込まない

処理の分割と構成1

Page 37: リーダブルコード 1.0

ここで質問

Page 38: リーダブルコード 1.0

ド・モルガンの法則って覚えていますか?

Page 39: リーダブルコード 1.0

「「A かつ B である」なんてことはない」

とは、

「Aでないか B でない」

と同じ意味になる、という法則。

• if (!(A && B) == !A || !B) {

}

• if (!(A || B) == !A && !B) {

}

「ド・モルガンの法則」とは、AND演算とOR演算を相互に変換するものです。以上のように、左辺のAND演算を右辺のOR演算に変換したり、左辺のOR演算を右辺のAND演算に変換します。ド・モルガンの法則に相当するものは、四則演算にはありません。論理演算ならではの法則なのです。

ド・モルガンの法則

Page 40: リーダブルコード 1.0

• 巨大になってしまった処理

– 条件式で条件内に処理を詰め込みたい場合は、説明変数やマクロに代入し、それを比較するほうが読みやすくなる。

• コピペミス・タイプミスを減らせる

• 横幅が狭くなるので、コードが読みやすくなる

※ しかしマクロの多用は読みにくくなる恐れもある!

ケースバイケースで使うべき

処理の分割と構成3

Page 41: リーダブルコード 1.0

• グローバル変数は、読みにくく、どこで使っているかわかりにくいので、出来る限りスコープの小さい変数を使用する

処理の分割と構成4

Page 42: リーダブルコード 1.0

• 汚い実装をするぐらいなら標準APIから使えそうなものを探す

• 条件分岐に整数値や文字列を使わないでenum型を使う

• エラーメッセージを読みやすくする

☆おまけ

Page 43: リーダブルコード 1.0

さて、まとめます

リーダブルコードとは?

Page 44: リーダブルコード 1.0

リーダブルコードとは、

”他の人が最短時間で理解できるように書かれているコード”

読みやすいコード

忘れてもよいコード

Page 45: リーダブルコード 1.0

出典

リーダブルコード – より良いコードを書くためのシンプルで実践的なテクニック

Amazonでは★4.5の好評価!

★★★★★ 初級者にも上級者にもおすすめ

★★★★★ スラスラ読める実践的なコーディング指針

★★★★★優れたコードを書く切欠を与えてくれる本

Page 46: リーダブルコード 1.0

ご清聴ありがとうございました。