Top Of Page なぜルーチン化 ルーチンの名前 ルーチンの呼出 バグ対策 パラメータ Bottom

ルーチン

ルーチンは、ある機能について作成した「プログラムの一部分」をまとめて名前をつけたものです。
この「名前をつける」という意識は実は重要で、これについては後で触れます。

現代のプログラムはほぼ例外なくルーチンの集まりから構成されます。これをルーチン化されている、といいます。
プログラミング言語によって「関数」や「手続き」や「プロシージャ」や「ファンクション」など、様々な呼び方をされますが、現在主流になっているプログラミング言語で、この「ルーチン」の概念を持たないものはありません。
これはそれだけ、ルーチンという概念がプログラミングにとって重要であるということを示しています。
現代プログラミングは、もはやルーチン化ができないとオハナシにもならないのです。

初級を脱するレベルのプログラマになってくると、感覚的に作っても、合理的なルーチンができることが多くなります。
経験から、うまくいくパターンとうまくいかないパターンを直感的に判断し、無意識にうまくいくように作成するからです。
しかし、この「経験による直感」はクセモノで、その日の体調や気分によって不安定になったりします。
できるだけ合理的に分析してみましょう。

なぜルーチン化するのか

どんな時にルーチン化するのでしょうか。
なんとなく、とか。ゴーストがささやいた、とか。大自然の…(以下自粛)
私にもそういう時期がありました。しかしある程度組みなれてくると、ルーチンを作る理由の整理ができてきます。
データ構造やグローバル変数に対するアクセスをルーチン化しておくと、不正な値を設定されそうになったときにそのアクセスルーチンで判断してエラーとすることができます。
これは、バグにたいする強力なブロックとなり得ます。

なんとなくルーチンを作ってしまうと、そのルーチンの存在意義が薄れ、焦点がぼけたしまらないルーチンになってしまいます。そして経験的に、そういったルーチンが集まったプログラムは、やはり焦点がぼけたしまらないプログラムになってしまいます。 目的意識がしっかりした、切れ味鋭いルーチン化を心がけたいものです。
「なぜこういうルーチンにしたのか?」と聞かれたときに、よどみなく自分の考えが言えるように、明確な理由のもとにルーチンを作成しましょう。

ルーチンの名前

冒頭で、「名前をつける」ということは重要だということについて少し触れました。
ルーチンにとって名前は、そのルーチンの意味や運命を決定する力を持った強力なモノです。
そのルーチンが何をするものなのか、はっきり判るように名前を付けましょう。
意味が大きすぎて限定できない言葉は避けましょう(DoProcessなんていう名前だと何してるかわかりませんよね?)。そしてルーチンがすることをすべて表現します。
いい名前がついているルーチンは、その名前だけで何をしているルーチンなのかがわかります。
ルーチンがすることをすべて表現する名前を付けると、長くなる傾向があります。
あまりにも長い名前を付けなければならなくなったら、ルーチンの機能分割が適切かどうかもう一度検討したほうがいいかもしれません。

一般的に、戻り値がないルーチンを「プロシージャ」、戻り値があるルーチンを「ファンクション」(関数)と呼んで区別します。
プロシージャは本質的に戻り値を持たず、処理だけを行います。
これに対して、ファンクションは、もともと戻り値を求めるために作られるルーチンです。
たとえば、PrintReport は報告書印刷のためのプロシージャ名です。これに対して、GrandTotalは総合計を求めるためのファンクションで、その総合計を返します。
しかし、実際のプログラミングでは、PrintReportも戻り値を返します。そう、エラーコードや成功情報です。だからといって、PrintReportを ReturnErrorCodeという名前にするのは変ですよね。
戻り値があるといっても、それが補助的な情報に過ぎないのか、それとも本質的な情報なのかを判断して、ルーチンの命名を考えてあげてください。

ルーチンの呼出し

あるルーチンから別のルーチンを呼び出す事をプログラミング用語で「ルーチンの結合」といいます。
そして、ルーチンAがルーチンBを呼び出す時、Aがどの程度Bの中身を知っていなければならないかという度合いを「結合の強度」といいます。
この結合強度は一般的に弱いほうがいいのです。
結合が弱いということはお互いにほとんど依存していないということを示しており、他への応用やルーチンの変更を行う時に気を遣う箇所が少なくて済むからです。

結合(呼び出し)の種類としては以下があります。
単純なデータによる結合 パラメータによる呼び出し
データ構造による結合 パラメータに構造体を渡す
フラグによる結合 パラメータにフラグを渡す
グローバル変数による結合 パラメータではなくグローバル変数で渡す
上に行くほど結合が弱く、理想的です。
特に最も結合が強い「グローバル変数による結合」を選択した場合、よほど注意深くルーチンを作成しないと、そのルーチンを他に応用することが困難になります。
できるだけ、弱い結合を心がけましょう。最初は面倒かもしれませんが、プログラムを変更したり、後から調査するときに、その面倒は必ず、そして十分に報われます。
それぞれの結合の例はこちらです。

ルーチン内でできるバグ対策

バグ…ああなんという不快な響き…。(゜゜)遠い目
…はっ。
現実から逃げてないで続けましょう(^^;
バグというのは基本的に予期せぬ事態です。
いきなりバグなしのプログラムが書ければいいのですが、痛い目に多少なりとも遭った事がある人は、「バグは必ずある」という認識があることと思います。
ですから、ルーチンを作る時にバグ対策として以下の事を組み込んでおきましょう。
これだけで、ケアレスなミスの早期発見に大変役立ちます。面倒くさいですが、徹底しましょう。

パラメータ

ルーチンとは切っても切れない仲のパラメータ。これも何気なく使ってしまいがちです。
しかし、パラメータの使い方にも決まりを作ると、(特に大規模な開発や継続する開発で)プログラミングが楽になります。 ルーチンによって同じパラメータの順番が違ったりすると大変混乱します。
あるルーチンではx, yの順、別のルーチンはy, x の順だったりすると、プログラミングする際に余計なことまで気を回さなければなりません。
また、たとえば入力パラメータを前に、出力パラメータを後ろにする、などというルールも効果的です。
パラメータの個数が8個を超えると、バグ件数が急激に増加することがIBMの調査で明らかにされています。
#Win32APIのCreateFontのパラメータの数は大変よろしくないといえます。
たくさんのパラメータを並べなければいけないときは、ルーチンの分割を考えたほうがいいかもしれません。また、パラメータに構造体を適用することを検討してみましょう。

最後に…ルーチンにすべきか?

心理的に「こんな単純な事、ルーチンにするまでもない」という場合。
そういう場合はしばしばあります。
あまり小さいルーチンをたくさん作ると、確かに非効率になることは否めません。
しかし、ルーチンを作るための理由を思い浮かべてください。
明確な理由があるなら、たとえ小さくてもルーチン化するべきなのです。
はじめに ルーチン モジュール 変数名の力 変数使用法 制御構造 レイアウト コメント テスト デバッグ 謝辞 Top of Site

Copyright (c) 2000 Takao Tamura