CTS-KB
開発手法

COBOL は1959年からDDDをやっていた — レガシー言語に学ぶドメイン駆動設計

#DDD #COBOL #AS400 #設計原則 #モダナイゼーション

Eric Evans が『Domain-Driven Design』を出版したのは 2003 年。しかし、その核心にある設計思想は、1959 年に生まれた COBOL にすでに組み込まれていた。

これは偶然ではない。COBOL は Common Business-Oriented Language(共通事務処理用言語)として、業務ドメインを正確にコードに写し取ることを目的に設計された言語だからだ。

🗺️ DDD の概念と COBOL の対応

DDD と COBOL の概念対応図

DDD の概念COBOL での対応
ユビキタス言語COBOL 自体が「業務用語で書く言語」
値オブジェクトCOPY 句のレコード定義
エンティティFD + レコード(一意キーを持つ)
集約グループ項目(01レベル)
境界づけられたコンテキストプログラム単位(PROGRAM-ID)
ドメインサービス外部サブプログラム(CALL)
リポジトリファイル操作(OPEN/READ/WRITE/CLOSE)

ひとつずつ見ていく。

🗣️ ユビキタス言語 — COBOL はそれ自体が業務言語

DDD の最も重要な概念はユビキタス言語(Ubiquitous Language)。開発者と業務担当者が同じ用語を使い、その用語がそのままコードに現れるべきだ、という考え方だ。

COBOL では、業務ルールがそのまま変数名と段落名になる。給与計算を例にすると:

*> 業務用語 → 変数名(ユビキタス言語)
*>
*>   基本給     → BASE-SALARY
*>   残業代     → OVERTIME-PAY
*>   総支給額   → GROSS-SALARY
*>   税金       → TAX
*>   社会保険料 → INSURANCE
*>   手取り     → NET-SALARY

*> 業務ルール → 段落名
*>
*>   ルール1-2  → CALC-GROSS-PARA      (総支給額の計算)
*>   ルール3-4  → CALC-DEDUCTION-PARA  (控除の計算)
*>   ルール6    → VALIDATE-PARA        (入力チェック)

変数名は英語だが、これは 1959 年の制約であって思想の問題ではない。重要なのは業務用語がそのままコードの識別子になっていること。Java や C# で DDD を実践するときに行う「ドメインモデリング → クラス名・メソッド名の命名」と、COBOL の「業務ルール → 変数名・段落名の命名」はまったく同じプロセスだ。

📦 値オブジェクト — COPY 句で定義を一元化

DDD の値オブジェクトは、同一性(ID)を持たず、属性の組み合わせで意味を持つオブジェクトだ。COBOL の COPY 句(コピーブック) によるレコード定義がこれに当たる。

*> copybooks/salary-record.cpy
*> 業務ルールで使う用語がそのままフィールド名になっている

*> --- 入力: 計算に必要な情報(リクエスト) ---
01 SALARY-REQUEST.
    05 SR-EMP-ID          PIC X(5).     *> 社員番号
    05 SR-EMP-NAME        PIC X(20).    *> 社員名
    05 SR-BASE-SALARY     PIC 9(7).     *> 基本給
    05 SR-OVERTIME-HOURS  PIC 9(3).     *> 残業時間
    05 SR-OVERTIME-RATE   PIC 9(5).     *> 残業単価

*> --- 出力: 計算結果(レスポンス) ---
01 SALARY-RESPONSE.
    05 SS-GROSS-SALARY    PIC 9(8).     *> 総支給額
    05 SS-TAX             PIC 9(7).     *> 税金
    05 SS-INSURANCE       PIC 9(7).     *> 社会保険料
    05 SS-NET-SALARY      PIC 9(8).     *> 手取り
    05 SS-RETURN-CD       PIC 9.        *> 結果コード
       88 SS-SUCCESS      VALUE 0.      *>   正常
       88 SS-ERROR        VALUE 1.      *>   エラー

この定義を COPY 句で複数プログラムから共有する。DDD で値オブジェクトを共有ライブラリに置くのと同じ設計だ。

注目すべきは 88 条件名SS-SUCCESS / SS-ERROR は、値オブジェクトに振る舞いを持たせている。DDD でいう「自身の状態を知っているオブジェクト」そのものだ。

🧱 境界づけられたコンテキスト — PROGRAM-ID で分割

DDD の境界づけられたコンテキスト(Bounded Context)は、ドメインモデルが有効な範囲を明確に区切る概念だ。COBOL では PROGRAM-ID でプログラム単位を分割し、CALL で連携する。

*> calc-salary.cob(給与計算ドメイン)
PROCEDURE DIVISION
    USING SALARY-REQUEST SALARY-RESPONSE.

CALC-MAIN.
    PERFORM VALIDATE-PARA            *> 入力チェック
    IF SS-ERROR
        GOBACK
    END-IF
    PERFORM CALC-GROSS-PARA          *> 総支給額
    PERFORM CALC-DEDUCTION-PARA      *> 控除と手取り
    SET SS-SUCCESS TO TRUE
    GOBACK.

メイン段落は「何をしているか」だけを示し、「どうやるか」は各段落に隠蔽する。1 段落 = 1 業務ルールという分割は、DDD のドメインサービスにおける単一責務の原則と同じだ。

📐 DDD の設計プロセスと COBOL の開発プロセス

DDD もCOBOL も「いきなりコードを書かない」。段階的に業務理解を深める:

#DDD のアプローチCOBOL のアプローチ
1ドメインエキスパートと対話業務ルールを日本語で書き出す
2ユビキタス言語を定義変数名・段落名を業務用語から決める
3ドメインモデルを設計COPY 句にデータ構造を定義
4境界づけられたコンテキストPROGRAM-ID でプログラムを分割
5実装段落単位で業務ロジックをコード化

COBOL の「冗長に見える構文」は、実は業務ロジックを正確にコード化するための仕組みだ。DDD が 2003 年に体系化した概念を、COBOL は 1959 年から実践していた。

🚀 モダナイゼーションへの示唆

この対応関係を理解すると、レガシー COBOL システムのモダナイゼーションが格段にやりやすくなる。

  • COPY 句のレコード定義 → そのまま DTO / 値オブジェクトクラスに変換
  • PROGRAM-ID の分割境界 → マイクロサービスの境界候補
  • 88 条件名の定義 → enum / ドメインイベントの設計材料
  • 段落名の命名規則 → メソッド名の命名にそのまま使える

「レガシーを捨てて新しく作り直す」のではなく、レガシーに埋め込まれたドメイン知識を正しく抽出する。それが DDD 的なモダナイゼーションのアプローチだ。


📚 さらに詳しく学ぶ

この記事では概要を紹介しました。具体的なコード例と段階的な実装手順は、学習教材シリーズで詳しく解説しています。


CTS では AS/400 モダナイゼーションを「コードを書き直す」のではなく、レガシーに埋め込まれたドメイン知識を抽出して再構築するアプローチで支援しています。お問い合わせはこちら