2013年10月27日

説明変数を書くことを面倒くさがるな - リーダブル・コード(13)

1行に複数の文を書くな、というコーディングがよく見られます。 これは、1行に1つの文があるという思い込んでいる人にも楽に読めるようにする効果がありますが、1つの行に複数の処理を書かないようにして複雑にならないようにするという期待も込められています。

本題に入る前に、このルールの副作用(問題点)を挙げましょう。 二次元座標を表す x と y の変数があったとします。 これらの変数を原点の座標に設定して描画するコードは、次のようになります。

x = 0; y = 0;
DrawAt( x, y ); // DrawAt 関数は描画する関数のサンプル

1行に複数の文を書くときは、2つのスペースを置くと読みやすくなります。 ただ、このコードは、1行に複数の文を書くなというコーディング・ルールに違反するため、次のように変えました。

x = 0;
y = 0;
DrawAt( x, y );

1つ1つの文は行が分けられたことで読みやすくなったのですが、x を代入する行の説明、y を代入する行の説明をすることが難しくなりました。 意味を考慮しないで機械的に複数の行に分断してしまったために、x と y の両方で表現できていた「原点」を表現できなくなってしまったからです。

このルールに対処するには、空行を活用して、ブロックで原点を表現するしかありません。

x = 0;
y = 0;

DrawAt( x, y );

最初のコードと比べると長くなってしまいました。 空行が増えたことでスッキリした印象を持って読みやすくなった気持ちもわかりますが、一覧性が失われてしまい、全体の処理を理解することが難しくなってしまっています。 一覧性を重視するなら、次のようにした方がもっと良いでしょう。

x = 0; y = 0; DrawAt( x, y );

この1行で、原点に描画するという1つの処理になりました。 1行に複数の文を書いてはいけないのは、1行で何を表現しているのか説明できないときです。

1行に1つの文に限定しても、1行を複雑にすることはいくらでもできます。

count = atoi( time ) * 60 + atoi( strchr( time, ":" ) + 1 );

1行で count に何かの値を代入している処理ですが、何かをコードから読みとることは難しいでしょう。 この文を読みやすくするには、式の途中の意味のある値を変数に入れることです。

hour = atoi( time );
minute = atoi( strchr( time, ":" ) + 1 );
count = hour * 60 + minute;

この hour, minute 変数のことを説明変数と言います。 説明変数を書くことで、大きくて複雑に見える処理を小さく簡単な処理に分割して確実に理解していくことができるようになったのです。 ただし、説明変数は、何かの概念に対応できるものにしなければ読みにくくなります。

hour_60 = atoi( time ) * 60;
minute = atoi( strchr( time, ":" ) + 1 );
count = hour_60 + minute;

hour_60 は、hour の 60倍の値だよ、と説明できるかもしれませんが、hour(時)のように一般に知られている1つの概念ではないので、チャンキングがしにくく読みにくいのです。

説明変数を書くと、書かないときよりタイプ量は増えますし、変数名を考える手間が増えます。 しかし、テストや保守のことまで考えると、読む機会の方が多いため、全体の開発期間は短縮できるのです。

説明変数を書くと処理速度が遅くなったり、使用するメモリーが増えてしまうと思うかもしれませんが、そうはなりません。 変数に代入されない計算結果も無名の変数のような領域(レジスター、または、メモリー)に格納されるからです。

参考:
リーダブルコード - より良いコードを書くためのシンプルで実践的なテクニック
オライリージャパン ISBN-13: 978-4873115658
8.1章 説明変数、8.2章 要約変数

sage_p at 22:58│Comments(0)TrackBack(0) プログラミング 

トラックバックURL

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔