明日から役立つ?プログラマーの考え方講座 その2
「“いい名前”ってどんな名前?」

こんにちは、鳥井雪です。
ヒューマンアカデミー こどもプログラミング教室の教材監修をしています。
このコラムでは、現役職業プログラマーとして、実際にプログラマーが毎日どんなことを考えてプログラミングしているかを、わかりやすく紹介していけたらと思っています。

第二回は「“いい名前”の見分け方」について。

第一回は、プログラマーにとって「名前をつける」ことの大切さについてお話ししました。 しかし、そうやって頭をひねってつけた名前がほんとうにいい名前なのか、どうやったら判断できるでしょう?「いい名前」ってなんでしょう?

プログラミングにとって永遠の課題のような問いですが、プログラマーであれば、自分なりにいくつか判断の基準を持っていることが多いでしょう。 わたしが名前を見直す時にまず気にするのは、次のような項目です。

それぞれ例を挙げて見ていきましょう。

大きすぎ(広すぎ)ない?

「名前の範囲が広すぎて、それが何を指しているのか正確に読み取れない」パターンです。
第一回で出てきた、変数名‘using_country’(プログラムが使われている国)が、もし‘name’だったら、の例を思い出してみましょう。
nameが人名と誤解されてプログラムのバグを呼んでいましたね。
他にも、「**をする」という意味で使われることの多い「関数」の名前が、‘do(する)’だけで、何をするのかさっぱり分からない…という困った例もあります。
その関数を呼ぶと本当に行われることは「計算する」?「保存する」?それとももしかして、「友達を探して挨拶をする」?名前からは想像もできない状態から、関数に書かれた中身を読みに行かなければならないのは、だいぶ脳のコストが高くつきます。名前の範囲をちょうどいいところまで絞り込むのは、バグを少なく、労力を省いてプログラミングをするのにとても大事なのです。

小さすぎ(狭すぎ)ない?

こちらは逆に、「名前が対象の一部しか表現できていない」パターンです。
例えばあるトランプゲームのプログラムで、‘distribute_cards’(カードを配布する)という名前の関数があったとします。 「なるほどこれはカードをプレーヤーに配布する関数なんだな」と、後からそのゲーム開発に参加したプログラマーは考えるでしょう。 ですが実は‘distribute_cards’関数を呼ぶと、「カードを複数のプレーヤーに配布し、そのカードの内容でプレーヤー同士の行動順を決め、その順番に従って画面の並び順を変更する」処理が行われるとしたら...?
もしわたしがそのプログラマーだったとしたら、半日くらいはふてくされていると思いますね。

長すぎない?

では、「小さすぎ(狭すぎ)ない?」のところで例に出した「カードを複数のプレーヤーに配布し、そのカードの内容でプレーヤー同士の行動順を決め、その順番に従って画面の並び順を変更する」関数の適切な名前ってどんなものでしょう? distribute_cards_and_rank_users_on_cards_and_order_on_ranking
見るからに、「それはちょっとね」というような名前です。
内容がはっきりするのはいいのですが、今度は具体的すぎて変更に弱くなっています。例えば、この処理の途中に「前回の成績を考慮してカードを入れ替える」処理が追加されたとしたら?名前をさらに長くして、その名前を使った関数の呼び出し部分もすべて変えるのでしょうか。変更が多いと、それだけでバグの原因になります。また、関数の名前を目にした時に「さっと“それでやりたいこと”を把握する」という名付けの機能の一つが不足しています。ちょっと難しい言い方をすると「抽象化が不足している」という感じでしょうか。

ここで考えるのは、
■それを一言で表すことができる?(例えば「ゲームの下準備をする」など)
という観点が一つあります。
その観点から考えてみてもどうもしっくり行かなかった場合、もう一つ考えたいのは、
■一つの関数に仕事をさせすぎていない?
という、名前ではなく、プログラムの設計そのものの見直しです。
たとえば関数を小分けにしたり、そもそもデータのまとめ方を「ゲーム」より細かい「カード」「ユーザー」「ランキング」などにしたほうが良かったり。そうやって、小分けにしたものをもう一度統合しようとするときに、「本当にここでやりたいことは一言で言うと何か」が見えてくるかもしれません。
名付けは、名前そのものだけでなく、プログラムそのもののより良い構成への手がかりでもあるのです。

他の名前とルールは合ってる?

すでに動いているプログラムの中で、「処理に失敗したら例外を出す(処理を中止してその警告を通知する)関数の名前には、最後に!をつける」というルールがあったとします。例えばあるゲームで、データを保存しようとして失敗したら例外を出す関数の名前は‘save!、ダメージ計算をしようとして失敗したら例外を出す関数の名前はcalculate!’です。

ここに、新しく「特殊効果でダメージが追加された場合に再計算を行う、失敗したら例外を出す」をrecalculate!なしで名付けてしまったとします。後からその関数を別のところで別のプログラマーが使う時、「!」が付いてないばっかりに、「この関数は呼んでも例外は起こらないんだな」と早合点して、例外の警告が出たときの処理を書かなかったとします。その結果、再計算が失敗したときに画面は真っ暗、一面に赤い<Error!!!>の文字がびっしり...(※実際にはこんなにドラマチックではありません)

郷に入っては郷に従え、ではありませんが、一つのプログラムの中に名付けのルールがある時は、そのルールに合わせるのはとても大事です。 また、うっかりそのルールを見過ごしてしまわないように、あるルールを決めたら、プログラムに関わる誰にでも目に付くところにまとめておくのも大切ですね。

まとめ

色々とポイントを挙げましたが、名前をつける時に気をつけることを一文でまとめると、
「他人や1年後の自分になった気持ちでその名前を読んで、十分に意味が伝わるか、予想を裏切る内容ではないか」です。
一度自分の予備知識やこれまでやったことを頭から追いやって、「この名前を初めて見たときにどんな中身を想像するだろう」と考えるのです。「びっくりさせない名前」であればOK、と言い換えてもいいかもしれません。 その意識が、読みやすく書きやすい、開発を続けやすいプログラムにつながるのです。

また、どんなに悩んでも、上記のポイントをクリアできる名前が思いつかない場合、そもそもプログラムのデータのまとめ方が適切でなかった、というようなこともあります。その時は全体を見直し、より分かりやすく開発の続けやすいプログラム設計にするチャンスかもしれません。そういった兆候に気づくためにも、名前について意識しておくのが大事なのです。

次回は「大きい問題を小さく分ける」ことについてお話しできればと思います。

一覧ページへ戻る