Short cut: [Prev] [Up] [Next] [Return to Top]
long long functions (1997.Sep.17)
1関数(SubあるいはFunction)の長さはどれぐらいが適切だろう。良く言われるのは1 page以内。というものである。
古の昔、1 pageは66行(?)であったが、これはラインプリンタで使われた連続用紙に由来する数字である。
未だWindowsが脚光を浴びる前のエピソードを紹介する。
「関数の長さは1画面以内に収めろと指導しているのだが、25行じゃ足りない。」
「DOS画面を50行、VGAなら60行にするtoolがあるけど。」
「それは素晴らしい。これでもっと強力に(1画面以内という)指導ができる。」
66行にせよ、50行にせよ、どちらも同じ発想から最大行数が決定されている。
<1つの処理は1度で見渡せる範囲でなくてはならない>
デバッグの時にプリントされた紙を使うか、画面を見ながらやるか、その違いで1 pageの長さが変わる訳である。
さて。前にも似たような事を書いたが、ここでも思考実験をする。
同じ処理を実行するに辺り、10行の関数10本で実現するのと、100行の関数1本で実現するのとで、どっちにbugが多いと思うか?また、どっちの信頼性がより高く感じられるか?どっちの保守が簡単か?
3つの質問の答えは、後、前、前。である。当然。
さて。以前にプログラムの長さが2倍になればbugの数は8倍になる、と書いた。短い関数ばかりでプログラムを構成すると、そのメリットがもちろん作用する。
しかし、それ以外のメリットもあるのだ。
1つの関数が短いという事は:
1. それだけ関数の汎用性が増す
長い関数はつまり短い奴より色々な事をする。それだけ特殊なプログラムになる訳だから、汎用性が減る。
また汎用性がある関数が後でも使えれば、つまりその部分は何も考えなくて良い事になる。楽ができる訳だ。また前にも使った、ならばその関数には基本的にbugがないと言える。安心して新しく作った部分のみに注力できるのだ。
2. 良く考えられている
内容にももちろん依るが、ある処理を関数に分割する時は、どうやって分割するか考えなければならない。漫然にコーディングしている訳にはいかない。
そして美しく処理が分割されたソースは非常に見やすいものになる。
それだけに、プログラマの質がもろにソースに反映されてしまうが……。
綺麗な機能分割ができているという事は、そのソースを書くのに当たってのプログラマの余裕(*1)を示すものと考えられる。
3. 見やすい
1画面に収まらない関数をdebugしていて、変数名をどう定義したかを思い出すためだけに画面をスクロールさせた事はないか?
変数が幾つも定義された長い関数で、ある変数がどこで必要なのか即答できる自信があるか?
…つまりそういう事である。
分割できないから長いんだ!という意見はあるだろう。もちろん無理に短くする必要はない。だけど、どうして短くならないのだろう?と自問する価値はある。
違う方法を考えればすっきりと短い関数だけで実現できるかもしれない。
インデントが深くなって浅くなる。そういう山が幾つも1つの関数内にあったら、分割できるかどうか考えてみる価値があると思う。
経験から言うと、関数が大きくなり、どうしても取れないbugに悩まされたら、いっそその関数を削除して新たに書き直した方が早い事がある。
「そんなはずはないのに」というbugの場合にお勧めする。
#コメントを削ったり、マルチステートメントを多用すると言った話じゃないよ、念のため。年刊Ahscii!(知ってるだろうか?)の「細密充填リスト」はBasicだからできた芸当だが、あれは……(笑)
(*1)補足:「プログラマの余裕」
1. ある部分が汎用的な関数にできると見抜ける実力
同じ機能であるとしても、より使い回しのできる書き方を思い付ける、という事。
2. 常に安定して関数を作る力
同じ処理を実現するのに、ある時はGetErrMsg(sFnc As String)と書き、ある時はTakeErrorString(iErr As Integer)と書く。では話にならないと言う事(似て非なる関数が山のようにできてしまう)。
3. メリット/デメリットの判断ができる事
深いループの底が汎用関数にできる、と分かっても敢えてやらない。
そういうコスト面も考慮できてなければ駄目。
まぁその。長大なIf文、という名人のプログラムも見た事があるが、凡人はまねない方がよろしいかと……。第一、そのソースを後から保守する人の事を考えるとねぇ。
Short cut: [Prev] [Up] [Next] [Return to Top]