プログラミングで使う変数名は気分でつけるな
皆さんこんにちは。
毎度おなじみゼバ会です。
それと初めましての方も、よければ第1回と第2回を見ておなじみと思っていただければ幸いです!
世露死古!
さて前回のコラムで、サンプルコードの中に user という名前のデータベーステーブルが登場し、この名前がダメだという話をしました。
極めて一般的に使われがちなこの名前。
なんでダメなのかっつーと、user という名前がちゃんと物事を説明できてないからです。
あまりにもシンプルすぎ。
要は自分の犬に「犬」って名づけるようなもんでしょ。
そりゃ犬だけどさ!! みたいな。
ビジネスシステムにおいてユーザーというは、要するに「商売の対象となる人間全て」という意味です。
それを管理するためのテーブルが user なんてザックリした名前となると、「ここさえ見ればお客さんの全てが分かる」って意味になってしまいます。
1テーブルで人間の全てを現すなんて、そんなこと絶対ムリっしょ!
たかがシステムごときが、人間バカにすんなよ?
ではでは、user テーブルの名前を「ここを見れば何が分かるか」に合わせて変えましょう。
まぁ、あくまで例ですからそんなに深く考えずに決めてしまいますが、"user_account_basic_information" なんてどうでしょうかね。
これで「ここを見ればアカウントとしての基本情報が分かる」ということが表現できました。
長さ的にも、全文検索したときに「結果がゴミ情報に埋もれる」なんてこともないでしょう。(まぁ、さすがにもうちょっと短くてもいいけどね)
それから、前回やはり例として出てきた getAllUsers メソッドも同じです。
割とよく使われそうな名前でしたが、この名前は内部の挙動を示しているにすぎず、そもそも「何に使うメソッドか」を示していません。
自己紹介でいえば「私の趣味は読書です」で自己紹介が終わっちゃうようなもの。
だから「どんな本でも読みまくる乱読家」のような印象を与えてしまい、期せずした似たような用途に使いまわされてしまうのです。
もしあなたがラノベしか読まないような人間だったら、「日本航空123便の謎」なんて本とか薦められても困るでしょ? 周囲にトンチンカンな行動をさせないためには、「自分は何がしたい人なのか」まで含めて自己紹介することが大事です。
ラノベが読みたいのか、SFが読みたいのか、それとも技術雑誌とか読みたいのか。
それと同じで、メソッド名は「何のために使いたいメソッドなのか」を説明する。
「全ユーザー名を取得したい」は確かに立派な用途だけど、それがなぜ必要になったのかを何も語ってない。
なので模範解答例は listupAllAccountNames とかになるワケです。
これなら「使えそうに見えてもこれでメアド取っちゃダメなんだ」とすぐ分かる。
自己紹介でいえば「私の趣味は読書です。ペリーローダンをとにかくたくさん読みたいです」までちゃんと言う感じ。
ここまでいえば、相手も「自分と趣味が合うかどうか」を判断しやすくなります。ペリーローダンマニアに、日本航空123便の本を薦めてくるヤツぁ普通いないよね?
(あ、ごめん、俺の周りに1人いたわ。空気読まんアイツ。アイツには個人的に、墜落原因は米軍の攻撃じゃないと強く申し上げたい。言っても無駄なんだろうけど、、、)
〇名づけのコツ
テーブル名・メソッド名・変数名なんでもそうですが、名前をつけるときのコツは「ビジネス上の用途」を説明することです。
「システム上の動き」を説明するのでは不十分です。
つまり、自分の仕事の全容がちゃんと見えている状態じゃないと、正しい名づけはできないということです。
この「名づけ」という行為は、将来その部分を担当するプログラマーに対し「こういう用途で使ってね」というお願いを含むものです。
そのお願いがちゃんとできてないから、次の人がトンチンカンなことをしてしまう。
逆に言えば、そういうふうにならなければちゃんとバグは減るのです。
〇名づけテクニック1 DIC法
名前のつけ方で個人的にオススメなのは、「DIC法」というコード記述テクニックに合わせて名前をつけることです。
DIC法は、新人マネージャーが新人エンジニアを率いる、みたいなプロジェクトにありがちな、下記のような問題を解決するために私が考えたものです。
・コードと詳細設計書の内容が、時間経過とともに徐々にズレてくる
・コードを書く以前の、頭の中で処理の流れを整理するフェーズがそもそも難しい
DIC法は、その性質上、ドキュメントとコードの内容がズレることがありません。
加えて詳細設計をコードを書きながら同時にやっても問題ないので、頭の中の整理が苦手な人でもそこそこキレイなコードが書けます。
やり方は基本的にはとってもシンプルで、最上位のビジネスメソッド(コントローラーから直接呼ばれるコード)に、こんな感じでドキュメントを直接埋め込んでしまうんです。
(2階層以降は任意)
/** 全アカウント情報を画面に表示する */
function displayAccountInfomations()
{
// 1. 初期処理
this.init();
// 2. 名前の一覧の取得
Map<Account> accounts = this.listupAllAccountNames();
// 3. HTMLの生成
return view('account/list', {accounts: accounts});
}
分かりやすいでしょ?
この書き方だとね、コメント部分だけ抜き出せば、そのまま詳細設計書としても通用しちゃうのよ。
しかも「コーディングが終わる頃にはコードの整理が完璧に終わってる」というオマケつき。
この書き方なら、新人だらけのプロジェクトにありがちな、「こいつ自分がナニ作ってるか自分で分かってねぇなぁ」も減らせます。
ただし、最下位のメソッドまで含めて完全にこういう書き方をするとコードの大部分がコメントになってしまうので、「第1層目のみ義務」とするのもポイントです。
詳細なルールはこんな感じ。
1. 最上位のビジネスロジックは、1行1処理で記述しなければならない
2. 処理とコメントは必ず1:1のワンセットとし、処理とコメントが矛盾する状態で保存してはならない
3. 2階層目以降のメソッドは、「ビジネスロジックであるかぎり」「無難な範囲で」このルールに従う
4. ただしシステムロジックの場合、読めば分かるコードにいちいちコメントつけない(コメントをつけないと分からないシステムロジックなら、コメントがなくても分かるようにコードを書き直す)
5. Cyclomatic complexity の最大値をチーム内で話し合って決め、みんなで守る(私の推奨値は20)
ま、機会があったらやってみてつかーさいな。
〇名づけテクニック2 「誰が・何を・どうした」法
ただ、上記のDIC法はチーム全体の運用規約に影響を与えてしまうので、現場によってはさすがにできないこともあります。
そういうときもう1つおすすめなのは、「誰が・何を・どうした」法。
心理学では、人間は
・どんな状況で
・何が
・何を
・どうする
という4つの要素が1文で表現されているとき、「分かりやすい」と感じることが知られています。
ということは、メソッド名でこれを表現してあげれば、名前は断然分かりやすくなるわけです。
通常多くの場合「どんな状況で」はクラス名が、「何が」は引数がすでに表現してくれているので、あとは「何を」と「どうする」の2つを表現するだけです。
冒頭に模範解答として出した例 listupAllAccountNames の場合は「全アカウントの名前を」「リストアップする」となります。
たま~~~に「メソッド名の先頭は set か get であること」という規約がある現場とかあるけど、あんなの絶対ダメです。
メソッド名はヒューマンエラーをなくす上でとっても大事な要素なので、名前の一部を固定するなんて愚の骨頂です。
「用途に応じて固定する」ならまだいいんだけど、「無条件に固定する」では名づけという行為自体の意味がなくなります。
そういう現場からはそうそうに引き上げるに限ります。
(そういうプロジェクトはどうせすぐコケます)
こちらはDIC法よりは幾分使いやすいと思うので、次の機会にやってみてね?(はーと)
〇次回予告
ただし、ネーミングルールをキチンと整備して、メソッドの使いまわしを禁止したとして、その結果ちゃんとバグが減ったとしても、それは「エンジニアから見た体感的なバグ件数」が減っているだけです。
当たり前ですよね。バグが減ったことを数字で証明できないのだから。
バグが減ったことをちゃんとお客さん(とか会社の上層部とか)に認めてもらうためには、バグ件数をキチンと計測することが必要です。
でもさ、バグ件数の計測って何でやる?
お客さんからのクレーム数?
でもお客さんって、自分に都合の悪いものはなんでもバグ扱いするよね?
最初は便利だからってつけてたショートカットボタンを、むしろ紛らわしいって理由で消したら多くのお客さんは喜ぶけど、中には「便利に使ってたのに」ってクレーム出してくる人も一部いるよね。
大部分の人が喜ぶようにしたことがバグ?
それともバグ報告書の枚数? それだってデバッガーさんの主観で枚数が決まることには違いないでしょ?
本当に優れた最高のシステムができるまで、俺たちの戦いは永久に終わらない? そんなのやだよ。俺だって日曜日よりの使者には甘えたいもん。
当然ながら、バグ件数を数値で計測をするためには、「何が起こったらバグと見なすか」という定義が必要になります。
その定義に合致するものがバグであり、それ以外はバグではありません。
何となく世の中的に「バグゼロのシステムは不可能」って風潮あるけど、それもバグの定義をしてないからでしょ?
当然っちゃ当然の話。
荒唐無稽な絵空事でもなんでもなく、バグゼロのシステムはちゃんと作れるのです。
それもこれも、バグをちゃんと定義すればいいだけの話。
(はい、第1回のタイトル回収っと)
てなわけで次回は、「そもそもバグとは何か? ~責任範囲で4つに分ける例」でお送りします。
お楽しみに!