ここでは先のプログラム UPD005 を複数のモジュールへ分割する手法について紹介する。
分割する分類は MVC 3階層モデル を基本として、あたかも VC++ のプロジェクトと同じような分類となる。
UPD0051 : コントロール ( CONTROL ) | ・・・ | メイン・ルーチンのフローを記述する。
これは VC++ のアプリケーション・クラスに相当する。 UPD0051 は全体の流れだけを記述している。 |
|---|---|---|
UPD0052 : 初期画面 ( DSPHEAD ) | ・・・ | 初期画面 ( DSPHEAD ) を表示して機能キーを処理する。 |
UPD0053 : 明細画面 ( DSPDTA01 ) | ・・・ | 明細画面 ( DSPDTA01 ) を表示して機能キーを処理する。 |
UPD0054 : 終了画面 ( ENDOPT ) | ・・・ | 終了画面 ( ENDOPT ) を表示して機能キーを処理する。 |
UPD0055 : 更新 | ・・・ | 商品マスター ( SHOHIN ) を更新する記述。 |
MVC 3階層モデル として表現すると次のようになります。
メイン・ルーチンのフローを記述する。 全体の流れだけを記述している。
---------------------------------------------------------------------------------------
0001.00 H DFTNAME(UPD0051) DATEDIT(*YMD/)
0002.00 F******** 商品マスターの登録 ***************************
0003.00 F*****************************************************************
0004.00 D DSPHEAD_ PR 4A
0005.00 D SHCODE 10A VALUE
0006.00
0007.00 D DSPDTA01_ PR 4A
0008.00 D SHCODE 10A VALUE
0009.00
0010.00 D ENDOPT_ PR 4A
0011.00
0012.00 D UPD_SHOHIN PR 1S 0
0013.00 D OPT 1S 0 VALUE
0014.00 D INDATA 1024A VALUE
0015.00
0016.00 D SHCODE S 10A IMPORT
0017.00 D INDATA S 1024A IMPORT
0018.00 D ANS S 1A IMPORT
0019.00 D ADDREC S 5S 0 IMPORT
0020.00 D CHGREC S 5S 0 IMPORT
0021.00 D DLTREC S 5S 0 IMPORT
0022.00 D FKEY S 4A
0023.00 D CF03 S 4A INZ('CF03')
0024.00 D CF10 S 4A INZ('CF10')
0025.00 D CF12 S 4A INZ('CF12')
0026.00 D CF23 S 4A INZ('CF23')
0027.00 D ADD S 1S 0 INZ(1)
0028.00 D CHG S 1S 0 INZ(2)
0029.00 D DLT S 1S 0 INZ(3)
0030.00 D UPD S 1S 0 INZ(4)
0031.00 D RES S 1S 0
0032.00 C*----------------------------------------------------+
0033.00 C START TAG
0034.00 C EVAL FKEY = DSPHEAD_(SHCODE)
0035.00 C*----------------------------------------------------+
0036.00 C SETOFF 919299
0037.00 C*( CF03 )- 終了
0038.00 C FKEY IFEQ CF03
0039.00 C SETON LR
0040.00 C LR EXSR LRRTN
0041.00 C LR RETURN
0042.00 C GOTO START
0043.00 C END
0044.00 C*----------------------------------------------------+
0045.00 C DSPLY TAG
0046.00 C EVAL FKEY = DSPDTA01_(SHCODE)
0047.00 C*----------------------------------------------------+
0048.00 C SETOFF 919299
0049.00 C*( CF03 )- 終了
0050.00 C FKEY IFEQ CF03
0051.00 C SETON LR
0052.00 C LR EXSR LRRTN
0053.00 C LR RETURN
0054.00 C GOTO DSPLY
0055.00 C END
0056.00 C*-( CF12 )- 前画面
0057.00 C FKEY IFEQ CF12
0058.00 C GOTO START
0059.00 C END
0060.00 C* ( 入力内容のチェック )
0061.00 C EXSR CHECK
0062.00 C 99 GOTO DSPLY
0063.00 C*-( CF10 ) 更新
0064.00 C FKEY IFEQ CF10
0065.00 C EVAL RES = UPD_SHOHIN(UPD:INDATA)
0066.00 C IF RES = ADD
0067.00 C EVAL ADDREC = ADDREC + 1
0068.00 C ELSE
0069.00 C IF RES = CHG
0070.00 C EVAL CHGREC = CHGREC + 1
0071.00 C END
0072.00 C END
0073.00 C GOTO START
0074.00 C END
0075.00 C*-( CF23 ) 削除
0076.00 C FKEY IFEQ CF23
0077.00 C EVAL RES = UPD_SHOHIN(DLT:INDATA)
0078.00 C IF RES = DLT
0079.00 C EVAL DLTREC = DLTREC + 1
0080.00 C END
0081.00 C GOTO START
0082.00 C END
0083.00 C*-( 実行キー )
0084.00 C GOTO DSPLY
0085.00 C******************************************************
0086.00 C CHECK BEGSR
0087.00 C******************************************************
0088.00 C ENDCHK ENDSR
0089.00 C******************************************************
0090.00 C LRRTN BEGSR
0091.00 C******************************************************
0092.00 C MOVE 'Y' ANS
0093.00 C*----------------------------------------------------+
0094.00 C DSPEND TAG
0095.00 C EVAL FKEY = ENDOPT_
0096.00 C*----------------------------------------------------+
0097.00 C*( CF03 )- 終了
0098.00 C FKEY IFEQ CF03
0099.00 C RETURN
0100.00 C END
0101.00 C*-( CF12 )- 前画面
0102.00 C FKEY IFEQ CF12
0103.00 C SETOFF LR
0104.00 C END
0105.00 C*-( 実行キー )
0106.00 C RETURN
0107.00 C ENDSR
---------------------------------------------------------------------------------------
UPD0051 はコントロールであって処理の流れだけを記述している。
つまり従来のプログラムのメイン・ルーチンに相当する。
UPD0051 は処理の流れだけを制御するのであるので、ファイルや DSPF への具体的な記述は一切、
存在していない。
具体的な処理そのものはプロシージャーを呼び出すことであり、プロシージャーは
0004.00 D DSPHEAD_ PR 4A 0005.00 D SHCODE 10A VALUE 0006.00 0007.00 D DSPDTA01_ PR 4A 0008.00 D SHCODE 10A VALUE 0009.00 0010.00 D ENDOPT_ PR 4A 0011.00 0012.00 D UPD_SHOHIN PR 1S 0 0013.00 D OPT 1S 0 VALUE 0014.00 D INDATA 1024A VALUE
のようにして、プロトタイプ、つまり型だけが定義されている。
共通して使用するために必要なフィールドは、
0016.00 D SHCODE S 10A IMPORT 0017.00 D INDATA S 1024A IMPORT 0018.00 D ANS S 1A IMPORT 0019.00 D ADDREC S 5S 0 IMPORT 0020.00 D CHGREC S 5S 0 IMPORT 0021.00 D DLTREC S 5S 0 IMPORT
のようにして IMPORT として他のモジュールから参照されるものとして定義されている。
つまり、ビジネス・ロジックはプロシージャーの型宣言だけであり、変数は IMPORT による参照である。
モジュールの作成 ( CRTRPGMOD ) によるコンパイルはこれで十分であり、モジュール ( *MODULE ) を
作成することができる。
プログラム作成( CRTPGM ) のときに初めて、参照されていたプロシージャーや変数が具体的に
どのプロシージャーや変数を指すのかをコンパイラーに宣言することになる。
このように参照オブジェクトの具体化のことを「名前解決」と呼ぶ。
「名前解決」という用語は、ポインターの位置から変数を定義すること等にもしばしば使用されるので
覚えておくと良い。
初期画面 ( DSPHEAD ) を表示して機能キーを処理する。
----------------------------------------------------------------------------
0001.00 H NOMAIN DFTNAME(UPD0052) DATEDIT(*YMD/)
0002.00 F******** 商品マスターの登録 - DSPHEAD ***************************
0003.00 FUPD005D CF E WORKSTN
0004.00 F*****************************************************************
0005.00 D DSPHEAD_ PR 4A
0006.00 D SHCODE 10A VALUE
0007.00
0008.00 D SHCODE S 10A EXPORT
0009.00
0010.00 P DSPHEAD_ B EXPORT
0011.00 D PI 4A
0012.00 D SHCODE 10A VALUE
0013.00 D CF03 S 4A INZ('CF03')
0014.00 D ENTER S 4A INZ('ENTR')
0015.00 C EXFMT DSPHEAD
0016.00 C*( CF03 )- 終了
0017.00 C *IN03 IFEQ *ON
0018.00 C CLOSE UPD005D
0019.00 C RETURN CF03
0020.00 C END
0021.00 C*( 実行キー )
0022.00 C RETURN ENTER
0023.00 P E
----------------------------------------------------------------------------
UPD0052 は初期画面 DSPHEAD を表示するだけの小さなモジュール( プログラムではない ) である。
0001.00 H NOMAIN DFTNAME(UPD0052) DATEDIT(*YMD/)
にあるように NOMAIN によって UPD0052 はメイン・ルーチンを持たないモジュールだけを作成するための
ソースである。
つまり UPD0052 は DSPHEAD_ という名前の初期画面を表示するためのプロシージャーを定義しており
エンド・ユーザーの機能キー操作によって ENTER や CF03 を戻すようにしているだけである。
0018.00 C CLOSE UPD005D
によって DSPF: UPD005D を明示的に CLOSE 命令によってクローズしているのは、モジュールの場合、
ファイルは暗黙のうちにオープンされるが、クローズは明示的に行わなければならないからである。
また、プロシージャー DSPHEAD_ は
0010.00 P DSPHEAD_ B EXPORT
の EXPORT によって公開されて、UPD0051 によって参照される。
同様に
0008.00 D SHCODE S 10A EXPORT
によってフィールド SHCODE も、ここで公開されて UPD0051 によって参照される。
従って UPD0051 は、このモジュールを組み込むことによって( CRTPGM )
DSPHEAD_ と SHCODE の名前解決を行うことができるようになる。
UPD0052 もまた、CRTRPGMOD によってコンパイルされる。
明細画面 ( DSPDTA01 ) を表示して機能キーを処理する。
-----------------------------------------------------------------------------------
0001.00 H NOMAIN DFTNAME(UPD0053) DATEDIT(*YMD/)
0002.00 F******** 商品マスターの登録 - DSPDTA01 **************************
0003.00 FUPD005D CF E WORKSTN
0004.00 FSHOHIN IF E K DISK
0005.00 FHINSHU IF E K DISK
0006.00 F*****************************************************************
0007.00 D DSPDTA01_ PR 4A
0008.00 D SHCODE 10A VALUE
0009.00
0010.00 D INDATA E DS EXTNAME(SHOHIN) EXPORT
0011.00 D DSPDTA 1 1024
0012.00 D DIM(1024)
0013.00
0014.00 P DSPDTA01_ B EXPORT
0015.00 D PI 4A
0016.00 D SHCODE_ 10A VALUE
0017.00
0018.00 D CF03 S 4A INZ('CF03')
0019.00 D CF10 S 4A INZ('CF10')
0020.00 D CF12 S 4A INZ('CF12')
0021.00 D CF23 S 4A INZ('CF23')
0022.00 D ENTER S 4A INZ('ENTR')
0024.00 C SETOFF 99
0025.00 C SHCODE_ CHAIN SHOHIN 99
0026.00 C EXSR CHECK
0027.00 C DSPLY TAG
0028.00 C EXFMT DSPDTA01
0029.00 C*( CF03 )- 終了
0030.00 C *IN03 IFEQ *ON
0031.00 C CLOSE UPD005D
0032.00 C CLOSE SHOHIN
0033.00 C CLOSE HINSHU
0034.00 C RETURN CF03
0035.00 C END
0036.00 C*-( CF12 )- 前画面
0037.00 C *IN12 IFEQ *ON
0038.00 C RETURN CF12
0039.00 C END
0040.00 C*-( CF10 ) 更新
0041.00 C *IN10 IFEQ *ON
0042.00 C EXSR CHECK
0043.00 C 99 GOTO DSPLY
0044.00 C RETURN CF10
0045.00 C END
0046.00 C*-( CF23 ) 削除
0047.00 C *IN23 IFEQ *ON
0048.00 C RETURN CF23
0049.00 C END
0050.00 C*-( 実行キー )
0051.00 C RETURN ENTER
0052.00 C******************************************************
0053.00 C CHECK BEGSR
0054.00 C******************************************************
0055.00 C* *NOKEY CLEAR @HINSHU
0056.00 C SETOFF 9993
0057.00 C SHSCOD CHAIN HINSHU 99
0058.00 C ENDCHK ENDSR
0059.00 P E
-----------------------------------------------------------------------------------
UPD0053 もまた UPD0052 と同様であり、明細画面( DSPDTA01 )の表示と処理だけを行うための
モジュールであり、プロシージャー DSPDTA01_ を公開するように作られている。
同様に CRTRPGMOD によってモジュールを作成する。
終了画面 ( ENDOPT ) を表示して機能キーを処理する。
-----------------------------------------------------------------------------
0001.00 H NOMAIN DFTNAME(UPD0054) DATEDIT(*YMD/)
0002.00 F******** 商品マスターの登録 - ENDOPT **************************
0003.00 FUPD005D CF E WORKSTN
0004.00 F*****************************************************************
0005.00 D ENDOPT_ PR 4A
0006.00 D ANS S 1A EXPORT
0007.00 D ADDREC S 5S 0 EXPORT
0008.00 D CHGREC S 5S 0 EXPORT
0009.00 D DLTREC S 5S 0 EXPORT
0010.00
0011.00 P ENDOPT_ B EXPORT
0012.00 D PI 4A
0013.00 D CF03 S 4A INZ('CF03')
0014.00 D CF12 S 4A INZ('CF12')
0015.00 D ENTER S 4A INZ('ENTR')
0016.00
0017.00 C MOVE 'Y' ANS
0018.00 C*----------------------------------------------------+
0019.00 C DSPEND TAG
0020.00 C EXFMT ENDOPT
0021.00 C*----------------------------------------------------+
0022.00 C*( CF03 )- 終了
0023.00 C *IN03 IFEQ *ON
0024.00 C CLOSE UPD005D
0025.00 C RETURN CF03
0026.00 C END
0027.00 C*-( CF12 )- 前画面
0028.00 C *IN12 IFEQ *ON
0029.00 C RETURN CF12
0030.00 C END
0031.00 C*-( 実行キー )
0032.00 C RETURN ENTER
0033.00 P E
-----------------------------------------------------------------------------
UPD0054 は終了画面を処理するプロシージャー ENDOPT_ を記述しているだけである。
他と同様、CRTRPGMOD によってモジュールを作成する。
商品マスター ( SHOHIN ) を更新する記述。
更新記述を独立したモジュールとしたのは VC++ 等で「シリアライズ」と呼ばれている
データ更新のための独立した記述とするためである。
UPD0055 は、他の多くのモジュールやプログラムも参照して数多く利用されることが
予想されるので DLL のようなサービス・プログラム ( *SRVPGM ) として作成しても良いくらいである。
例えば商品マスターを更新するときには、同時に商品在庫マスターも更新する必要があるのであれば
それを UPD0055 に記述しておいてカプセル化することができる。
商品マスターを更新することが発生した他のプログラムではプログラマーが UPD0055 の中で
どのような処理が行われるのかを知っている必要はない。
商品マスターを更新するときには、とにかく UPD0055 をバインドすれは良いというだけで十分である。
--------------------------------------------------------------------------------- 0001.00 H NOMAIN DFTNAME(UPD0055) DATEDIT(*YMD/) 0002.00 F******** 商品マスターの登録 - UPD_SHOHIN ***************************** 0003.00 FSHOHIN UF A E K DISK 0004.00 F***************************************************************** 0005.00 D UPD_SHOHIN PR 1S 0 0006.00 D OPT 1S 0 VALUE 0007.00 D INDATA 1024A VALUE 0008.00 0009.00 P UPD_SHOHIN B EXPORT 0010.00 D PI 1S 0 0011.00 D OPT 1S 0 VALUE 0012.00 D INDATA 1024A VALUE 0013.00 0014.00 D SAVDTA S 1 DIM(1024) 0015.00 D SAVEDS E DS EXTNAME(SHOHIN) 0016.00 D DSPDTA 1 1024 0017.00 D DIM(1024) 0018.00 D ADD S 1S 0 INZ(1) 0019.00 D CHG S 1S 0 INZ(2) 0020.00 D DLT S 1S 0 INZ(3) 0021.00 D UPD S 1S 0 INZ(4) 0022.00 D TRUE S 1S 0 INZ(0) 0023.00 D FALSE S 1S 0 INZ(-1) 0024.00 C*----------------------------------------------------+ 0025.00 C TRNKEY KLIST 0026.00 C KFLD SHCODE 0027.00 C*----------------------------------------------------+ 0028.00 C MOVEA(P) INDATA DSPDTA 0029.00 C OPT COMP ADD 41 0030.00 C OPT COMP CHG 42 0031.00 C OPT COMP DLT 43 0032.00 C OPT COMP UPD 44 0033.00 C SETOFF 90 0034.00 C TRNKEY CHAIN SHOHIN 90 0035.00 C 41 0036.00 COR 42 0037.00 COR 44 MOVEL(P) INDATA DSPDTA 0038.00 C*----------------------------------------------------+ 0039.00 C 41 0040.00 CAN 90 0041.00 COR 44 0042.00 CAN 90 WRITE SHOHINR 0043.00 C 42 0044.00 CANN90 0045.00 COR 44 0046.00 CANN90 UPDATE SHOHINR 0047.00 C 43 0048.00 CANN90 DELETE SHOHINR 0049.00 C*----------------------------------------------------+ EXCPT 0050.00 C CLOSE SHOHIN 0051.00 C 41 0052.00 CAN 90 0053.00 COR 44 0054.00 CAN 90 RETURN ADD 0055.00 C 42 0056.00 CANN90 0057.00 COR 44 0058.00 CANN90 RETURN CHG 0059.00 C 43 0060.00 CANN90 RETURN DLT 0061.00 C RETURN FALSE 0062.00 P E ---------------------------------------------------------------------------------
UPD0055 は商品マスター( SHOHIN ) を更新して更新結果が追加、変更または削除であったのかの
結果をプロシージャーの結果の値として戻す。
更新に失敗したときには FALSE を戻す。