勉強会_ジェネレーター実装解説

-- Views

June 01, 26

スライド概要

https://zenn.dev/yukiko_sapporo/articles/59e67faa3a509c

profile-image

何卒よろしくお願い申し上げます。 一流のIT研修講師を目指し、日々研鑽を続けております。 本資料は外部公開用としてご提供するものです。

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

ダウンロード

関連スライド

各ページのテキスト
1.

エンジニア勉強会 ジェネレーターツールの実装解説 新人向け(1行ずつ)+ 中堅向け(設計・UML) 題材:最小版ジェネレーター mini-gen(入力 → 生成 → 出力 + セルフテスト) WHY → WHAT → HOW / 人ではなく仕組み

2.

全体像 ツールは「4つの役割」でできている ① ② ③ ④ 入力 INPUT 生成 GENERATE 出力 OUTPUT セルフテスト ユーザーが値を入れる(<input>) 入力から文字列を組み立てる 作った文字列を画面に出す 起動時に壊れていないか確認 うさうさラーメン店のたとえ:①注文を聞く → ②作る → ③ 出す → ④ 味見。当たり前の流れをコードに分けただけ。

3.

第1部 新人向け:1行ずつ読む 役割で小さく分ける/外の入力は疑う/作ると出すを分ける/起動時に味見

4.

新人向け|① 入力を読む val():入力欄の値を安全に読む function val(id){ var el = document.getElementById(id); // idで部品を取り出す return el ? el.value : ""; // 無ければ空文字(落ちない) } getElementById:idで部品を1つ探す 三項演算子 el ? A : B は「あればA、無ければB」 見つからなくてもエラーで止まらない。これが「落ちないコード」の第一歩。

5.
[beta]
新人向け|② 入力を疑う

esc():危険な文字を無害化(XSS対策)
function esc(s){
return String(s).replace(/[<>&]/g, function(c){
return {"<":"&lt;", ">":"&gt;", "&":"&amp;"}[c];
});
}

< > & を表示用の安全な表記に置き換える

合言葉:外から来た文字は、まず疑う。

例)<script> をそのまま画面に出すと危険 → &lt;script&gt; にして無害化

6.
[beta]
新人向け|③ 生成(心臓)

generate():入力から文章を組み立てる
function generate(inp){
var course = inp.course || "(コース名なし)"; // 未入力でも落ちない
var who = inp.audience ? inp.audience+"向け" : "受講者向け";
var md = "";
md += "# " + esc(course) + " 設計メモ\n\n"; // 見出し
md += "- 対象:" + esc(who) + "\n";
// 箇条書き
return md;
// 作るだけ。画面には触らない
}

大事:この関数は「作る」だけ。「出す」のは別の係(render)。役割を分けるとテストしやすい。

7.

新人向け|④ 出力と流れ render() と doGenerate():出して、つなぐ function render(md){ document.getElementById("out").textContent = md; // 安全に表示 } function doGenerate(){ var inp = collectInput(); // ①集める if(!inp.course){ alert("..."); return; } // ②検証(早期リターン) render(generate(inp)); // ③生成 → ④表示 } 流れが「集める→検証 →生成 →表示」と一直線。読めば分かるのが良いコード。

8.
[beta]
新人向け|セルフテスト

起動時に「味見」を自動化する
T("生成に見出しが入る", function(){
return generate({course:"テスト"}).indexOf("# テスト") >= 0;
});

✓ PASS
generate() を実際に呼び、結果に見出し
が含まれるか確認。含まれれば合格。

人が毎回手で確認しなくて済む = 「人ではなく仕組み」。壊れたら起動時に赤く分かる。

9.

第2部 中堅向け:設計の意図とUML 副作用を1か所に閉じ込める/純粋ロジックでテスト容易に/追加は「分岐+テスト」をセットで

10.

中堅向け|関心の分離(SoC) 単方向の流れ:副作用は1か所に DOM入力 collectInput generate generate() は純粋関数に近い → 同じ入力なら同じ出力/DOMに副作用なし → テストが容易 render() だけが DOM に触れる → 副作用の出口を1か所に閉じ込めるのが保守性の肝 実物:generate() → generateMarkdown() の switch ルーター(16成果物へ振り分け) render DOM出力

11.

中堅向け|クラス図(UML相当) 責務の地図:UI / Controller / Service / View / Test <<UI>> InputForm <<Model>> InputData reads #course / #audience #genBtn course: string audience: string click <<Controller>> doGenerate collectInput() 検証(早期return) <<Service>> Generator generate(inp): md esc(s): string <<Test>> SelfTest runSelfTests() T(name, fn) MVC+Service+Test。役割が一方向に流れ、依存が循環しない。 <<View>> render DOMに出力 textContentで安全表示

12.

中堅向け|シーケンス(UML相当) 実行時の流れ:click から表示まで User → InputForm : click InputForm → doGenerate() doGenerate → collectInput() : 入力を集める collectInput → doGenerate : inp doGenerate : course空? ⇒ alert して return(早期リターン) doGenerate → generate(inp) : 文章を組み立て generate → doGenerate : md(Markdown) doGenerate → render(md) : 出力 render → DOM(out) : textContent をセット(表示) 生成(純粋)と表示(副作用)が分かれているので、各ステップを単体で検証できる。

13.

中堅向け|テスト容易性 なぜこの分け方? → テストが書けるから 内蔵セルフテスト 起動時に自動実行。生成・反映・エスケープを関数で確認 商用テスト(jsdom) ブラウザ相当で検証:出力・CSV・XSS・DL・ページエラー0 出荷条件 5回連続オール緑(再現性のある安定) mini-gen の runSelfTests() は、その最小サンプル。観点を関数で持つ形は実物と同じ。

14.

中堅向け|拡張の型 新機能を足す手順(破綻させない) 1 generate() に分岐を足す(実物:genXxx()+switchに1行) 2 入力UIを足す(collectInput に1項目) 3 セルフテストを1〜2個追加(生成される・反映される) 4 商用テストに観点追加 → 5回連続緑を確認 「分岐+テストをセットで足す」習慣が、16成果物まで破綻なく育てられた理由。

15.

まとめ 新人 • • • • 役割で小さく分ける 外の入力は疑う(esc) 作ると出すを分ける 起動時に味見(テスト) 中堅 • • • • 副作用を1か所に閉じ込める 純粋ロジックでテスト容易に 追加は「分岐+テスト」をセットで 5回連続緑を出荷条件に 小さく理解して、実物で確認。mini-gen が読めれば実物(16成果物)は同じ型の拡大版。 面白きこともなき世を面白く