🦄
Cline開発に設計図を!Design Doc生成ステップを挟んでみる
Clineにざっくりとした開発要件を伝えてDesign Docをまず生成させ、
そのドキュメントを利用して開発させてみた記事です。
TL;DR
- LLMへの仕様書を詳細に書けば効率が上がるのは解っているが、仕様書にする手間を省きたい。
- Clineを使って開発する際にまずDesign Docを生成させることを試してみる。
- llm用のDesign Doc
llm_design_doc_template.md
を用意してみた。 - LLMは
gemini-2.0-pro-exp-02-05
開発プロセス
以下の手順で開発を進めます。
LLM用のDesignDoc Template
LLM用のdesign_docテンプレート
llm_design_doc_template.md
# 開発プロジェクト 設計ドキュメントテンプレート (design_doc)
## 1. Overview (概要)
- この開発プロジェクトの概要を簡潔に記述します。最大 3 段落まで。
## 2. Context (背景)
- この開発プロジェクトが必要な理由、解決しようとしている問題、技術戦略などを記述します。
## 3. Scope (範囲)
- 変更対象のファイルを書き出します。
- 追加が必要な場合はファイル名と役割を書き出します。
## 4. Goal (目標)
- 開発の目標を記述します。成功を測定するための指標を具体的に示します。
- 各目標は箇条書きで 3 行以内にまとめます。
## 5. Non-Goal (目標外)
- このプロジェクトでは扱わない範囲を明確に記述します。
- 各項目は箇条書きで 3 行以内にまとめます。
## 6. Solution / Technical Architecture (解決策 / 技術アーキテクチャ)
- 提案する解決策を記述します。具体的なユーザー ストーリーを用いて説明し、必要に応じて、複数のサブセクションや図(Mermaid 記法など)を含めます。
- 全体像を示した後、詳細を記述します。
- 以下の要素について、必要に応じて記述します。
- **System Context Diagrams (システムコンテキスト図):** システムと周辺環境の関係性を視覚的に表現します。
- **APIs:** API に関する仕様を記述します。
- **Data Model:** データモデル(データベースの構造、データの流れなど)に関する仕様を記述します。Mermaid の ER 図などを用いて視覚的に表現することを検討します。
- **Data Storage:** データストレージに関する仕様を記述します。
## 7. Alternative Solution (代替案)
- 提案した解決策以外に検討した代替案を記述します。各代替案の Pros/Cons を記述します。
## 8. Concerns (懸念事項)
- プロジェクトに関する懸念事項を記述します。
## 10. Safety and Reliability (安全性と信頼性)
- **システムの暴走や誤動作を防ぐための対策:**
- 生成されたコードやシステムの挙動にバグがないとは限らないため、事前に「ガードレール」を設置します。
- ガードレールの設置には、主に以下の 2 つのポイントがあります。
- **テストの実施:** システムの出力に対するテスト(ユニットテスト、統合テスト、E2E テストなど)を実施し、品質を保証します。
- **テストカバレッジの計測:** テストカバレッジは必ず計測して 80%以上にします。
- **静的型付け言語の採用:** (該当する場合) TypeScript などの静的型付け言語を使用し、型エラーを自動で検出し、コードの品質を向上させます。
## 11. References (参考資料)
- 参考資料をリスト化します。
planモードでDesign Docを計画
next.jsで計算機アプリを作成したいです。
どんな実装方法がありますか?
@/doc/llm_design_doc_template.md
を参考にDesignDocを書いてください。
yyyymmdd_task.mdのフォーマットでdocフォルダに格納してください。
LLMが生成したDesign Doc
生成したDesign Docはyyyymmdd_task.md
のフォーマットでdocフォルダに格納します。
LLMが生成したdesign_doc
開発プロジェクト 設計ドキュメントテンプレート (design_doc)
1. Overview (概要)
- この開発プロジェクトは、Next.js を使用して基本的な四則演算(加算、減算、乗算、除算)が可能な電卓アプリケーションを開発します。
- ユーザーは、Web ブラウザ上で直感的に操作できる、シンプルでスタイリッシュな電卓を利用できます。
- Storybook を使用して、コンポーネントのカタログを作成し、UI の開発とテストを効率化します。
2. Context (背景)
- この電卓アプリケーションは、個人の日常的な計算をサポートするために開発されます。
- Web ブラウザ上で手軽に利用できる電卓を提供することで、ユーザーの利便性向上を目指します。
- 例えば、外出先でスマートフォンを使ってちょっとした計算をしたい場合や、PC での作業中に簡単な計算をしたい場合などに利用できます。
3. Scope (範囲)
-
app/page.tsx
:-
Calculator
コンポーネントを配置します。 - アプリケーションのメインエントリーポイントとなります。
-
-
components/Calculator.tsx
:- 電卓の UI を実装します。
-
useCalculator
フックから状態とイベントハンドラを受け取り、UI に表示します。 - ユーザーの入力(ボタンクリック)に応じて、
useCalculator
フックのイベントハンドラを呼び出します。
-
hooks/useCalculator.ts
:- 電卓のロジック(状態管理、計算処理)を実装します。
- 状態管理には
useState
を使用します。-
displayValue
: 現在ディスプレイに表示されている値を保持します。 -
previousValue
: 前回の計算結果または入力値を保持します。 -
operator
: 現在選択されている演算子(+、-、*、/)を保持します。
-
- ユーザーの入力(ボタンクリック)に応じて、状態を更新し、
lib/calculate.ts
の関数を呼び出して計算を実行します。 - 状態とイベントハンドラを返します。
-
components/Button.tsx
:- 数字ボタン、演算子ボタン、クリアボタンなど、電卓の各ボタンのコンポーネントを定義します。
-
props
として、ボタンに表示する値(数字または演算子)、ボタンの種類(数字、演算子、クリアなど)、クリック時のイベントハンドラを受け取ります。
-
lib/calculate.ts
:- 四則演算を実行する関数を定義します。
-
add(a: number, b: number): number
: 加算 -
subtract(a: number, b: number): number
: 減算 -
multiply(a: number, b: number): number
: 乗算 -
divide(a: number, b: number): number
: 除算
-
- 各関数は、2 つの数値(
number
型)を引数として受け取り、計算結果(number
型)を返します。 - 0 での除算の場合は、エラーをスローします。
- 四則演算を実行する関数を定義します。
-
.storybook/main.ts
:- Storybook の設定ファイル。
- addons として、
@storybook/addon-essentials
を使用します。
-
components/Button.stories.tsx
:- Button コンポーネントの Storybook のストーリー。
- 数字ボタン、演算子ボタン、クリアボタンなど、 ವಿವಿಧ な種類のボタンのストーリーを記述します。
- 各ボタンの props(value, kind, onClick)を変化させた場合の表示と動作を確認できるストーリーを記述します。
4. Goal (目標)
- ユーザーが基本的な四則演算を正確に行える電卓アプリケーションを開発する。
- ユーザーが直感的に操作できる、シンプルで使いやすい UI を実現する。
- 開発期限は特に設けないが、可能な限り迅速に開発を進める。
- Jest によるユニットテストと Storybook によるビジュアルテストを実施し、品質を確保する。
- テストカバレッジを 80% 以上にする。
5. Non-Goal (目標外)
- 今回のプロジェクトでは、基本的な四則演算以外の機能(関数電卓、メモリ機能など)は実装しません。
6. Solution / Technical Architecture (解決策 / 技術アーキテクチャ)
-
UI:
- Next.js (React) を使用して、コンポーネントベースの UI を構築します。
-
components/Calculator.tsx
で、電卓全体のレイアウト(数字ボタン、演算子ボタン、ディスプレイなど)を定義します。- 全体のコンテナ:
flex flex-col items-center justify-center h-screen bg-gray-100
- ディスプレイ:
w-80 h-20 bg-white border border-gray-300 rounded-md mb-4 text-right text-2xl px-4 py-2
- ボタンコンテナ:
grid grid-cols-4 gap-2 w-80
- 全体のコンテナ:
-
components/Button.tsx
で、個々のボタンのコンポーネントを作成します。- 数字ボタン:
bg-white hover:bg-gray-100 text-gray-800 font-semibold py-2 px-4 border border-gray-400 rounded shadow
- 演算子ボタン:
bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded
- クリアボタン:
bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded
- 数字ボタン:
- スタイリングには、Tailwind CSS を使用します。
-
Storybook:
- Storybook を使用して、
components
ディレクトリ以下のコンポーネントのカタログを作成します。 -
Button
コンポーネントについては、value
、kind
、onClick
などの props を変化させた場合の表示と動作を確認できるようにします。 -
Calculator
コンポーネントについては、初期状態、数字入力後、演算子入力後、計算結果表示後など、様々な状態を Storybook 上で確認できるようにします。
- Storybook を使用して、
-
ロジック:
-
lib/calculate.ts
は、純粋な四則演算関数のみを提供します。状態管理は行いません。-
各関数は、以下のインターフェースを持ちます。
function add(a: number, b: number): number; function subtract(a: number, b: number): number; function multiply(a: number, b: number): number; function divide(a: number, b: number): number;
-
0 での除算の場合は、
Error
オブジェクトをスローします。 -
以下のオブジェクトで、演算子と関数のマッピングを定義します。
export const operators = { "+": add, "-": subtract, "*": multiply, "/": divide, };
-
-
-
データフロー:
7. Alternative Solution (代替案)
-
UI フレームワーク:
- React 以外の UI フレームワーク(Vue.js、Angular など)を使用することも検討しましたが、Next.js のファイルベースルーティングやサーバーサイドレンダリングの機能を活用できるため、Next.js を採用しました。
-
状態管理:
- 電卓の状態管理には、React の useState フックを使用します。より複雑な状態管理が必要な場合は、Redux や Zustand などの状態管理ライブラリの導入も検討できますが、今回の電卓アプリでは useState で十分と判断しました。Redux は大規模アプリケーションで状態管理を一元化するのに適しており、Zustand はより軽量でシンプルな状態管理に適しています。
8. Concerns (懸念事項)
-
入力エラー処理:
- ユーザーが不正な入力(0 での除算、無効な数式など)を行った場合の、エラー処理を適切に実装する必要があります。
-
複雑な数式への対応:
- 将来的には、括弧を含む複雑な数式にも対応できるように拡張することを検討します。
-
パフォーマンス:
- 大量の計算を行う場合でも、パフォーマンスが低下しないように注意する必要があります。
-
アクセシビリティ:
- キーボード操作のみでも電卓を利用できるようにするなど、アクセシビリティにも配慮する必要があります。
10. Safety and Reliability (安全性と信頼性)
-
システムの暴走や誤動作を防ぐための対策:
- 生成されたコードやシステムの挙動にバグがないとは限らないため、事前に「ガードレール」を設置します。
- ガードレールの設置には、主に以下の 2 つのポイントがあります。
-
テストの実施:
-
lib/calculate.ts
に対して、ユニットテスト(Jest など)を実装し、四則演算が正しく行われることを確認します。- 正常系のテストケース:
- 1 + 2 = 3
- 10 - 5 = 5
- 3 * 4 = 12
- 10 / 2 = 5
- 異常系のテストケース:
- 1 / 0 = Error (エラーメッセージの確認)
- 正常系のテストケース:
-
components/Calculator.tsx
に対して、結合テスト(Testing Library など)を実装し、UI とロジックが連携して正しく動作することを確認します。- ユーザーが "1", "+", "2", "=" と順にボタンをクリックしたときに、ディスプレイに "3" と表示されること。
- ユーザーが "C" ボタンをクリックしたときに、ディスプレイが "0" にリセットされること。
- ユーザーが数字ボタンを連続してクリックしたときに、ディスプレイに正しく数字が表示されること (例: "1", "2" で "12")。
- ユーザーが演算子ボタンをクリックした後に数字ボタンをクリックしたときに、ディスプレイがリセットされて新しい数字が表示されること。
- Storybook を使用したビジュアルリグレッションテスト(Chromatic)を実施し、コンポーネントの見た目が意図せず変更されていないことを確認します。
-
- テストカバレッジの計測: テストカバレッジは必ず計測して 80%以上にします。
- 静的型付け言語の採用: (該当する場合) TypeScript などの静的型付け言語を使用し、型エラーを自動で検出し、コードの品質を向上させます。
-
テストの実施:
11. References (参考資料)
- Next.js 公式ドキュメント: https://nextjs.org/docs
- React 公式ドキュメント: https://react.dev/
Actモードで実装
@/doc/20250302_next_calculator_app.md
の内容に従って実装してください。
何度かDesign Docの調整と実装を繰り返しましたがアプリは完成しました。
感想
- DesignDocの生成を挟む事でclieとのやりとりは以前より減ったと思います。LLMは思ったよりしっかりとDesignDocを書いてくれました。
- LLM用のDesignDocは実装方法だけを書けばよくビジネス面は当然考慮できません。(今のところ?contextとして渡す方法もあるのかも)
- DesignDocはLLMのコード生成でもかなり有効だと解りました。
Discussion
design_docをLLMにレビューさせるPrompt