COBOL設計の極意!モジュール間依存を整理して読みやすいプログラムを作る方法
生徒
「COBOLのプログラムがどんどん長くなって、どこで何をしているのか分からなくなってきました。整理するコツはありますか?」
先生
「それは『モジュール化』がうまくできていないサインかもしれませんね。大きな塊を小さな部品に分けて、それぞれの関係を整理するのがポイントです。」
生徒
「部品に分けるのはいいですが、部品同士が複雑に絡み合うと余計に大変そうです。どう設計すればいいんでしょう?」
先生
「その通り。部品同士のつながり、つまり『モジュール間依存』をスッキリさせる工夫が大切です。初心者の方にも分かりやすく解説しますね!」
1. モジュール化と依存関係とは?プログラミングの整理術
プログラミング未経験の方にとって、一つの大きなプログラムを書き続けるのは大変な作業です。そこで、特定の役割ごとにプログラムを小分けにします。この小分けにされた部品のことをモジュールと呼びます。例えば、「データの読み込み」「計算」「結果の表示」といった単位で分けます。
そして、あるモジュールが別のモジュールを呼び出して使うとき、そこには依存関係(いぞんかんけい)が生まれます。パソコンを触ったことがない方に例えるなら、料理の工程と同じです。「野菜を切る係」と「炒める係」が分かれているとき、炒める係は切られた野菜が届かないと仕事ができません。これが「炒める係」が「切る係」に依存している状態です。
この依存関係が複雑になりすぎると、一つの部品を直しただけで、関係ないはずの別の部品まで壊れてしまうことがあります。これを防ぐために、依存関係を整理して、各モジュールを「自立」させることが、良い設計の第一歩となります。
2. 疎結合(そけつごう)を目指す!理想的な部品のつながり
良い設計のキーワードに疎結合という言葉があります。これは、モジュール同士の結びつきが「ゆるい」状態を指します。逆に結びつきが強すぎることを「密結合(みつけつごう)」と言います。
密結合なプログラムは、部品同士がべったりくっついているため、一部を交換しようとすると全体がバラバラになってしまいます。一方、疎結合なプログラムは、まるでレゴブロックのように、中身がどうなっているか知らなくても、決まった差し込み口(インターフェース)さえ合っていれば、簡単に取り替えたり修理したりできます。
COBOLで疎結合を実現するには、一つのモジュールに多くの役割を持たせないことが重要です。「計算もするし、ファイルも書くし、画面にも出す」というモジュールは避け、「計算だけをする」モジュールを作るように心がけましょう。役割がはっきりしているほど、依存関係は整理しやすくなります。
3. CALL文を使った階層設計の基本
COBOLでモジュール同士を繋ぐ主な手段はCALL(コール)文です。メインとなる大きなプログラムから、特定の処理を行う小さなプログラムを呼び出します。このとき、階層設計(かいそうせっけい)という考え方を取り入れます。
階層設計とは、役割に「上下関係」をつけることです。一番上の親プログラムが全体の流れを指揮し、中間のプログラムが具体的な手順をまとめ、一番下のプログラムが実際の計算などの細かい作業を行います。指揮官が直接、末端の兵士一人ひとりに細かく指示を出すのではなく、隊長を通じて命令を伝えるような構造です。
このように役割の階層を分けることで、依存関係が上から下への一方通行になり、プログラムの構造が劇的に見やすくなります。どこでトラブルが起きているのかも探しやすくなるため、初心者こそ意識すべき設計の工夫です。
* メインプログラムからサブプログラムを呼び出す例
PROCEDURE DIVISION.
* 消費税計算モジュールを呼び出す
CALL "TAX-CALC-SUB" USING WK-PRICE WK-TAX.
* 結果表示モジュールを呼び出す
CALL "DISPLAY-SUB" USING WK-TAX.
STOP RUN.
4. データの受け渡しを制限する!引数の標準化
モジュール間で情報をやり取りする際、使われるのが「引数(ひきすう)」です。COBOLではUSING(ユージング)という言葉の後に、渡したいデータを並べます。この受け渡しのルールを整理することが、依存関係の改善に直結します。
悪い例は、関係のないデータまで大量に渡してしまうことです。炒める係に、まな板や包丁まで渡す必要はありません。必要なのは「切られた野菜」だけです。同じように、モジュールが必要とする最小限のデータだけを渡すように設計します。
また、受け渡すデータの形(桁数や種類)をあらかじめ決めておくことも大切です。これをインターフェースの標準化と呼びます。ルールを統一することで、どのモジュールを組み合わせても正しく動く、安全なシステムになります。
* サブプログラム側でのデータ受け取り定義
LINKAGE SECTION.
01 L-PRICE PIC 9(07).
01 L-TAX PIC 9(06).
PROCEDURE DIVISION USING L-PRICE L-TAX.
COMPUTE L-TAX = L-PRICE * 0.10.
EXIT PROGRAM.
5. 共通モジュールの作成と再利用性の向上
いろいろなプログラムで何度も使う同じ処理は、共通モジュールとして独立させます。例えば、「日付の形式を変換する処理」や「消費税の計算」などです。これらを共通化することで、同じコードを何度も書く手間が省けます。
共通モジュールを作る最大のメリットは、修正が一度で済むことです。もし消費税率が変わっても、共通モジュールを一箇所直すだけで、それを使っている何百ものプログラムすべてに対応できます。これを「再利用性(さいりようせい)」が高い設計と言います。
ただし、共通モジュールが多すぎると、今度は「何がどこにあるか分からない」という事態になります。図書館のように、役割ごとに整理して名前を付け、誰でも見つけられるように管理することが、大規模開発における標準的な規約となります。
6. データの局所化(カプセル化)による影響範囲の限定
プログラム全体でどこからでも読み書きできる「グローバルな変数」は、依存関係を複雑にする最大の原因です。Aという場所で中身を変えたら、遠く離れたZという場所でエラーが出た、ということが起こりやすくなります。
これを防ぐのがデータの局所化(きょくしょか)です。そのモジュールの中だけで使うデータは、外からは見えないように閉じ込めてしまいます。これを専門用語で「カプセル化」とも呼びます。自分のカバンの中身は自分しか触れないようにするのと同じです。
COBOLでは、WORKING-STORAGE SECTION(ワーキングストレージセクション)に書かれたデータは、基本的にはそのプログラム専用です。外とのやり取りは、必ずLINKAGE SECTION(リンケージセクション)を通した引数だけに絞る。このルールを徹底するだけで、プログラムの安全性は格段に上がります。
* プログラム内部だけで使う変数の例
DATA DIVISION.
WORKING-STORAGE SECTION.
* この変数はこのプログラムの外からは直接触れない
01 WK-INTERNAL-COUNTER PIC 9(03) VALUE 0.
PROCEDURE DIVISION.
ADD 1 TO WK-INTERNAL-COUNTER.
7. ファイルアクセスモジュールの独立(入出力の分離)
COBOLプログラムの多くはファイルを読み書きしますが、これを直接あちこちのモジュールで行うと、ファイルの形式が変わったときに修正が大変になります。そこで、入出力専用のモジュールを作る設計が推奨されます。
「データを計算するモジュール」は、ファイルがどこにあるか、どんな形式で保存されているかを知らなくて済むようにします。入出力モジュールに「データを取ってきて」と頼むと、綺麗な形でデータが届くようにするのです。
これは、レストランで客が厨房の冷蔵庫を直接開けないのと同じです。ホールスタッフ(入出力モジュール)が料理を持ってくる役割に専念することで、厨房(計算モジュール)は料理を作ることに集中できます。この分離が、変化に強いシステムを作るコツです。
8. 循環参照の禁止!きれいな依存グラフを描く
絶対に避けるべきなのが、循環参照(じゅんかんさんしょう)です。これは、AがBを呼び出し、BがさらにAを呼び出すといった、ぐるぐる回る関係のことです。これが発生すると、コンピュータが無限ループに陥って止まらなくなったり、構造が複雑すぎて誰も理解できなくなったりします。
依存関係を整理するときは、常に「一方通行」を意識してください。上から下、あるいはAからBという、明確な流れを作ります。これを図に描いたときに、円(サイクル)ができずに、木の枝が広がっていくような形になるのが理想です。
初心者のうちは、プログラムを書く前に「どの部品がどの部品を使うか」を紙に書いてみるのがおすすめです。矢印を書いてみて、もし矢印が戻ってくるようなら、設計を見直すチャンスです。シンプルな流れこそが、最高の設計なのです。
9. コーディング規約で「依存」をルール化する
最後に、これらの設計の工夫をチーム全員が守れるようにコーディング規約に盛り込みます。「一つのプログラムの長さは○行以内にする」「サブプログラムの呼び出し階層は○段階まで」といった具体的なルールです。
ルールがあることで、経験の浅い人でも迷わずに整理されたコードを書くことができます。また、他人の書いたプログラムを読むときも、ルール通りに書かれているという安心感があるため、理解するスピードが上がります。規約は自由を縛るものではなく、チームで迷子にならないための地図のような存在です。
パソコン初心者の方にとって、最初は「動けばいい」と思いがちですが、長く愛されるシステムを作るためには、この「整理整頓の心」が欠かせません。美しいモジュール設計は、あなたのプログラミングスキルを一段上のステージへ引き上げてくれるはずです。まずは小さな部品分けから、丁寧に取り組んでみましょう。
10. 実行結果の確認とデバッグのしやすさ
依存関係が整理されたプログラムは、テストやデバッグ(間違い探し)も非常に楽になります。特定のモジュールが正しく動くか、そこだけを切り離して確認できるからです。もし計算間違いがあれば、計算モジュールだけを調べれば済みます。
以下の実行結果は、モジュールごとに処理の開始と終了を表示するようにしたログのイメージです。このようにログを出すことで、どの段階で依存関係が動いているのかが手に取るように分かります。設計の工夫は、こうした運用段階でのメリットとなって現れてきます。
[INFO] メイン処理開始
[INFO] 消費税計算モジュール呼び出し開始
[INFO] 消費税計算モジュール正常終了
[INFO] 表示モジュール呼び出し開始
[INFO] 税額: 0000100 を表示
[INFO] 表示モジュール正常終了
[INFO] メイン処理正常終了