Eric Evans が『Domain-Driven Design』を出版したのは 2003 年。しかし、その核心にある設計思想は、1959 年に生まれた COBOL にすでに組み込まれていた。
これは偶然ではない。COBOL は Common Business-Oriented Language(共通事務処理用言語)として、業務ドメインを正確にコードに写し取ることを目的に設計された言語だからだ。
🗺️ 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 的なモダナイゼーションのアプローチだ。
📚 さらに詳しく学ぶ
この記事では概要を紹介しました。具体的なコード例と段階的な実装手順は、学習教材シリーズで詳しく解説しています。
- COBOL モジュール設計 — サブルーチン・外部 CALL・COPY 句によるモジュール化と DDD 的設計の詳細
- COBOL 文法基礎 — COBOL の基本文法リファレンス
- COBOL 業務ロジック実装 — 銀行入出金・受注システムの実装例
- AS400 モダナイゼーション戦略 — 新旧共存戦略とマイグレーションパターン
CTS では AS/400 モダナイゼーションを「コードを書き直す」のではなく、レガシーに埋め込まれたドメイン知識を抽出して再構築するアプローチで支援しています。お問い合わせはこちら。