2009年6月30日火曜日

ソースコードの品質

ソースコードの品質について考えてみました。

とりあえずソースコードの品質なので、そのソースコードから作られるオブジェクトの品質と切り離して考えることにします。

読みやすさ
いきなり、プログラムのライフサイクルに関わる話になってしまいますが、書いた、動いた、それで終わり、というパラダイムの製品という物は、最近は滅多になくなってしまいました。それはセカンドライフの世界でも同じでしょう。現代では「書いた、動いた、不具合出た」ということが普通ですし、うまく言っても「書いた、動いた、欲が出た」と改良されてゆくことが普通です。ですから、不具合の原因を探るにも、また、機能を追加するにも、以前のソースが読みやすくなければ話になりません。読めないソースでは、不具合の原因を探し修正することも、また、機能を追加することも不可能です。

それでは、ソースの読みやすさ(可読性)とは何でしょうか。

統一されたインデント
K&Rスタイルでも、オールマンスタイル構いません。非常識でないスタイル(常識的なインデントはここ)全ソース内で統一したインデントスタイルが使われている必要があります。正しくインデントが取られたソースは、制御構造の見通しがとても良くなります。

わかりやすい変数名
ソースコード中でaやb、zなどという変数名が使われていると、その中に格納されているデータの内容を把握することが困難になります。逆に言うとその中に格納されているデータを的確に表す変数名が使われているソースコードは、処理内容がとても把握しやすくなります。
またネームスペース(ここでは簡単にいうと変数が利用できる範囲)を意識した変数命名規則、例えばグローバル変数(私個人の言い方として Perpetuity Variables もしくは Permanent Variables)の先頭の1文字目は大文字で書く、逆にローカル変数(私個人の言い方として Temporary Variables)は先頭文字は小文字にする、ループカウンタは i, j , k の順で使うなど統一したルールが存在しているソースコードは、不具合の発見がとてもしやすくなります。

ブロック化(処理のドキュメント化)
例えば、2つの整数変数aとbの内容を交換する時に、
int temp = a;
a = b;
b = temp;
と書くよりも、引き数付き置換マクロ
#define XSWAP(a, b, type) {type temp = a; a = b; b = t;}
を定義して、
XSWAP(a, b, int);
と書いた方が、そこで何をしているのか直感的にわかりやすくなります。プログラミングの初等教科書等にサブルーチン(関数)のことを、「良く似た同じ処理をまとめ、プログラムサイズを小さくするために使われる」と書かれていることが多いが、私は1回しか使わない処理でも、ソースのドキュメント性をあげるために、あえて関数化することがあります。

適切なコメント
コメントの付き過ぎたソースは逆に見にくくなるが、適切なコメントをつけることで、プログラムがより読みやすくなります。
例えば、最近知ったLSLのブードゥーマジック(最近は有害になっていると聞くけど)を使ったソースでは
a = (a=[]) + a + [llDetectedKey(0)]; // a += [llDetectedKey(0)];
と書くことで、より意味がわかりやすくなります。

これらの可読性の着目点に沿って、ソースコードを採点した場合、

高 ・教育に使用するソース
↑ ・人に見せることを前提として書かれたソース
↑ ・人に見せる可能性のあるソース
↑ ・人には見せないけど、再利用する可能性があるプログラムのソース(実験レベル)
低 ・人に見せず、かつ再利用もしない一時的使用するカスプログラムのソース

という順で高い水準の可読性が要求されるのが、あるべき姿でしょう。あえて言えば、カスプログラムのソースはどうでも良いんです。

また、ソースコードの主役はアルゴリズムであって、書式はアルゴリズムを引き立てる脇役、目立ってはいけない(読み手に違和感を抱かせてはいけない)ということも、意識すべきでしょう。
(しかし、まれではありますが、カスプログラムのソースが、教育目的で出回っちゃうこともあるのですが。持って瞑目すべし)

0 件のコメント:

コメントを投稿