はじめに
わたしは現在従事しているプロジェクトに参画したときは、いち開発者でした。ほかに3名の開発者がいました。 それぞれの開発者がRPAを導入されたい依頼者にヒアリング、要件定義を実施し、RPA開発を実施しました。 チーム開発ではなく、一人ひとりが要件ヒアリングから実装、テスト、納品までを担当しました。
年度が終わったとき、4人のうち、ノークレームで納期を守り続けたのは私だけでした。
ほかの3人はクレームが入る、もしくは納期が間に合わない、ということが度々ありました。 私との違いは何だったのか。 後から知りました。それに「ドメイン駆動設計(DDD)」という名前がついていることを。
言葉の定義がズレると何が起きるか
私は以前、高速道路のトンネルのアンカーボルト健全性検査の研究開発チームに携わっていました。超音波探傷やアコースティックエミッションを応用して、腐食や劣化を定量的に検出する手法と機器を研究するチームの一員として、モックアップの作成、現場での測定、検査機器のアプリ開発など、多岐にわたる業務を担いました。
研究の世界では、言葉の定義が少しでもズレると致命的なことになる。
「異常あり」と判定するとき、それは超音波の反射強度がどの閾値を超えた場合なのか。 「劣化している」とは、健全なボルトと比べてどの程度の変化を、何回の測定で確認した結果なのか。 「改善した」とは、何を基準にどれだけ変化したことなのか。
勝手な思い込みで走ってしまうと、何週間もかけた実験が「そもそも条件が違った」という話になる。 時間とコストだけでなく、信頼も失う。
この経験が、私の根っこにあります。 言葉の定義があいまいなまま動くことへの、強烈な違和感。
RPAリーダーになって、仕様書を書き始めた
研究開発、アプリ開発の現場を離れ、ある機会があってSIerでRPAリーダーになりました。 300件を超える業務自動化の相談を受け、仕様書を書き続けました。
私が自然にやっていたことがあります。
現場の担当者が使っている言葉を、そのまま仕様書に書く。
こちらの言葉に変換しない。「input処理」とは書かない。担当者が「Excelの取り込み」と言っているなら「Excelの取り込み」と書く。「システムへの打鍵」と言うなら「打鍵」と書く。
仕様書はこんな形になりました:
RPA開始(担当者さまRPAスタートボタンクリック)
↓
1.RPA設定ファイル読み込み
↓
2.新規動作であるか、ポップアップメッセージで担当者に確認
↓
(担当者選択後、OKボタンクリック)
3.新規動作(条件分岐)
True:4.へ
False:5.へ
↓
4.〇〇サイトの〇〇をクリックし、表からinputファイル(Excelファイル)を作成
↓
5.作成したinputファイル読み込み
↓
6.inputファイル、RPA処理欄、空白すべて処理(Loop)
数字は順番ではなくナンバリングだ。 後から4と5の間に処理を追加するとき「4A」と書く。再ナンバリングしない。 詳細が必要なら「7-1」「7-2」と階層化する。
この仕様書は、担当者・上司・開発者・開発管理者の全員が読める共通言語になりました。 トラブルが劇的に減りました。
ある日、DDDという言葉を知った
しばらくして、ドメイン駆動設計(DDD)を学びました。
読み始めてすぐ、既視感がありました。
DDDの核心概念のひとつ、「ユビキタス言語」。
プロジェクト内の全員が使う共通の用語。 ビジネス側もエンジニアも同じ言葉を使い、その言葉をそのままコードに反映する。
私がやっていたことでした。
仕様書の中で現場の言葉を使うのは、ユビキタス言語の実践だった。 担当者・上司・開発者が同じ言葉で話せるようにしたのは、DDDが目指す姿そのものだった。
300件かけて自分で辿り着いたものに、2003年からすでに名前がついていました。
私に足りていなかったもの:用語集
気づいたことがあります。私の仕様書には用語集がなかったのです。
現場の言葉を使ってはいました。でも「その言葉がどういう意味か」を文書として明示していませんでした。
たとえば「inputファイル」。 私の頭の中では「〇〇サイトから取得した、RPA処理対象のExcelファイル」だ。 でも新しい担当者が仕様書を読んだとき、それは伝わらない。
DDDでは、用語集をプロジェクトの最初に作る。
用語集の例
┌──────────────┬─────────────────────────────────────────┐
│ 用語 │ 定義 │
├──────────────┼─────────────────────────────────────────┤
│ inputファイル │ 〇〇サイトから取得した処理対象Excelファイル │
│ 新規動作 │ 前回実行時のinputファイルが存在しない初回実行 │
│ RPA処理欄 │ inputファイルの処理済みフラグ列。空白=未処理 │
│ 打鍵 │ 〇〇システムへのデータ入力操作 │
└──────────────┴─────────────────────────────────────────┘
この1枚が仕様書の冒頭にあるだけで、全員の認識が揃う。
DDDがさらに一歩進める:コードまで同じ言葉にする
仕様書で現場の言葉を使うだけでは、まだ半分だ。
DDDは、その言葉をそのままコードに持ち込む。
# ❌ 翻訳されたコード(現場の言葉が消えている)
def process_item(flag):
if flag == 1:
load_file()
execute_loop()
# ✅ ユビキタス言語を反映したコード(仕様書と同じ言葉)
def start_rpa(is_new_operation: bool):
config = load_rpa_config()
if is_new_operation:
input_file = fetch_input_file_from_site()
else:
input_file = load_existing_input_file()
process_all_unprocessed_rows(input_file)
下のコードは、仕様書を読んだ担当者が見ても意味がわかる。 コードが現場の言葉でできているからだ。
これがユビキタス言語を「仕様書だけ」でなく「コードまで」貫くということだ。
DDDの本質は、難しい技術じゃない
DDDを学び始めると、Entity、ValueObject、Aggregate、Repositoryといった概念が出てくる。 それらは確かに重要だ。でもそれはDDDの「道具」であって「本質」ではない。
DDDの本質を一言で言うと:
論理的に、順序立てて整理し、全員の共通認識にすること。
研究開発の現場で身につけたこと。 RPAの仕様書で自然にやっていたこと。 DDDはそれを体系化した設計手法でした。
当たり前のことだ。でも「当たり前のことを面倒だからやらない」が積み重なって、システム開発の多くの混乱が生まれる。
いま、わたしはAIを使ったアプリ開発にも携わっていますが、そこでもDDDを全面に出すようにしています。AIはユビキタス言語と相性がよいのです。用語集や仕様書で定義した言葉をそのままプロンプトに使うと、AIが生成するコードも現場の言葉に近づきます。「AIに任せる前に、まず言葉を定義する」——これはDDDの本質と同じです。
なぜノークレームだったのか
冒頭の話に戻ります。
ほかの3人は、おそらく悪意はありませんでした。 ただ、現場の言葉を確認せずに、自分の解釈で動いていました。 「こういう意味だろう」と思って仕様書を書き、実装していたのです。
私がノークレームだった理由は、技術力でも経験年数でもありません。 「あなたが言う〇〇とは、△△と理解しましたが、相違ないでしょうか?」とお聞きして、認識をすり合わせ、その内容をドキュメントに残したからです。
そのやりとりから用語集が生まれ、仕様書が生まれ、コードが生まれます。
300件の現場経験で気づいたことを、DDDという言葉で整理できた今、もっと意識的にこれを使っていこうと思っています。
まとめ
- 現場の言葉をそのまま仕様書に書くのは、ユビキタス言語の実践だった
- 用語集を仕様書の冒頭に置くだけで、全員の認識が揃う
- DDDはその言葉をコードにまで貫く
- DDDの本質は「論理的に整理し、共通認識にすること」
- 難しい技術ではなく、当たり前を面倒がらずにやること
次に読むもの
- 『ドメイン駆動設計入門』(成瀬允宣)← 日本語で読める最良の入門書
- 『エリック・エヴァンスのドメイン駆動設計』← 原典。難しいが最も深い
関連記事:野良UiPathシナリオをAIで仕様書化し、DDDで整理してPythonに移行する(近日公開)