LoginSignup
1
0

More than 3 years have passed since last update.

オブジェクト指向言語じゃない、COBOLで依存性逆転の法則を実践してみる

Posted at

動機

オブジェクト指向言語じゃない、COBOLで依存性逆転の法則を実践してみて、疎結合の理解を深める。
プログラミング言語の制約が色々あるので、イマイチですが(COBOLには動的に依存性を注入するような仕組みがなく、コンパイル&リンク時に具象モジュールを結合しなければいけないなど)、疎結合な内部設計の発想を広げるということで。

Wikipedia 依存性逆転の法則

この原則に従うとソフトウェアの振る舞いを定義する上位レベルのモジュールから下位レベルモジュールへの従来の依存関係は逆転し、
結果として下位レベルモジュールの実装の詳細から上位レベルモジュールを独立に保つことができるようになる。
A. 上位レベルのモジュールは下位レベルのモジュールに依存すべきではない。両方とも抽象に依存すべきである。
B. 抽象は具象に依存してはならない。具象が抽象に依存すべきである。
この上位レベル、下位レベルの両方とも抽象に依存しなければならないと言う要求により、この設計原理は一部の人々のオブジェクト指向プログラミングに対する考え方を反転させる。

シナリオ1

CSV形式で商品名と価格を出力するCOBOLアプリ、PRICE-APPを作ります。

APPLE,12345

従来のレイヤーパターン

上位レベルのプログラム(PRICE-APP)は下位レベルのプログラム(SHOW-PRICE-CSV)をCALL。

ソースファイル名=PRICE-APP.cbl(PROGRAM-ID=PRICE-APP)
 ---> ソースファイル名=SHOW-PRICE-CSV.cbl(PROGRAM-ID=SHOW-PRICE-CSV)

依存性逆転パターン

COBOLには抽象クラスがないので、どうするか? PROGRAM-IDを抽象クラスに見立て、ソースファイル名を具象クラスに見立てます。

ソースファイル名=PRICE-APP.cbl(PROGRAM-ID=PRICE-APP) ---> PROGRAM-ID=SHOW-PRICE
                                                                     ^
                                                                     |
                                                     ソースファイル名=SHOW-PRICE-CSV.cbl

図を書き換えているだけで、コードは何も変わっていないように見えますが、
PROGRAM-IDを抽象クラス名に見立てSHOW-PRICEに書き換えて(CSVを取り外し抽象的な名前にしてみました)、
ソースファイル名を具象クラス名に見立てて、SHOW-PRICE-CSV.cblにして俯瞰してみると、
PROGRAM-IDさえ同じなら、具象クラスは何でも良くて、差し替え可能と見えてきます。

シナリオ2

PRICE-APPの変更しないで、JSON形式で商品名と価格を出力するCOBOLアプリを作ります。

{"NAME":"APPLE","PRICE":12345}

呼び出し元のPRICE-APPを変更しないで、JSON形式のプログラムに差し替える

PROGRAM-IDとその引数を変えずに、ソースファイル名を別の名前にしてJSON形式で出力するプログラムを作り、
コンパイル&リンク時にそのソースに差し替えればJSON形式の出力アプリができます。

ソースファイル名=PRICE-APP.cbl(PROGRAM-ID=PRICE-APP) ---> PROGRAM-ID=SHOW-PRICE
                                                                     ^
                                                                     |
                                                     ソースファイル名=SHOW-PRICE-JSON.cbl

COBOLソース

下記dockerコンテナの/home/cobol直下に次の3つのファイルを作ります。

PRICE-APP.cbl
000000 IDENTIFICATION DIVISION.
000000 PROGRAM-ID. PRICE-APP.
000000*--------------------------------------------------------------
000000 ENVIRONMENT DIVISION.
000000*--------------------------------------------------------------
000000 DATA DIVISION.
000000*--------------------------------------------------------------
000000 WORKING-STORAGE SECTION.
000000 01    POUT         SYNC.
000000   03  POUTNAME     PIC X(5) VALUE 'APPLE'.
000000   03  POUTPRICE    PIC 9(5) VALUE 12345.
000000*--------------------------------------------------------------
000000 PROCEDURE DIVISION.   
000000 A00-MAIN SECTION.
000000 A00-010.
000000     CALL 'SHOW-PRICE' USING POUT.
000000 A00-EXIT.
000000     MOVE ZERO TO RETURN-CODE.
000000     GOBACK.
SHOW-PRICE-CSV.cbl
000000 IDENTIFICATION DIVISION.
000000 PROGRAM-ID. SHOW-PRICE.
000000*--------------------------------------------------------------
000000 ENVIRONMENT DIVISION.
000000*--------------------------------------------------------------
000000 DATA DIVISION.
000000*--------------------------------------------------------------
000000 WORKING-STORAGE SECTION.
000000*--------------------------------------------------------------
000000 LINKAGE SECTION.
000000 01    POUT         SYNC.
000000   03  POUTNAME     PIC X(5).
000000   03  POUTPRICE    PIC 9(5).
000000*--------------------------------------------------------------
000000 PROCEDURE DIVISION USING POUT.
000000*--------------------------------------------------------------
000000 A00-MAIN SECTION.
000000 A00-010.
000000   DISPLAY POUTNAME ',' POUTPRICE.
000000 A00-EXIT.
000000   MOVE ZERO TO RETURN-CODE.
000000   GOBACK.
SHOW-PRICE-JSON.cbl
000000 IDENTIFICATION DIVISION.
000000 PROGRAM-ID. SHOW-PRICE.
000000*--------------------------------------------------------------
000000 ENVIRONMENT DIVISION.
000000*--------------------------------------------------------------
000000 DATA DIVISION.
000000*--------------------------------------------------------------
000000 WORKING-STORAGE SECTION.
000000*--------------------------------------------------------------
000000 LINKAGE SECTION.
000000 01    POUT         SYNC.
000000   03  POUTNAME     PIC X(5).
000000   03  POUTPRICE    PIC 9(5).
000000*--------------------------------------------------------------
000000 PROCEDURE DIVISION USING POUT.
000000*--------------------------------------------------------------
000000 A00-MAIN SECTION.
000000 A00-010.
000000   DISPLAY '{"NAME":"' POUTNAME '","PRICE":' POUTPRICE '}'.
000000 A00-EXIT.
000000   MOVE ZERO TO RETURN-CODE.
000000   GOBACK.

実行環境

COBOLのちょいお試しのdockerコンテナイメージを公開してくださっているので、こちらを活用しました。

プログラムちょい替え(4)COBOLを40年ぶりにうごかしてみた:dockerでcobol, docker(81)

コンテナイメージの取得と実行

docker run -v /home/madilloar/prj/cobol:/home/cobol -it kaizenjapan/cobol /bin/bash

コンテナイメージの起動と停止

docker start boring_mendeleev
docker stop boring_mendeleev

コンテナ内に入る

docker exec -it --user root boring_mendeleev bash -p

コンパイル&リンク、及び実行

CSV形式プログラムのコンパイル&リンク

cd /home/cobol

cobc -x -o PRICE-APP PRICE-APP.cbl SHOW-PRICE-CSV.cbl

./PRICE-APP

APPLE,12345

JSON形式プログラムのコンパイル&リンク

cd /home/cobol

cobc -x -o PRICE-APP PRICE-APP.cbl SHOW-PRICE-JSON.cbl

./PRICE-APP

{"NAME":"APPLE","PRICE":12345}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0