RPG

206. RPGソース の近代化 (6)

究極の近代化はサブ・ルーチンをプロシージャーに変更することである。
サブ・ルーチンとは、繰り返し何度も使用するようなロジックをメイン・ルーチンから分岐して、
実行するためのメイン・ルーチンの補足といえる。
サブ・ルーチンは、繰り返し使用するロジックをサブ・ルーチンにするべきであり、
メイン・ルーチンの中で、いきなり

EXSR   MAIN

のように MAIN という名前のサブ・ルーチンに分岐するようなプログラムを
時折り見かけるがこれは何の理由も目的もない無駄なロジックである。
サブ・ルーチンの多用はプログラムを見難くするだけである。

■ サブ・ルーチンとプロシージャーのちがい

プロシージャーは単独で完結して動作することができる。

それはともかくサブ・ルーチンは、あくまでもメイン・ルーチンの一部の機能であり
変数もメイン・ルーチンと完全に共用している。
これに対してプロシージャーとは、プロシージャーだけでロジックが完結しており
プロシージャー単独でも動作することができるロジックである。

ローカル変数とグローバル変数

従ってプロシージャーの場合は変数もプロシージャー内部で独自に定義されており
プロシージャー外部のロジックからプロシージャー内部の変数を参照したり
変更することはできない。
このようなプロシージャー内部の変数のことをローカル変数と呼ぶ。
すべてのプロシージャーから共有して使用することができる変数のことを
グローバル変数と呼ぶ。

プロシージャーは結果を戻す

サブ・ルーチンではロジックは実行されるのだが、実行の結果はどれなのかが
不明瞭な場合がある。
このサブ・ルーチンで何をやることが目的なのかを読み手が推測して判断しなければ
ならないのだ。
これに対してプロシージャーの場合は明確に結果を戻すので目的がハッキリしている。
つまり目的がわかりやすいのである。

■ オープン系の関数はすべてプロシージャーである。

オープン系と言われる開発言語の「関数」は、すべてプロシージャーであり、
その関数の中だけですべてが完結できるように記述されている。

VisualBASIC・・・関数
VBA・・・サブ・プロシージャー
Visual C++・・・関数
C#, C・・・関数

[ サブ・ルーチンのある開発言語 ]
RPG, COBOL
※ただし ILE-RPG にはプロシージャーはあるが ILE-COBOL にはプロシージャーはない。

■ なぜプロシージャー化が必要なのか ?

サブ・ルーチンをプロシージャーに置き換えることが、なぜ近代化であると言えるのだろうか ?
それはプロシージャーは最も小さなビジネス・ロジックの単位でありプロシージャーはそれ自体で
完結しているので他のプログラムから自由に呼び出して再利用することができるからである。
つまり言われて久しい「オブジェクト指向」を実現することができるからである。

プロシージャーは、そのプログラムの中だけで利用できるのではなく他のどのような
プログラムからでも呼び出して再利用することができるビジネス・ロジックである。
これに対してサブルーチンはあくまでもメイン・ルーチンの一部であるので他のプログラムからは
参照することもできない。

例えば社内で独自の処理方式があったとする。
納期算出の処理は社内カレンダーを参照して更に取引先のカレンダーも参照する、というお決まりの
処理があるとすると、その処理をプロシージャー化しておけば他のどのようなプログラムからでも
参照して利用することができる。
さらに広げてそのお決まりの算出方法を Webで公開して取引先からでも利用可能にすることもできる。
(Webサービス)
すべての共有できる有用なビジネス・ロジックをプロシージャー化しておけばある開発要求が
あったときには、プロシージャーを寄せ集めるだけで(マッシュアップ) 新しい要求に迅速に
応えることができるようになるはずである。( SOA = Servive Oriented Application )

プロシージャー化しておけば未来のプログラムは、プログラムという考え方は無くなるかも知れない。
社内の必要はすべてのビジネス・ロジックがプロシージャー化されると新規開発は HTML 上の
JavaScript を使ってマッシュアップするだけの作業となり、元々は社内プログラムが
RPG や COBOL を使って組まれていたなんて誰も意識しなくなるかも知れない。
主たる開発のプラットフォームは 5250エミュレータ上ではなくブラウザ上での開発となる日も
遠くはないはずだ。

■ サブ・ルーチンとプロシージャーの記述の比較

[ サブ・ルーチンによる旧型の記述 ]

0001.00 C                   EXSR      CHECK
0002.00 C******************************************************
0003.00 C     CHECK         BEGSR
0004.00 C******************************************************
0005.00 C                   MOVE      *BLANKS       TKNMJ
0006.00 C                   SETOFF                                       99
0007.00 C     JUTKCD        CHAIN     TOKMAS                             99
0008.00 C   99              SETON                                        63  99    ERRMSG
0009.00 C   99              GOTO      CHKEND
0010.00 C                   MOVEL     TKNMJ         TKNAME
0011.00 C     CHKEND        ENDSR

サブ・ルーチンの場合はサブ・ルーチンの中で何をやっているのか
読んでみないと出力結果がわからない。

[ プロシージャー化された新しい記述 ]

001.00 D GET_TKNAME      PR            42A
002.00 D  TKCD                         10A   VALUE
003.00
004.00 C                   EVAL      TKNAME = GET_TKNAME(JUTKCD)
005.00
006.00 *********************************************************
007.00 P GET_TKNAME      B                   EXPORT
008.00 *********************************************************
009.00 D                 PI            42A
010.00 D  TKCD                         10A   VALUE
011.00
012.00 C     TKCD          CHAIN     TOKMAS
013.00 C                   IF        %FOUND
014.00 C                   RETURN                  TKNMJ
015.00 C                   ELSE
016.00 C                   RETURN                  *BLANKS
017.00 C                   ENDIF
018.00 P                 E

プロシージャーの場合は実行に必要な入力値(入力パラメータ) と出力結果が
非常に明確である。

プロトタイプ:
001.00 D GET_TKNAME      PR            42A
002.00 D  TKCD                         10A   VALUE

を見ただけで、その機能を把握することができる。

この例では読者に理解できるような非常に簡単な例を示しているが
実際の業務において社内の複雑な処理(ビジネス・ロジック)をプロシージャー化しておくと
再利用も簡単で品質に優れて保守性にも効果を発揮することになる。