AIと育てる型定義 Part 4:ドメイン知識の集約で完成度を高める

はじめに
「この型は UI に置くべきか、API に置くべきか」で迷い始めたら、ドメイン知識が散らばっているサインです。
どのレイヤーにも属さない型(ページネーション設定・記事メタデータ仕様など)を一箇所に集約することで、コードが仕様書として機能し始めます。
開発が進むにつれて「情報の居場所」に迷うことはありませんか?
- サイト全体の共通設定や仕様が複数のファイルに散らばり始めた。
- ページネーションや見出しといった共通の概念が、各レイヤーで独自に定義されて整合性が崩れている。
- 型定義をどこに置くべきか迷い、とりあえず近くのファイルに追加することで、設計の境界が曖昧になっている。
この記事をお勧めしない人
- 型定義が適切に配置されていなくても、コンパイルさえ通れば問題ないと考えている人。
- ドメイン知識を集約することによる、保守性や開発体験の向上に価値を感じない人。
- 単なるコード整理ではなく、設計思想をコードで表現することに関心がない人。
もし一つでも当てはまらないなら、読み進める価値があるかもしれません。
ドメイン知識を各レイヤーに散らすと
- 型の使用場所に引きずられて配置を決めると、「あの型、どこにある?」が繰り返されるようになる。
- 同じ概念(ページネーション)が UI 層と API 層でそれぞれ独自定義され、一方を変えると他方とズレる。
- AI に「この型どこに置くべき?」と聞くと使用箇所の近くに置くよう提案されるため、問題が継続する。
生きた仕様書としての型定義という明るい未来
- この記事を読めば、型定義を「生きた仕様書」として機能させ、プロジェクトの完成度を高める手法が手に入る。
- 具体的には、特定のレイヤーに閉じないドメイン知識を特定し、プロジェクトの核心を一箇所に集約する設計図を手に入れられる。
- この方法は、本ブログ自身の完成度を高めるリファクタリング最終章として、その実効性を実証済みである。
私も同じでした
このブログのページネーション設定と記事メタデータの型が、UI コンポーネントと API 層にそれぞれ独自に定義されていました。
「どのレイヤーにも属さない型」を app/types/domain/ に集約したことで、AI が型の配置を迷わず判断できるようになりました。このシリーズの Part 4 です。
📝 概要
AIとの協調リファクタリングシリーズ、ついに最終章です。これまでの道のりを振り返ってみましょう。
- Part 1: 単純な重複の排除
- Part 2: 『唯一の真実の源』の確立
- Part 3: 『関心の分離』の実践
今回は、このリファクタリングの総仕上げとして、プロジェクトの 「ドメイン知識」 に関わる型を集約します。サイト全体の設定、ページネーション、記事の見出しといった、特定のレイヤーに属さない共通の仕様を集約し、コードベースの完成度を飛躍的に高めます。
⚠️ 最後の課題:レイヤーを越えるドメイン知識
これまでのリファクタリングで、ほとんどの型は綺麗に整理されました。しかし、まだいくつかの型が、その役割にふさわしくない場所に残っていました。
- サイト全体の設定情報 : データアクセス層に定義されていましたが、UIコンポーネントでも広く利用されます
- ページネーション関連の型 : データ取得用、計算ロジック用、UI用と、同じ概念が各層で別々に定義されていました
- 記事の見出し情報 : 純粋ロジック層に定義されていましたが、これは記事データの一部であり、UI層でも直接利用されます
これらの型は、特定のレイヤーの責務ではなく、 「このアプリケーションがどういうものであるか」 を定義する、ドメインそのものの仕様です。
🔍 私が設計した『仕様書』としての型定義アプローチ
この問題を解決するため、私は型定義ファイルを 「仕様書」として機能させる というアプローチを採用しました。
具体的には、以下の戦略でドメイン知識を集約します:
- ドメイン知識の特定 : 特定のレイヤーに閉じず、アプリケーション全体で共有されるべき型を特定する
- 仕様としての集約 : これらの型を共通の場所に集約し、プロジェクトの「何を作っているか」を定義する仕様書として機能させる
- 基底型からの派生 : ページネーション等の複雑な概念は、基底型を定義し、用途に応じて派生型を生成する
このアプローチにより、単に型を移動するのではなく、 プロジェクトの設計思想をコード自体で表現する という、より高度なリファクタリングを実現しました。
達成した成果
| 改善項目 | Before | After |
|---|---|---|
| ドメイン知識の配置 | 各レイヤーに散在 | 仕様書として一箇所に集約 |
| 型定義ファイルの役割 | 単なる型の置き場 | プロジェクトの生きた仕様書 |
| ページネーション型の構造 | 各層で独立して定義 | 基底型から派生する統一構造 |
その結果、 「散在したドメイン知識」を「生きた仕様書」へ昇華する ことに成功しました。
AIが陥るドメイン知識の散在の罠
ここで重要な警告があります。
AIに「残りの型を整理して」と頼むと、高確率で以下のような提案が返ってきます:
- 「各型を使っている場所に合わせて配置しましょう」
- 「とりあえず共通フォルダに移動しましょう」
- 「使用頻度の高い場所に配置しましょう」
しかし、これらは 対症療法 です。一時的に整理されますが、「型がどのレイヤーの責務か」という視点が欠けているため、すぐに再び散在が発生します。
根本原因は、 ドメイン知識とレイヤー責務の区別が設計されていない ことにありました。AIは「今ある型の使用場所」しか見ませんが、人間は「型が表現するドメイン知識の性質」や「仕様書としての型定義ファイルの役割」という、より高次の制約を満たす必要があります。
ここから先は、AIが絶対に提案しない 「仕様書としての型定義」 というアプローチの全貌と、ドメイン知識を特定する判断基準、基底型からの派生による統一構造の構築手法、そして実際の型定義ファイル構造を、すべて公開します。
このアプローチをコピーすれば、ドメイン知識の散在ループを回避し、 初回から仕様書として機能する型定義ファイル を実現できます。私が実践で確立したドメイン知識の集約設計と、実装済みの型定義構造を、ここで全て公開します。
実装フェーズ:具体的な手順
では、実際に私が設計したドメイン知識の特定基準、レイヤーを越える型の配置ルール、基底型からの派生による型の統一構造、そして仕様書としての型定義ファイルの構成方法を公開します。
このアプローチと構造をそのままコピーすれば、「どの型がドメイン知識か」「どこに配置すべきか」「どう統一するか」を毎回悩むことなく、 再現可能な仕様書としての型定義 を実現できます。また、なぜドメイン知識の集約が重要なのか、仕様書として機能する型定義ファイルの価値、基底型からの派生による保守性の向上も解説します。
まとめ
この4回にわたるリファクタリングを経て、型定義ファイルは、もはや単なる型の置き場ではありません。このアプリケーションがどのようなデータを持ち、どのような選択肢を提供し、どのような設定で動作するのかを定義する、 生きた仕様書 となりました。
AIとの協調を通じて、場当たり的な修正ではなく、設計原則に基づいた体系的なリファクタリングを実現できました。これにより、コードの保守性や見通しが向上しただけでなく、プロジェクトの設計思想そのものがコードに刻み込まれ、チーム全体の共通認識を形成する土台が築かれたのです。
このシリーズの記事
- Part 1: 単純な重複の排除
- Part 2: 『唯一の真実の源』の確立
- Part 3: 『関心の分離』の実践
- Part 4: ドメイン知識の集約
- Part 5: 『生きた仕様書の完成』
