基幹システム移行プロジェクトで、私は1つの気づきを得ました。それは、
私が見ているのは「ドメインの言葉」が蒸発したソースコードだ。
「正しい名前をつけること」で、
コードに「失われたドメイン知識を再構築すること」が必要だ。
これこそ、エンジニアの仕事の本質ではないか。
ということです。
この記事は、レガシーマイグレーションの課題と対処方針を共有する記事です。
0.はじめに
どうしてこの結論に至ったのか。
背景から順に説明します。(お急ぎの方はまとめからご覧ください)
現在進行中のシステム移行プロジェクト。対象は、長年会社を支えてきたAS/400(IBM i)上のシステムです。
AS/400(IBM i)は、時に、レガシーシステムとして「乗り越えるべき過去の遺物」として登場します。しかし、課題の本質は、ハードウェアの古さにはないと気づきがありました。
1. オーパーツとしてのAS/400(IBM i)
誤解を恐れずに言えば、AS/400(IBM i)というアーキテクチャは「オーパーツ」です。
1978年の源流(System/38)時点で、ハードウェアレベルの「オブジェクト指向」がありました。
そう感じた一番の理由は「単一レベル記憶(Single Level Storage)」の存在です。
現代のORMに通じるテーマ
これはメモリとディスクの境界がなく、開発者が意識することなく裏側でシステムがデータを永続化します。現代の言語やORMがアプリケーション層で(苦心して)実装している「永続化の隠蔽」を、OSとハードウェアが一体となって解決します。
基盤は堅牢なのに、なぜレガシー?
さらに、ファイルもプログラムも、すべてオブジェクトとして保護され、不正なポインタ操作など入り込む余地がない堅牢な基盤です。
加えて垂直統合された開発環境(ソースコード管理、全文検索、スプール管理)は、開発・保守運用の負担を軽減してくれます。
では、なぜその上で稼働するアプリケーションは「変更困難なレガシー」となっているのか。
2. 厳しすぎる「物理的制約」と「バイト操作」的アプローチ
もちろん当時のエンジニアの能力不足などではありません。
原因は、当時の厳しすぎる「物理的制約」への適応です。
物理的制約と適応のメカニズム
| 制約の対象 | 当時の具体的な制約 | 生存戦略(適応した結果) |
|---|---|---|
| 1.CPU・コンパイラ | 計算能力の未発達 | メモリ配置やCPU処理に直結したコードが必要。抽象化の余地は少ない。 |
| 2.画面サイズ | 80桁×24行という画面 | 変数名やカラム名を短縮・記号化し、一覧性を確保 |
| 3.メモリ・ストレージ | メモリ・ディスク容量が少なく高価 | 状態を「意味のある言葉」より、最小バイトの「区分値」を採用 |
適応の具体例
- 名前の圧縮
- 画面幅が狭いため長い項目名は表示できません
- カラム名も現代なら
CustomerNameとするところCSTNMABC006といった記号で表現
- コード化
- ディスク容量は貴重なので、データ量を抑える必要があります
-
Status.Shippedという状態は'2'という値にしてデータ量を節約
そのため、コードに記述されるのは 「意味を削ぎ落とし、機械に最適化したバイト列(Bytes)操作的アプローチ」です。「意味」を知るには、人間が「紙の設計書」をひも解いて理解する方法を採用しました。
当時の事情として、メモリやディスクより「紙」のほうが断然安かったのです。
この適応は、当時の経済的合理性に基づいた誠実な判断です。
可読性よりも『適応』を選ぶしかなかったのです。
そして現代へ
現代に話を戻します。
今、私の前にあるのは「ドメインの言葉」が蒸発したソースコードです。
かつての「適応」が残したもの
- カラムから「名前」は失われ
- 上から下へ書かれたロジックは「バイト列を組み立てる処理」の羅列
そこから「業務の意図」を汲み取るのは「人間」の仕事です。
if文から「業務の意図」を読み取る
コードを開いて、if文を見ます。
「記号と記号を判定」し「値を上書きしている」のはわかります。
しかし、ここから意図を読み解くのは「認知負荷」の高い作業です。
テーブルの項目名(カラム名)から「業務の意図」を読み取る
「項目名」は...AS/400(IBM i)を開くと
「短い記号」とは別に「日本語名」が登録されてますね。さすがです。
しかし、そのカラムは使いまわされ「項目名」と「意味」は切り離されています。
また、とある項目では「何バイト目から何バイト目」に、新しい意味が込められているようです。
これもまた、意図を読み解くのは「認知負荷」の高い作業です。
3. 現代の制約は「認知限界」である
ハードウェアが潤沢になった現代、制約条件(ボトルネック)も変化します。希少資源が移動したと言えます。
当時の希少資源
それは「計算能力・メモリ・ディスク・画面幅」です。
そのため「意味」を圧縮し、人間が脳内で解凍するのが最適解でした。
その後、CPU・コンパイラが進化し、メモリ、ディスクは単価が下がり、画面は広くなりました。
現代の希少資源
それは「開発者の認知能力・時間」です。
そのため「意味」を展開(解凍)し、コード上に明示するのが最適解です。
当時の最適解が負債となる
このことから、かつて最適解だった「バイト操作視点の高効率処理」は、今や「コードを読む人間の認知リソースを食いつぶす負債」へと反転しました。
CSTNM が何を指すのか、'2' が何を意味するのか。
それを解読するために、現代の希少資源である開発者が、大量の設計書やベテランの伝承を、脳内で解凍しなければなりません。
レガシーマイグレーションとは
レガシーマイグレーションの本質は、単にCOBOLをJavaやC#に書き換えることではありません。(もし思考停止でCOBOLを書き換えれば、それは「モダンな言語で書かれたCOBOL(現代版の大福帳システム)」です)
私がやるべきは、かつて物理的制約によってコードから追い出された「意味」と「文脈」を、コードで表現することです。
今ならわかること
外部の移行パートナーに協力を打診するような場面で 「ドキュメントありますか?」 と聞かれたことはありませんか?
それは 「バイト列を組み立てるプログラム」だけ渡されても「業務の意図」はわかりません。 というメッセージなのです。1
4. 2つのアプローチ
今、私は意味を回復するために、2つのアプローチを試みています。
1.失われた 「意味」 を回復する
1つ目は、いわゆる「混然一体となったデータ構造」(大福帳DB)を整理し「名前」をつけることです。
これは、データ中心アプローチ(DOA)2由来の視点です。
DOAには、大福帳DBに挑んできた先人たちの知恵が詰まっています。
正規化と関数従属性の整理を通じて、1テーブル数百カラムのデータ構造を「人間が認識する単位」に書き直す作業です。これは、データの不用意な破壊を防ぎ、システムの骨格となります。
いわば『データ構造への名付け』です。『大福帳データベース』というカオスを制するために、DOA的アプローチを用います。
2.埋もれた「意図」を発掘する
2つ目は、「バイト列を組み立てる処理の羅列」に「名前」をつけることです。
これは、ドメイン駆動設計(DDD)由来の視点です。
DDDは単に 記号(CSTNM) を ユビキタス言語(CustomerName) へ書き換える、だけではありません。
コードに書かれた「上から下へ継ぎ足された秘伝のif文」から 業務の意図 を発掘し、「名前」をつけることに価値があります。(そのためにも、CSTNM を CustomerName へ書き換える必要があります。)
いわば『振る舞いへの名付け』です。『バイト列を組み立てる処理の羅列』(手続きの羅列)というカオスを制するために、DDD的アプローチを用います。
(補足)かつてのプログラムにおけるビジネスルール
「もしステータスが'2'で、かつ在庫数がマイナスなら……」
当時、こういったビジネスルールは、上から下へとつながるif文として記述しました。
機能追加時は「既存のコードに手を入れることなく、途中にif文を追加、値を上書きする」
これが副作用を抑え、安く早く安全に開発する最適解だったのです。
こうした条件分岐の羅列を分解し、「出荷可能判定(CanShip)」や「在庫引当ルール(AllocationRule)」 といった「名前」を与えて、ドメインモデル(エンティティや値オブジェクト)の近くに再配置する。
つまり、上から下へ流れる「手続き」の中に埋もれていたビジネスルールを、オブジェクトが常に守るべき「不変条件(業務ルール)」として宣言し直すこと。
それが「振る舞いへの名付け」の本質です。
なぜ2つも必要なのか
答えは簡単です。以前、1つ目の視点で組み立てたシステムがあり、その保守を通じて「痛み」を知ったのです。
そのシステム、データ構造は堅牢でしたが
- 「在庫引き当てで、おかしなロットが引きあたった」
- 「金額にマイナスがでているがなぜか」
このような状況が発生し、その都度、原因を究明し対処することが「人間」の担当になっていたのです。
なぜか。「振る舞い」がコードの複数の層やSQLに分散し、認知負荷が高くなっていたのです。
この「痛み」に対処するため、2つの手法が必要なのです。
まとめ:コンテキストの継承
「AS/400だからできない」「古いからダメだ」では、解像度が低く、焦点がぼやけてしまいます。
- 当時の合理性
- 高い信頼性、整合性、そして当時のハードウェア資源で最大のパフォーマンスを出すための密結合。
- 現在の課題
- ビジネスの多角化やリアルタイム性の要求に対し、当時の「最適解」が現在の「制約」に変わってしまった。
向き合うべきは、かつてのリソース不足に由来する 「意味の欠落」と「意図の埋没」 です。
- 大福帳DBの構造を、名前を付けた構造(モノコト)に整える
- これは、構造への名付け(DOA2由来のアプローチ) です
- 上から下へ継ぎ足された秘伝のif文から、名前を付けた不変条件に整える
- これは、振る舞いへの名付け(DDD由来のアプローチ) です
レガシーマイグレーションとは
古い言語を新しい言語に翻訳することではありません。
- 『データ構造でビジネスの整合性』で表現する
- 『不変条件(業務ルール)』を、コードの中心(ドメインモデル)に取り戻す
つまり 「名付け(=概念の定義)」 です
データ構造(DOA)とドメインモデル(DDD)で「名前」をつけていくこと
これが大福帳データベース(と、そのシステム)の攻略法です。3
アプローチの比較:構造と振る舞いへの名付け
表1:負債の正体
| 項目 | 構造への名付け | 振る舞いへの名付け |
|---|---|---|
| 制するべき 「カオス」 |
大福帳データベース (例:1テーブル数百カラム) |
バイト列を組立てる処理の羅列 (例:手続きの羅列/カラム・状態の記号化) |
| 「痛み」 |
どれが正しいデータか分からない (不整合を直す手間に追われ、データの活用に苦戦する) |
どこを直せばいいか分からない (影響範囲の調査に追われ、変更箇所の特定に苦戦する) |
| 得られなかった「価値」 | 業務・経営判断に使える 正確な情報(統計・分析) |
ビジネスの成長に追従する 迅速な機能改善 |
表2:設計の指針
| 項目 | 構造への名付け | 振る舞いへの名付け |
|---|---|---|
| 主な対象 | データ(構造) | ロジック(振る舞い) |
| 名付けの役割 |
「誰の情報か?」の名づけ (単価は「商品」に、 住所は「顧客」に帰属) |
「何をする処理か?」の名づけ (ロジックの塊に 「送料を算出する」と名付ける) |
| 価値の源泉 | データの整合性と 長期的な再利用性 |
ビジネスルールの 変更に対する適応力 |
-
個人的には、ここでいう「バイト列」を意識してゼロアロケーションで最適化する等、そういった文脈の取り組みは控えめに言って大好きです。現場でも局所的に仕込んでいます。ですが、あくまでライブラリレベルです。今回のテーマのような「業務システム」の文脈で「意味」を失ってまでやる必要はありません。 ↩
-
ここで言うデータ中心アプローチ(DOA)とは、渡辺幸三氏や佐藤正美氏らが提唱する、業務の事実(ファクト)から不変のデータ構造を導き出す設計思想を指します。実装技術の変遷に左右されない「ビジネスの論理構造」を最上位に置くことで、長期的な保守性と整合性を両立させるアプローチとして定義しています。日本独特なのでしょうか? ↩ ↩2
-
本記事そのものが「名づけ万能説」になっている点。それが次の課題です。すべての移行が完了したあと、待っているのは「意味の希薄化」であり「希少資源」の移動です。変わり続ける「意味」「希少資源」に、どう対処するのか?AIがCI/CD等で防いでくれるのか。興味は尽きません。 ↩