読みやすいコードを書く~変数名編~
はじめに
こんにちは、SHIFT の開発部門に所属しているmurasawaです。
SHIFTには中途入社し、バックエンド関連の開発を担当しています。
現在、研修でデータベースやRestAPIについて基本的な事から学んでいます。学んだことをアウトプットし理解を深めていくとともに技術の共有として役に立てば幸いです。
今回、自身のきれいなコードを書く能力を上げたいと思い、読んだ本「リーダブルコード」から学んだことをアウトプットしていきます。
ある特定のコード規約があるわけではなく、コードを書く際にきれい、あるいは見やすい、共有しやすい書き方をまとめたものになっています。
チームやプロジェクトでコード規約がある場合はコード規約に従っていただき、コード規約外での実装や、コード規約を決める際の指標にしていただければ幸いです。
また、例示しているコードが古く、現在主流の記述とずれがある場合がありますが、あくまで説明のためのコードであるので、本題理解のためにご了承お願いいたします。
内容は多くの言語に適用できるものですが、例にはjavascriptを使用しています。
名前の情報量
コードを書く際、変数自体に情報が含まれていないことがあると思います。
しかし、変数は短いコメントのようなもので簡潔に情報を読み手に伝えることができます。
getやsizeのように一見問題がなさそうな名前であっても、情報が含まれていないことがあります。
明確な名前を付ける
以下のような関数
function getData(path) {
...
}
この関数はどこからdataを取ってくるのかわかりません。
ローカルキャッシュなのか、データベースからなのか、はたまたインターネットからなのか。
インターネットであればFetchData(DB)やDownloadData(url)のほうが明確でわかりやすい名前になります。
次に
const size = size();
のようになっている例です。 このsize()は何を返すのかわかりません。
画像のpixel数?高さ?byte数?
明確に名前を付けるのであれば、imageHeightPx()やStringBytes()のほうが明確です。
また、
stop();
のような名前も注意が必要です。
取り消しができない重い処理なのか。再開できる処理なのか。
取り消しができないのであればkill(), 再開できるのであればpause()のほうが明確に動作を説明できます。
英語であれば、例えばmakeをcreate, set up, generate, add, newなどに言い換えたり、表現が豊富です。
気取り過ぎず、意味が明確になる単語を選ぶことができると伝わりやすい変数にできそうです。
汎用的な名前を避ける
変数の名前に困ったら、tmp,retval,resultなどの名前をつけがちですが値や目的を現した名前を付けたほうがわかりやすいです。
例えば、
const rootSumSquire = (data) =>{
let result = 0.0;
for(let i = 0; i < data.length; i += 1)
result += data[i] * data[i];
return Math.sqrt(retval);
};
であれば、resultをsumSquaresに変えたほうがバグにも気付きやすくなります。
実装者が間違って記述した際、
result += data[i];
であれば二乗しなければいけないことにすぐには気付けないですが、
sumSquares += data[i];
であればすぐ違和感に気づくことができると思います。
イテレータ
以下のようにfor文を二つ使わなければいけないとき、iとjを使って記述したとします。
for(let i = 0; i < users.length; i += 1){
for(let j = 0; j < menbers.length; j += 1){
if(users[j] === menbers[i])
console.log('ok');
}
}
いつの間にかiとjが入れ替わっていても気づきにくいです。
そこでiをusersの頭文字をとってuiに、jをmenbersの頭文字をとってmiと置き換えれば
if(users[mi] === menbers[ui])
頭文字が違うのでバグにすぐ気づくことができます。
具体的な名前を付ける
あるコードの実行時に--run_developというオプションが設定されているとします。
run_developは開発環境であるlocalで実行するということはわりますが、ログが出力されるようになるのか ローカル用の特別なDBに接続するようになるのか、あいまいで範囲がわかりません。
ローカルでのパフォーマンスを確認したい場合、ログは必要ではないと考えられます。
このオプションを初めて見た人はログが出るのかわからないまま使ってしまうことになります。
そういった理由から、run_developというあいまいな名前でなく--logging, --use_local_databaseと二つに分けたほうが良いと思います。
オプションが二つに増えてしまうものの、範囲や目的がわかりやすく初めて触る人でも適切に実行できるようになります。
名前にフォーマットや値の情報を追加する
const id;
コードの中でidという変数を用いてそのidのフォーマットが重要な意味を持つ場合。その情報を付加するとわかりやすくなります。
idがuuidやulidであることや16新数であることが重要なのであれば、
const ulid;
const hex_id
のように定義することで意図が伝わりやすくなります。
また、値の単位が重要な場合
var start = (new Date()).getTime();
...
const elasped = (new Date()).getTime() - start;
console.log(elapsed);
と書くともっともらしく見えますが(new Date()).getTime()で帰ってくるのはミリ秒なのでバグの原因になります。
var startMs = (new Date()).getTime();
...
const elaspedMs = (new Date()).getTime() - start;
console.log(elapsedMs / 1000);
とすればミリ秒であることがすぐわかりミスする可能性が減ります。
名前の長さ
短いほうがコードは見やすくなりますが、メソッドや処理のスコープが大きい場合、無理に名前を短くすることはわかりやすさを損ねてしまいます。
例えば、最後のログインから立った時間を表す変数を単にtimeやlastLoginとしたら、前者は何の時間かわかりませんし、後者は最後のログインがどうしたのかわかりません。
長い名前を避けるあまりわかりにくくなってしまっては本末転倒なので、timeSinceLastLoginなど目的や意味の分かりやすい名前を付けるとよいと思います。
入力するのが面倒くさい、大変だは名前を無理に短くする理由にはなりえません。
テキストエディタは数文字入力すれば、勝手に補完してくれますし、補完を使ったほうが誤字する可能性は減ります。
プロジェクト固有の省略
長い変数の場合、頭文字をとって名前を短くすることがあると思います。
shiftAccountManagerをSAManegerとした場合、一般的なので初めて見た人は理解できません。
stringをstr、returnValueをretvalと省略する一般的に知られいるものや新規メンバーが理解できる変数であれば省略は有効です。
余計な単語を入れない
cnovertToString()やconvertToDate()はconvertがなくても通じると考えられるので、toString(),toDate()としても情報は損なわれません。
また、doConnectDB()などもconnectDBで伝わります。
削除しても明確さを損なわないものは削除したほうが簡潔になります。
その他
プロジェクトでメソッド、コンストラクターでフォーマット規約を決めて一貫性を持たせることでコードが読みやすくすることができます。
下記のように
const UserInfo = new UserInfo();
const displayWidth = displayWidth();
プロジェクトでコンストラクタ関数は大文字から始まり、通常の関数は小文字から始まると決めておけばそのメソッドが何なのかひとめで理解することができます。
参考
終わりに
以上、コードを読みやすくする名前の付け方です。
意識しているつもりでもできていないこと、短くするためにわかりやすさを犠牲にしていることなど学ぶことが多くありました。
この記事を生かしてより読みやすいコードをかけるように意識していきたいと思います。
《Satoshi Murasawa他の記事》
お問合せはお気軽に
https://service.shiftinc.jp/contact/
SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/
SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/
SHIFTの導入事例
https://service.shiftinc.jp/case/
お役立ち資料はこちら
https://service.shiftinc.jp/resources/
SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/