GoFデザインパターン(生成 / 構造 / 振る舞い)85章 詳細アウトライン(C# / Windows / Visual Studio 前提)
対象:C#は初級〜中級、設計は超入門、GoFは初めての人向け 方針:.NET標準クラス または 現場のデファクト(定番NuGet) を中心に学ぶ 禁止:パターンのためだけに“オレオレ汎用フレームワーク”を作らない(学習用の小さな業務モデルはOK)
- 生成日:2026-02-04(JST想定)
この詳細アウトラインの使い方(ブレを防ぐためのルール)
- 各章は「ねらい→到達目標→手順→落とし穴→演習→チェック」の順で固定します。
- 章の実装は“最小”でOK。テストが通る小さな成功を積み上げます。
- 迷ったら「呼び出し側のif/switchを減らす」「差し替えやすくする」「契約(例外/戻り値/Dispose)を明確にする」に戻ります。
前提環境(2026年 “最新版” 想定)
- Windows 11相当
- Visual Studio(最新版) + .NET SDK(最新版 / LTS優先)
- Git(GitHub)
- 任意:GitHub Copilot / OpenAI系AI拡張
- テスト:MSTest(標準)を基本。必要に応じてxUnit(デファクト)も紹介。
例題ドメイン(共通の小さなEC)
Order(注文) /Money(金額) /PaymentMethod(支払い手段) /Notification(通知)- “作り込み過ぎない”が最重要:以降の章で少しずつ改善するための土台です。
Part 0:学び方・準備(1〜12)🧰🌱
ゴール:学習の型(環境・テスト・AI補助・共通ドメイン)を固め、以降の章で迷子にならないようにする。
第1章. GoFってなに?暗記じゃなく“使い分け”📚🙂
ねらい
- GoFが“暗記リスト”ではなく、問題解決の語彙であることを理解する。
- 23パターンを学ぶ意義(設計の会話速度、変更耐性)を掴む。
前提
- C#のクラス/メソッドを一人で書ける。
到達目標
- “パターン名→困りごと→メリット/デメリット”の順で説明できる。
- 教材の学び方(演習→振り返り→適用判断メモ)を自分の言葉で言える。
扱うAPI / 言語機能(標準・デファクト中心)
- (なし)
進め方(アウトライン)
- GoFを“困りごと分類表”として眺める。
- 自分の過去コードの“つらい点”を3つ書き出す。
- その3つが、どの分類(生成/構造/振る舞い)に近いか当てはめる。
よくある落とし穴
- パターン名の丸暗記に戻る。
- 難しい例を追って挫折する。
ミニ演習(10〜30分)
- 自分の過去プロジェクト(小でもOK)で“変更が怖かった箇所”を1つ具体的に書く。
自己チェック
- “GoFは何のため?”を30秒で説明できる。
第2章. まず最初に:設計で一番損するパターンの覚え方🧠💦
ねらい
- “名前→実装”ではなく“困りごと→解決”で覚える学び方を固める。
- 学習中に起きるブレ(オレオレ抽象化、パターン収集癖)を避ける。
前提
- 第1章を読了。
到達目標
- 困りごとから逆引きできる(例:new地獄→Factory/Builderなど)。
- “採用しない判断”もできる。
扱うAPI / 言語機能(標準・デファクト中心)
- (なし)
進め方(アウトライン)
- 困りごとテンプレを作る:症状/原因/変わる点/変えたくない点。
- 各章でテンプレを埋める習慣を作る。
- 最後に“採用判断メモ”を1行で残す。
よくある落とし穴
- パターン数が増えるほど混乱する。
- “正解の実装”探しに時間を溶かす。
ミニ演習(10〜30分)
- 困りごとテンプレをNotion/Markdownに作る。
自己チェック
- 各章でテンプレが埋められている。
第3章. この教材の“縛り”を確認(標準/デファクト中心)🪢✅
ねらい
- 教材の縛り(標準/デファクト中心、汎用フレームワーク禁止)を具体例で理解する。
前提
- (なし)
到達目標
- “標準で体験できるパターン”を挙げられる。
- “作りすぎ”の兆候を言語化できる。
扱うAPI / 言語機能(標準・デファクト中心)
- IEnumerable/yield
- Stream デコレータ
- Microsoft.Extensions.*(DI/Logging)
進め方(アウトライン)
- 標準/デファクトの例を先に知る→自作は最後の手段、の順番を徹底する。
- 演習は“業務モデルの最小”だけ作る。
よくある落とし穴
- パターンのための抽象クラス群を作りがち。
ミニ演習(10〜30分)
- 自作禁止リストを自分用に追記(例:汎用Builder基盤、汎用Mediatorなど)。
自己チェック
- “なぜ標準寄せ?”を説明できる。
第4章. Visual Studioで学習用ソリューションを作る📁✨
ねらい
- 学習用ソリューション構成を固定し、章ごとのブレを減らす。
- 演習を“捨てやすい”形で作り、気軽に作り直せるようにする。
前提
- Visual Studioが使える。
到達目標
- ソリューション/プロジェクトの命名規約が決まる。
- テスト・共通ドメイン・共通ユーティリティの置き場所が決まる。
扱うAPI / 言語機能(標準・デファクト中心)
- dotnet new
- MSTest/xUnit
- Directory.Build.props(任意)
進め方(アウトライン)
- Solution: GofPatternsLearning.sln を作成。
- Projects: 章ごとに Console + Test のペア(例:Ch14.FactoryMethod)を追加。
- 共通ドメインは /src/Domain.Shared に最小で置く(増やしすぎない)。
- Gitで章単位コミット。
よくある落とし穴
- 共通化しすぎて依存が絡む。
ミニ演習(10〜30分)
- テンプレプロジェクト(Console+Test)を1つ作り、複製運用できるようにする。
自己チェック
- 新章を5分で追加できる。
第5章. テストの最小セット:AAAだけ覚える🧪🌸
ねらい
- テストを“設計の安全網”として使う最小セット(AAA)を身につける。
前提
- (なし)
到達目標
- Arrange/Act/Assertで読みやすいテストが書ける。
- 例外・境界値のテストが追加できる。
扱うAPI / 言語機能(標準・デファクト中心)
- MSTest
- xUnit(任意)
- FluentAssertions(任意:定番)
進め方(アウトライン)
- 1テスト=1主張を基本にする。
- 命名規約(Method_State_Expectedなど)を決める。
- 章の演習では“先に失敗するテスト”を1本書く。
よくある落とし穴
- テストが実装詳細に寄りすぎて壊れやすい。
ミニ演習(10〜30分)
- 第12章の分岐地獄サンプルに対し、失敗するテストを先に書く。
自己チェック
- テストを読むだけで仕様がわかる。
第6章. AI補助(Copilot/Codex)の正しい使い方🤖✍️
ねらい
- AI補助を“設計を良くする道具”として使い、依存しない。
前提
- Copilot等が使える(なくてもOK)。
到達目標
- 依頼テンプレでブレなく指示できる。
- 出力をレビューして直せる。
扱うAPI / 言語機能(標準・デファクト中心)
- (なし)
進め方(アウトライン)
- 依頼テンプレ:目的/制約/入出力/禁止事項/テストの期待を明記。
- AIは雛形まで、人間は責務と命名とテスト。
- 差分を小さく、コミットを小さく。
よくある落とし穴
- AIが作る“過剰抽象”を見抜けない。
ミニ演習(10〜30分)
- テンプレをMarkdownにして貼り付け運用する。
自己チェック
- AI出力の“採用しない理由”も言える。
第7章. C#の言語機能で“パターンが軽くなる”話✨🧡
ねらい
- C#機能でGoF実装が軽くなるポイントを整理し、過剰設計を避ける。
前提
- C#の基本文法。
到達目標
- record/with、デリゲート、switch式などを適材適所で使える。
扱うAPI / 言語機能(標準・デファクト中心)
- record
- with
- Func<>/Action<>
- switch 式/パターンマッチ
進め方(アウトライン)
- 各機能が置き換えるGoF要素を対応付ける(例:Strategy=Func)。
- ただし読みやすさ優先で“軽くしすぎない”。
よくある落とし穴
- 短くしすぎて意図が消える。
ミニ演習(10〜30分)
- Strategyをinterface版とFunc版で書き比べ、可読性で選ぶ。
自己チェック
- 言語機能を使う理由が説明できる。
第8章. “依存の向き”の超入門(外側と内側)🧭🏠
ねらい
- “外側(UI/DB/HTTP)”と“内側(業務ルール)”の分離を超入門で掴む。
前提
- (なし)
到達目標
- GoFが“内側を守る”ために役立つイメージが持てる。
扱うAPI / 言語機能(標準・デファクト中心)
- (なし)
進め方(アウトライン)
- 例題を“内側(Orderなど)”と“外側(通知、支払い)”に分けて紙に描く。
- 外側は差し替えやすく、内側は安定させる。
よくある落とし穴
- 全部をDI/抽象化し始める。
ミニ演習(10〜30分)
- 例題の境界(I/O)を3つ書く。
自己チェック
- “どこが外側?”を即答できる。
第9章. 例題ドメインの準備(小さくてOK)🛒🍰
ねらい
- 学習用ドメイン(小さなEC)を“最小”で用意し、以降の章で再利用する。
前提
- (なし)
到達目標
- Order, Money, PaymentMethod, Notificationの最小モデルがある。
扱うAPI / 言語機能(標準・デファクト中心)
- System.Text.Json(DTO用)
進め方(アウトライン)
- 型は自然なドメイン語で作る(OrderId, Money等)。
- 不変条件(例:金額>=0)を1つだけ入れる。
- 余計な抽象基盤は作らない。
よくある落とし穴
- 作り込み過ぎて学習が進まない。
ミニ演習(10〜30分)
- Orderに最小の状態(New/Paid/Cancelledなど)をenumで持たせる。
自己チェック
- 1ファイルで読める程度の小ささ。
第10章. ログは標準の仕組みを使う(デファクト)📝✨
ねらい
- ログを標準の形で統一し、Decorator/Proxyの演習に繋げる。
前提
- DIの最低限(任意)。
到達目標
- ILoggerを使い、ログレベルとメッセージ設計ができる。
扱うAPI / 言語機能(標準・デファクト中心)
- Microsoft.Extensions.Logging
進め方(アウトライン)
- ConsoleアプリにLoggerFactoryを導入。
- ログ出力箇所を“入口/出口/エラー”に絞る。
- 後でDecoratorでログ付与できるよう、I/Fを用意。
よくある落とし穴
- ログが多すぎて読めない。
ミニ演習(10〜30分)
- OrderServiceの入口と出口にログを入れる。
自己チェック
- ログだけで処理の流れが追える。
第11章. DIは標準の仕組みを使う(デファクト)🧩🔌
ねらい
- DI(標準)で差し替えを体験し、GoFの理解を邪魔しない範囲で使う。
前提
- (なし)
到達目標
- ServiceCollectionで登録/解決できる。
- テストで差し替え(モック/フェイク)ができる。
扱うAPI / 言語機能(標準・デファクト中心)
- Microsoft.Extensions.DependencyInjection
進め方(アウトライン)
- 最初はConsoleで手動new→次にDI登録、の順で小さく導入。
- ライフサイクル(Singleton/Scoped/Transient)を最小で理解。
よくある落とし穴
- DIコンテナに全部を押し込みすぎる。
ミニ演習(10〜30分)
- PaymentMethodFactoryをDIで差し替えるテストを書く。
自己チェック
- 差し替え点が登録箇所に集約されている。
第12章. ミニ演習:分岐地獄を1回だけ味わう🔥😵
ねらい
- “分岐地獄”をあえて作り、以降の章で改善する達成感の種にする。
前提
- 第5章(テスト)推奨。
到達目標
- 改善対象のベースラインができる(テスト付き)。
扱うAPI / 言語機能(標準・デファクト中心)
- switch式
- enum
- テスト
進め方(アウトライン)
- 注文状態×支払い方法×通知でif/switchが増える例を作る。
- 仕様をテストで固定し、後で壊さず改善する。
よくある落とし穴
- 分岐の例が現実離れしすぎる。
ミニ演習(10〜30分)
- 分岐が増える“要因”を3つメモ(状態/方針/通知)。
自己チェック
- テストがあり、リファクタの土台になっている。
Part 1:生成パターン(13〜32)🏭🧱✨
ゴール:
newや初期化の複雑さ、生成分岐、テスト差し替えを整理し、生成を“読みやすく・差し替えやすく”する。
第13章. 生成の基本:newが辛くなる3つの理由😅
ねらい
- “newが辛い”が発生する理由を分類し、生成パターンの使い分けの軸を作る。
前提
- Part 0の準備。
到達目標
- new地獄の症状を3種類(分岐/初期化/テスト差し替え)に言い分けできる。
扱うAPI / 言語機能(標準・デファクト中心)
- (なし)
進め方(アウトライン)
- 例題の生成箇所を洗い出す。
- 変わる点を分類する。
- どのパターンが効きそうか仮説を立てる。
よくある落とし穴
- 最初からFactoryを量産する。
ミニ演習(10〜30分)
- 例題でnewが並んでいる行を3箇所ハイライトする。
自己チェック
- どの問題にどのパターンが効くか“言える”。
第14章. Factory Method ①:考え方(生成を押し出す)🏭
ねらい
- Factory Methodが解く困りごと(生成する具体型を呼び出し側から隠し、条件分岐や依存を減らしたい。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Factory Methodの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- System.Security.Cryptography.*.Create()
- StreamWriter (TextWriter)
- HttpClientFactory(必要なら)
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- Factoryが増えすぎて探索コストが上がる
- 戻り型が具体型に寄ると効果が薄い
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをFactory Methodで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第15章. Factory Method ②:.NET定番例を読む🔐
ねらい
- .NETの“現実のFactory Methodっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- System.Security.Cryptography.*.Create()
- StreamWriter (TextWriter)
- HttpClientFactory(必要なら)
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第16章. Factory Method ③:演習(支払い手段の生成)💳
ねらい
- Factory Methodを“最小実装”で手を動かして体に入れる。
- テストで“差し替え可能性”を守る練習をする。
前提
- MSTest(またはxUnit)の基本。
- DIの最小(サービス登録/解決)の感覚(任意)。
到達目標
- 演習が“動く・テストが通る・責務が薄い”の3点を満たす。
- パターン導入前後で、呼び出し側の分岐/依存が減ったことを説明できる。
扱うAPI / 言語機能(標準・デファクト中心)
- System.Security.Cryptography.*.Create()
- StreamWriter (TextWriter)
- HttpClientFactory(必要なら)
進め方(アウトライン)
- まず“導入前”の素朴実装を作り、テストで現状を固定する(失敗を再現できる形)。
- Factory Methodの役割に合わせてクラス/関数を追加し、呼び出し側のif/switchを移動する。
- テストを追加し、差し替えたいパターン(スタブ/フェイク)で挙動を検証する。
- 最後に命名と責務の整理(1クラス1責務、薄い変換/薄い委譲)を行う。
よくある落とし穴
- Factoryが増えすぎて探索コストが上がる
- 戻り型が具体型に寄ると効果が薄い
- 演習のために汎用化しすぎて難しくする。
ミニ演習(10〜30分)
- “追加したクラスは何を守るために存在するか”を1行コメントで書く(後で消してOK)。
- 導入前後の差分をGitコミットで分ける。
自己チェック
- テストで差し替えたい点を1箇所で差し替えできるか?
- 新規クラスのpublic APIが最小か?
第17章. Factory Method ④:AIで雛形→人間が設計レビュー🤖👀
ねらい
- Factory Methodを“やりすぎない”ための判断軸を作る。
- AI補助を使う場合のプロンプト設計・レビュー観点を用意する(章タイトルに合う範囲)。
前提
- ここまでの章の演習が1つ以上動く状態。
到達目標
- “この状況なら導入しない/戻す”が言える。
- レビュー観点(責務/命名/テスト/拡張点)をチェックリスト化できる。
扱うAPI / 言語機能(標準・デファクト中心)
- System.Security.Cryptography.*.Create()
- StreamWriter (TextWriter)
- HttpClientFactory(必要なら)
進め方(アウトライン)
- 導入コスト(クラス数・理解コスト)と、得られる利益(差し替え/テスト/変更容易性)を天秤にかける。
- パターンが必要になる“兆候”を3つ言語化する(例:分岐が増える、初期化が複雑、組合せが爆発)。
- AIで雛形を作るなら、禁止事項(過剰抽象化、汎用フレームワーク化)をプロンプトに明記する。
- レビューで“最小の抽象”になっているかを確認し、不要なら戻す。
よくある落とし穴
- AI出力をそのまま採用して“謎抽象”が増える。
- “便利そう”で導入し、変更が減らない。
ミニ演習(10〜30分)
- 自分の演習コードで、追加した抽象が本当に必要か“削除してみる”実験をする。
- 必要性が残る場合だけ復活させ、その理由を1行で書く(ADRメモでも可)。
自己チェック
- 導入前より、読むべきファイルが増えすぎていないか?
- 抽象(interface/基底)が“利用者にとって”自然な言葉になっているか?
第18章. Abstract Factory ①:ファミリーをセットで差し替える🏭🏭
ねらい
- Abstract Factoryが解く困りごと(関連部品“セット”を整合性を保ったまま丸ごと差し替えたい。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Abstract Factoryの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- DbProviderFactory
- ILoggerFactory(考え方の例)
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- 粒度を誤るとFactoryが巨大化
- 必要以上に抽象化して可読性が落ちる
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをAbstract Factoryで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第19章. Abstract Factory ②:.NETの定番(DbProviderFactory)🗄️
ねらい
- .NETの“現実のAbstract Factoryっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- DbProviderFactory
- ILoggerFactory(考え方の例)
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第20章. Abstract Factory ③:演習(通知セットを差し替え)🔔
ねらい
- Abstract Factoryを“最小実装”で手を動かして体に入れる。
- テストで“差し替え可能性”を守る練習をする。
前提
- MSTest(またはxUnit)の基本。
- DIの最小(サービス登録/解決)の感覚(任意)。
到達目標
- 演習が“動く・テストが通る・責務が薄い”の3点を満たす。
- パターン導入前後で、呼び出し側の分岐/依存が減ったことを説明できる。
扱うAPI / 言語機能(標準・デファクト中心)
- DbProviderFactory
- ILoggerFactory(考え方の例)
進め方(アウトライン)
- まず“導入前”の素朴実装を作り、テストで現状を固定する(失敗を再現できる形)。
- Abstract Factoryの役割に合わせてクラス/関数を追加し、呼び出し側のif/switchを移動する。
- テストを追加し、差し替えたいパターン(スタブ/フェイク)で挙動を検証する。
- 最後に命名と責務の整理(1クラス1責務、薄い変換/薄い委譲)を行う。
よくある落とし穴
- 粒度を誤るとFactoryが巨大化
- 必要以上に抽象化して可読性が落ちる
- 演習のために汎用化しすぎて難しくする。
ミニ演習(10〜30分)
- “追加したクラスは何を守るために存在するか”を1行コメントで書く(後で消してOK)。
- 導入前後の差分をGitコミットで分ける。
自己チェック
- テストで差し替えたい点を1箇所で差し替えできるか?
- 新規クラスのpublic APIが最小か?
第21章. Abstract Factory ④:やりすぎ注意(Factory増殖)🐣💦
ねらい
- Abstract Factoryを“やりすぎない”ための判断軸を作る。
- AI補助を使う場合のプロンプト設計・レビュー観点を用意する(章タイトルに合う範囲)。
前提
- ここまでの章の演習が1つ以上動く状態。
到達目標
- “この状況なら導入しない/戻す”が言える。
- レビュー観点(責務/命名/テスト/拡張点)をチェックリスト化できる。
扱うAPI / 言語機能(標準・デファクト中心)
- DbProviderFactory
- ILoggerFactory(考え方の例)
進め方(アウトライン)
- 導入コスト(クラス数・理解コスト)と、得られる利益(差し替え/テスト/変更容易性)を天秤にかける。
- パターンが必要になる“兆候”を3つ言語化する(例:分岐が増える、初期化が複雑、組合せが爆発)。
- AIで雛形を作るなら、禁止事項(過剰抽象化、汎用フレームワーク化)をプロンプトに明記する。
- レビューで“最小の抽象”になっているかを確認し、不要なら戻す。
よくある落とし穴
- AI出力をそのまま採用して“謎抽象”が増える。
- “便利そう”で導入し、変更が減らない。
ミニ演習(10〜30分)
- 自分の演習コードで、追加した抽象が本当に必要か“削除してみる”実験をする。
- 必要性が残る場合だけ復活させ、その理由を1行で書く(ADRメモでも可)。
自己チェック
- 導入前より、読むべきファイルが増えすぎていないか?
- 抽象(interface/基底)が“利用者にとって”自然な言葉になっているか?
第22章. Builder ①:引数が多い問題を解く🧱🙂
ねらい
- Builderが解く困りごと(引数が多い/段階的に構築したい/検証タイミングを制御したい。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Builderの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- StringBuilder
- UriBuilder
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- Fluent連鎖が読みにくくなる
- 途中状態を外へ漏らすと不正状態が増える
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをBuilderで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第23章. Builder ②:標準クラスで体感(StringBuilder / UriBuilder)🧵
ねらい
- .NETの“現実のBuilderっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- StringBuilder
- UriBuilder
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第24章. Builder ③:演習(Orderを段階的に組み立て)🛒
ねらい
- Builderを“最小実装”で手を動かして体に入れる。
- テストで“差し替え可能性”を守る練習をする。
前提
- MSTest(またはxUnit)の基本。
- DIの最小(サービス登録/解決)の感覚(任意)。
到達目標
- 演習が“動く・テストが通る・責務が薄い”の3点を満たす。
- パターン導入前後で、呼び出し側の分岐/依存が減ったことを説明できる。
扱うAPI / 言語機能(標準・デファクト中心)
- StringBuilder
- UriBuilder
進め方(アウトライン)
- まず“導入前”の素朴実装を作り、テストで現状を固定する(失敗を再現できる形)。
- Builderの役割に合わせてクラス/関数を追加し、呼び出し側のif/switchを移動する。
- テストを追加し、差し替えたいパターン(スタブ/フェイク)で挙動を検証する。
- 最後に命名と責務の整理(1クラス1責務、薄い変換/薄い委譲)を行う。
よくある落とし穴
- Fluent連鎖が読みにくくなる
- 途中状態を外へ漏らすと不正状態が増える
- 演習のために汎用化しすぎて難しくする。
ミニ演習(10〜30分)
- “追加したクラスは何を守るために存在するか”を1行コメントで書く(後で消してOK)。
- 導入前後の差分をGitコミットで分ける。
自己チェック
- テストで差し替えたい点を1箇所で差し替えできるか?
- 新規クラスのpublic APIが最小か?
第25章. Builder ④:Fluent APIの落とし穴(読めない連鎖)😵
ねらい
- Builderを“やりすぎない”ための判断軸を作る。
- AI補助を使う場合のプロンプト設計・レビュー観点を用意する(章タイトルに合う範囲)。
前提
- ここまでの章の演習が1つ以上動く状態。
到達目標
- “この状況なら導入しない/戻す”が言える。
- レビュー観点(責務/命名/テスト/拡張点)をチェックリスト化できる。
扱うAPI / 言語機能(標準・デファクト中心)
- StringBuilder
- UriBuilder
進め方(アウトライン)
- 導入コスト(クラス数・理解コスト)と、得られる利益(差し替え/テスト/変更容易性)を天秤にかける。
- パターンが必要になる“兆候”を3つ言語化する(例:分岐が増える、初期化が複雑、組合せが爆発)。
- AIで雛形を作るなら、禁止事項(過剰抽象化、汎用フレームワーク化)をプロンプトに明記する。
- レビューで“最小の抽象”になっているかを確認し、不要なら戻す。
よくある落とし穴
- AI出力をそのまま採用して“謎抽象”が増える。
- “便利そう”で導入し、変更が減らない。
ミニ演習(10〜30分)
- 自分の演習コードで、追加した抽象が本当に必要か“削除してみる”実験をする。
- 必要性が残る場合だけ復活させ、その理由を1行で書く(ADRメモでも可)。
自己チェック
- 導入前より、読むべきファイルが増えすぎていないか?
- 抽象(interface/基底)が“利用者にとって”自然な言葉になっているか?
第26章. Prototype ①:コピーで量産する🧬✨
ねらい
- Prototypeが解く困りごと(初期状態が複雑なオブジェクトをテンプレから複製して量産したい。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Prototypeの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- record + with
- MemberwiseClone(注意事項として)
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- 浅いコピーで参照共有が起きる
- コピー範囲が無制限になる
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをPrototypeで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第27章. Prototype ②:C#らしく(record + with)🧾
ねらい
- .NETの“現実のPrototypeっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- record + with
- MemberwiseClone(注意事項として)
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第28章. Prototype ③:演習(注文テンプレを複製)🛒🔁
ねらい
- Prototypeを“最小実装”で手を動かして体に入れる。
- テストで“差し替え可能性”を守る練習をする。
前提
- MSTest(またはxUnit)の基本。
- DIの最小(サービス登録/解決)の感覚(任意)。
到達目標
- 演習が“動く・テストが通る・責務が薄い”の3点を満たす。
- パターン導入前後で、呼び出し側の分岐/依存が減ったことを説明できる。
扱うAPI / 言語機能(標準・デファクト中心)
- record + with
- MemberwiseClone(注意事項として)
進め方(アウトライン)
- まず“導入前”の素朴実装を作り、テストで現状を固定する(失敗を再現できる形)。
- Prototypeの役割に合わせてクラス/関数を追加し、呼び出し側のif/switchを移動する。
- テストを追加し、差し替えたいパターン(スタブ/フェイク)で挙動を検証する。
- 最後に命名と責務の整理(1クラス1責務、薄い変換/薄い委譲)を行う。
よくある落とし穴
- 浅いコピーで参照共有が起きる
- コピー範囲が無制限になる
- 演習のために汎用化しすぎて難しくする。
ミニ演習(10〜30分)
- “追加したクラスは何を守るために存在するか”を1行コメントで書く(後で消してOK)。
- 導入前後の差分をGitコミットで分ける。
自己チェック
- テストで差し替えたい点を1箇所で差し替えできるか?
- 新規クラスのpublic APIが最小か?
第29章. Prototype ④:浅い/深いコピー注意⚠️
ねらい
- Prototypeを“やりすぎない”ための判断軸を作る。
- AI補助を使う場合のプロンプト設計・レビュー観点を用意する(章タイトルに合う範囲)。
前提
- ここまでの章の演習が1つ以上動く状態。
到達目標
- “この状況なら導入しない/戻す”が言える。
- レビュー観点(責務/命名/テスト/拡張点)をチェックリスト化できる。
扱うAPI / 言語機能(標準・デファクト中心)
- record + with
- MemberwiseClone(注意事項として)
進め方(アウトライン)
- 導入コスト(クラス数・理解コスト)と、得られる利益(差し替え/テスト/変更容易性)を天秤にかける。
- パターンが必要になる“兆候”を3つ言語化する(例:分岐が増える、初期化が複雑、組合せが爆発)。
- AIで雛形を作るなら、禁止事項(過剰抽象化、汎用フレームワーク化)をプロンプトに明記する。
- レビューで“最小の抽象”になっているかを確認し、不要なら戻す。
よくある落とし穴
- AI出力をそのまま採用して“謎抽象”が増える。
- “便利そう”で導入し、変更が減らない。
ミニ演習(10〜30分)
- 自分の演習コードで、追加した抽象が本当に必要か“削除してみる”実験をする。
- 必要性が残る場合だけ復活させ、その理由を1行で書く(ADRメモでも可)。
自己チェック
- 導入前より、読むべきファイルが増えすぎていないか?
- 抽象(interface/基底)が“利用者にとって”自然な言葉になっているか?
第30章. Singleton ①:有名だけど慎重に👑⚠️
ねらい
- Singletonが解く困りごと(アプリ全体で一つでよい共有資源がある(ただし最小限)。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Singletonの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- Lazy
- IOptions
(代替の考え方)
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- グローバル状態でテストが困難
- 隠れ依存が増える
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをSingletonで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第31章. Singleton ②:.NET流(Lazy)で安全に🛡️🐢
ねらい
- .NETの“現実のSingletonっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- Lazy
- IOptions
(代替の考え方)
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第32章. 生成まとめミニ演習:Factory+Builder+Prototypeで「注文作成」完成🎉
ねらい
- Builderを題材に、変更点を外へ逃がす設計の感覚を強化する。
前提
- Part 0の準備(ソリューション・テスト・ログ)が整っている。
到達目標
- 例題で適用できる。
扱うAPI / 言語機能(標準・デファクト中心)
- StringBuilder
- UriBuilder
進め方(アウトライン)
- 章タイトルに沿って、最小の変更でパターンの効果を体験する。
よくある落とし穴
- Fluent連鎖が読みにくくなる
- 途中状態を外へ漏らすと不正状態が増える
ミニ演習(10〜30分)
- 演習(小)を1つ行う。
自己チェック
- 採用理由を言える。
Part 2:構造パターン(33〜54)🏗️🎁🔌
ゴール:既存コードを壊さず、つなぐ/包む/まとめる/共有することで、拡張に強い組み立て方を身につける。
第33章. 構造の基本:つなぐ/包む/まとめる/共有する🧩
ねらい
- 構造パターンの全体像(つなぐ/包む/まとめる/共有)を分類で掴む。
前提
- 生成パートのどれか1つ演習を完了。
到達目標
- Adapter/Decorator/Facade/Flyweightの違いを一言で言える。
扱うAPI / 言語機能(標準・デファクト中心)
- (なし)
進め方(アウトライン)
- 既存コードを変えずに拡張する発想を作る。
- “壊さない”とは何か(公開API/テスト/契約)を確認。
よくある落とし穴
- 全部Decoratorで解こうとする。
ミニ演習(10〜30分)
- Stream周りで、どこがAdapter/Decorator/Facadeっぽいか線を引く。
自己チェック
- 4分類で説明できる。
第34章. Adapter ①:型のズレを吸収する🔌
ねらい
- Adapterが解く困りごと(外部/既存の型やI/Fが合わないが、使う側のコードを変えたくない。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Adapterの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- Stream -> StreamReader
- TextReader/Writer
- System.Text.Json DTO変換
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- 変換層に業務ルールを混ぜる
- 変換が肥大化して“別のドメイン”になる
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをAdapterで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第35章. Adapter ②:.NET定番(Stream → StreamReader)📚
ねらい
- .NETの“現実のAdapterっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- Stream -> StreamReader
- TextReader/Writer
- System.Text.Json DTO変換
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第36章. Adapter ③:演習(外部APIレスポンスをドメインへ)🌐
ねらい
- Adapterを“最小実装”で手を動かして体に入れる。
- テストで“差し替え可能性”を守る練習をする。
前提
- MSTest(またはxUnit)の基本。
- DIの最小(サービス登録/解決)の感覚(任意)。
到達目標
- 演習が“動く・テストが通る・責務が薄い”の3点を満たす。
- パターン導入前後で、呼び出し側の分岐/依存が減ったことを説明できる。
扱うAPI / 言語機能(標準・デファクト中心)
- Stream -> StreamReader
- TextReader/Writer
- System.Text.Json DTO変換
進め方(アウトライン)
- まず“導入前”の素朴実装を作り、テストで現状を固定する(失敗を再現できる形)。
- Adapterの役割に合わせてクラス/関数を追加し、呼び出し側のif/switchを移動する。
- テストを追加し、差し替えたいパターン(スタブ/フェイク)で挙動を検証する。
- 最後に命名と責務の整理(1クラス1責務、薄い変換/薄い委譲)を行う。
よくある落とし穴
- 変換層に業務ルールを混ぜる
- 変換が肥大化して“別のドメイン”になる
- 演習のために汎用化しすぎて難しくする。
ミニ演習(10〜30分)
- “追加したクラスは何を守るために存在するか”を1行コメントで書く(後で消してOK)。
- 導入前後の差分をGitコミットで分ける。
自己チェック
- テストで差し替えたい点を1箇所で差し替えできるか?
- 新規クラスのpublic APIが最小か?
第37章. Bridge ①:2軸が増えるときに分離する🌉
ねらい
- Bridgeが解く困りごと(抽象(使い方)と実装(中身)の2軸がそれぞれ増える。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Bridgeの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- Stream(抽象)と FileStream/MemoryStream(実装)
- DbConnection/DbCommand(例)
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- 分離する軸の見極めを誤る
- レイヤが増えすぎて追跡が難しい
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをBridgeで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第38章. Bridge ②:.NETの感覚(Streamの実装差し替え)🧃
ねらい
- .NETの“現実のBridgeっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- Stream(抽象)と FileStream/MemoryStream(実装)
- DbConnection/DbCommand(例)
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第39章. Bridge ③:演習(通知フォーマット×通知先)🔔✉️
ねらい
- Bridgeを“最小実装”で手を動かして体に入れる。
- テストで“差し替え可能性”を守る練習をする。
前提
- MSTest(またはxUnit)の基本。
- DIの最小(サービス登録/解決)の感覚(任意)。
到達目標
- 演習が“動く・テストが通る・責務が薄い”の3点を満たす。
- パターン導入前後で、呼び出し側の分岐/依存が減ったことを説明できる。
扱うAPI / 言語機能(標準・デファクト中心)
- Stream(抽象)と FileStream/MemoryStream(実装)
- DbConnection/DbCommand(例)
進め方(アウトライン)
- まず“導入前”の素朴実装を作り、テストで現状を固定する(失敗を再現できる形)。
- Bridgeの役割に合わせてクラス/関数を追加し、呼び出し側のif/switchを移動する。
- テストを追加し、差し替えたいパターン(スタブ/フェイク)で挙動を検証する。
- 最後に命名と責務の整理(1クラス1責務、薄い変換/薄い委譲)を行う。
よくある落とし穴
- 分離する軸の見極めを誤る
- レイヤが増えすぎて追跡が難しい
- 演習のために汎用化しすぎて難しくする。
ミニ演習(10〜30分)
- “追加したクラスは何を守るために存在するか”を1行コメントで書く(後で消してOK)。
- 導入前後の差分をGitコミットで分ける。
自己チェック
- テストで差し替えたい点を1箇所で差し替えできるか?
- 新規クラスのpublic APIが最小か?
第40章. Composite ①:ツリーを同じ扱いにする🌳
ねらい
- Compositeが解く困りごと(木構造(ツリー)を“同じ操作”で扱いたい(葉と枝を同一視)。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Compositeの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- フォルダ階層の発想(DirectoryInfo等)
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- 子の管理責務が曖昧になる
- 循環参照や親参照で破綻しやすい
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをCompositeで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第41章. Composite ②:身近な例で理解(フォルダ階層の発想)📁
ねらい
- .NETの“現実のCompositeっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- フォルダ階層の発想(DirectoryInfo等)
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第42章. Composite ③:演習(メニュー構造をCompositeで)🍱
ねらい
- Compositeを“最小実装”で手を動かして体に入れる。
- テストで“差し替え可能性”を守る練習をする。
前提
- MSTest(またはxUnit)の基本。
- DIの最小(サービス登録/解決)の感覚(任意)。
到達目標
- 演習が“動く・テストが通る・責務が薄い”の3点を満たす。
- パターン導入前後で、呼び出し側の分岐/依存が減ったことを説明できる。
扱うAPI / 言語機能(標準・デファクト中心)
- フォルダ階層の発想(DirectoryInfo等)
進め方(アウトライン)
- まず“導入前”の素朴実装を作り、テストで現状を固定する(失敗を再現できる形)。
- Compositeの役割に合わせてクラス/関数を追加し、呼び出し側のif/switchを移動する。
- テストを追加し、差し替えたいパターン(スタブ/フェイク)で挙動を検証する。
- 最後に命名と責務の整理(1クラス1責務、薄い変換/薄い委譲)を行う。
よくある落とし穴
- 子の管理責務が曖昧になる
- 循環参照や親参照で破綻しやすい
- 演習のために汎用化しすぎて難しくする。
ミニ演習(10〜30分)
- “追加したクラスは何を守るために存在するか”を1行コメントで書く(後で消してOK)。
- 導入前後の差分をGitコミットで分ける。
自己チェック
- テストで差し替えたい点を1箇所で差し替えできるか?
- 新規クラスのpublic APIが最小か?
第43章. Decorator ①:包んで機能を足す🎁✨
ねらい
- Decoratorが解く困りごと(既存の振る舞いに、機能を“後付け”したい(組み合わせ自由)。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Decoratorの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- Streamデコレータ(Buffered/GZip/Crypto)
- ILogger(装飾の考え方)
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- デコレータの順序で挙動が変わる
- 責務が増えて本体が見えなくなる
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをDecoratorで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第44章. Decorator ②:.NET最強例(Streamデコレータ)💧
ねらい
- .NETの“現実のDecoratorっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- Streamデコレータ(Buffered/GZip/Crypto)
- ILogger(装飾の考え方)
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第45章. Decorator ③:演習(ログ付与 / リトライ付与)📝🔁
ねらい
- Decoratorを“最小実装”で手を動かして体に入れる。
- テストで“差し替え可能性”を守る練習をする。
前提
- MSTest(またはxUnit)の基本。
- DIの最小(サービス登録/解決)の感覚(任意)。
到達目標
- 演習が“動く・テストが通る・責務が薄い”の3点を満たす。
- パターン導入前後で、呼び出し側の分岐/依存が減ったことを説明できる。
扱うAPI / 言語機能(標準・デファクト中心)
- Streamデコレータ(Buffered/GZip/Crypto)
- ILogger(装飾の考え方)
進め方(アウトライン)
- まず“導入前”の素朴実装を作り、テストで現状を固定する(失敗を再現できる形)。
- Decoratorの役割に合わせてクラス/関数を追加し、呼び出し側のif/switchを移動する。
- テストを追加し、差し替えたいパターン(スタブ/フェイク)で挙動を検証する。
- 最後に命名と責務の整理(1クラス1責務、薄い変換/薄い委譲)を行う。
よくある落とし穴
- デコレータの順序で挙動が変わる
- 責務が増えて本体が見えなくなる
- 演習のために汎用化しすぎて難しくする。
ミニ演習(10〜30分)
- “追加したクラスは何を守るために存在するか”を1行コメントで書く(後で消してOK)。
- 導入前後の差分をGitコミットで分ける。
自己チェック
- テストで差し替えたい点を1箇所で差し替えできるか?
- 新規クラスのpublic APIが最小か?
第46章. Facade ①:入口を簡単にする🚪🙂
ねらい
- Facadeが解く困りごと(内部が複雑だが、利用者に“簡単な入口”を提供したい。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Facadeの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- File / Directory
- HttpClient(入口としての感覚)
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- FacadeがGod Object化
- 例外/戻り値の契約が曖昧になる
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをFacadeで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第47章. Facade ②:.NETで体感(File / HttpClient)📦🌐
ねらい
- .NETの“現実のFacadeっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- File / Directory
- HttpClient(入口としての感覚)
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第48章. Facade ③:演習(注文処理の窓口クラス)🛒
ねらい
- Facadeを“最小実装”で手を動かして体に入れる。
- テストで“差し替え可能性”を守る練習をする。
前提
- MSTest(またはxUnit)の基本。
- DIの最小(サービス登録/解決)の感覚(任意)。
到達目標
- 演習が“動く・テストが通る・責務が薄い”の3点を満たす。
- パターン導入前後で、呼び出し側の分岐/依存が減ったことを説明できる。
扱うAPI / 言語機能(標準・デファクト中心)
- File / Directory
- HttpClient(入口としての感覚)
進め方(アウトライン)
- まず“導入前”の素朴実装を作り、テストで現状を固定する(失敗を再現できる形)。
- Facadeの役割に合わせてクラス/関数を追加し、呼び出し側のif/switchを移動する。
- テストを追加し、差し替えたいパターン(スタブ/フェイク)で挙動を検証する。
- 最後に命名と責務の整理(1クラス1責務、薄い変換/薄い委譲)を行う。
よくある落とし穴
- FacadeがGod Object化
- 例外/戻り値の契約が曖昧になる
- 演習のために汎用化しすぎて難しくする。
ミニ演習(10〜30分)
- “追加したクラスは何を守るために存在するか”を1行コメントで書く(後で消してOK)。
- 導入前後の差分をGitコミットで分ける。
自己チェック
- テストで差し替えたい点を1箇所で差し替えできるか?
- 新規クラスのpublic APIが最小か?
第49章. Flyweight ①:大量オブジェクトを軽く🪶
ねらい
- Flyweightが解く困りごと(大量の似たオブジェクト生成でメモリ/GC負荷が高い。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Flyweightの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- string共有の発想
- ArrayPool
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- 共有対象が可変で破綻
- 共有管理が複雑になりすぎる
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをFlyweightで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第50章. Flyweight ②:.NET定番(stringの共有 / ArrayPool)🧵📦
ねらい
- .NETの“現実のFlyweightっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- string共有の発想
- ArrayPool
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第51章. Flyweight ③:演習(大量生成するラベル/アイコン情報)🏷️
ねらい
- Flyweightを“最小実装”で手を動かして体に入れる。
- テストで“差し替え可能性”を守る練習をする。
前提
- MSTest(またはxUnit)の基本。
- DIの最小(サービス登録/解決)の感覚(任意)。
到達目標
- 演習が“動く・テストが通る・責務が薄い”の3点を満たす。
- パターン導入前後で、呼び出し側の分岐/依存が減ったことを説明できる。
扱うAPI / 言語機能(標準・デファクト中心)
- string共有の発想
- ArrayPool
進め方(アウトライン)
- まず“導入前”の素朴実装を作り、テストで現状を固定する(失敗を再現できる形)。
- Flyweightの役割に合わせてクラス/関数を追加し、呼び出し側のif/switchを移動する。
- テストを追加し、差し替えたいパターン(スタブ/フェイク)で挙動を検証する。
- 最後に命名と責務の整理(1クラス1責務、薄い変換/薄い委譲)を行う。
よくある落とし穴
- 共有対象が可変で破綻
- 共有管理が複雑になりすぎる
- 演習のために汎用化しすぎて難しくする。
ミニ演習(10〜30分)
- “追加したクラスは何を守るために存在するか”を1行コメントで書く(後で消してOK)。
- 導入前後の差分をGitコミットで分ける。
自己チェック
- テストで差し替えたい点を1箇所で差し替えできるか?
- 新規クラスのpublic APIが最小か?
第52章. Proxy ①:本人の代わりに制御する🪞🚧
ねらい
- Proxyが解く困りごと(本体へのアクセス前後に制御(遅延/キャッシュ/制限/ログ)を入れたい。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Proxyの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- Lazy
- DispatchProxy
- HttpMessageHandler(近縁)
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- 副作用・例外の扱いが本体とズレる
- プロキシが責務過多になる
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをProxyで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第53章. Proxy ②:.NET定番(Lazy / DispatchProxy)⏳🧙
ねらい
- .NETの“現実のProxyっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- Lazy
- DispatchProxy
- HttpMessageHandler(近縁)
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第54章. 構造まとめミニ演習:Stream系でDecorator/Adapter/Facadeを一気に回収🎉
ねらい
- Adapterを題材に、変更点を外へ逃がす設計の感覚を強化する。
前提
- Part 0の準備(ソリューション・テスト・ログ)が整っている。
到達目標
- 例題で適用できる。
扱うAPI / 言語機能(標準・デファクト中心)
- Stream -> StreamReader
- TextReader/Writer
- System.Text.Json DTO変換
進め方(アウトライン)
- 章タイトルに沿って、最小の変更でパターンの効果を体験する。
よくある落とし穴
- 変換層に業務ルールを混ぜる
- 変換が肥大化して“別のドメイン”になる
ミニ演習(10〜30分)
- 演習(小)を1つ行う。
自己チェック
- 採用理由を言える。
Part 3:振る舞いパターン(55〜80)🎭⚙️📣
ゴール:分岐と依存を減らし、流れ・状態・通知・操作を整理して“変更が怖くない”状態に近づける。
第55章. 振る舞いの基本:if/switchを減らす3つの道🧠
ねらい
- 振る舞いパターンで“if/switch”を減らす3つの道を整理する。
前提
- 第12章の分岐地獄がある。
到達目標
- 方針/状態/通知のどれで分岐が増えているか判定できる。
扱うAPI / 言語機能(標準・デファクト中心)
- (なし)
進め方(アウトライン)
- 分岐要因を3分類に分ける。
- 各分類に対応する代表パターンを紐付ける。
よくある落とし穴
- パターンを混ぜすぎる。
ミニ演習(10〜30分)
- 第12章コードの分岐を3色で分類(方針/状態/通知)。
自己チェック
- “この分岐はStrategy/State/Observerのどれ?”が言える。
第56章. Chain of Responsibility ①:流れを“通す”設計🔗
ねらい
- Chain of Responsibilityが解く困りごと(処理を小さく分けて順に流し、途中で止めたり差し替えたい。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Chain of Responsibilityの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- ASP.NET Core Middleware
- DelegatingHandler (HttpMessageHandler)
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- 責務境界が曖昧で“何でも屋”ハンドラが生まれる
- 順序依存が強くなる
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをChain of Responsibilityで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第57章. Chain of Responsibility ②:デファクト①(ASP.NET Core Middleware)🌐
ねらい
- Chain of Responsibilityが解く困りごと(処理を小さく分けて順に流し、途中で止めたり差し替えたい。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Chain of Responsibilityの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- ASP.NET Core Middleware
- DelegatingHandler (HttpMessageHandler)
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- 責務境界が曖昧で“何でも屋”ハンドラが生まれる
- 順序依存が強くなる
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをChain of Responsibilityで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第58章. Chain of Responsibility ③:デファクト②(HttpMessageHandler / DelegatingHandler)📨
ねらい
- .NETの“現実のChain of Responsibilityっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- ASP.NET Core Middleware
- DelegatingHandler (HttpMessageHandler)
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第59章. Chain of Responsibility ④:演習(HttpClientパイプラインでログ+リトライ)📝🔁
ねらい
- Chain of Responsibilityを“やりすぎない”ための判断軸を作る。
- AI補助を使う場合のプロンプト設計・レビュー観点を用意する(章タイトルに合う範囲)。
前提
- ここまでの章の演習が1つ以上動く状態。
到達目標
- “この状況なら導入しない/戻す”が言える。
- レビュー観点(責務/命名/テスト/拡張点)をチェックリスト化できる。
扱うAPI / 言語機能(標準・デファクト中心)
- ASP.NET Core Middleware
- DelegatingHandler (HttpMessageHandler)
進め方(アウトライン)
- 導入コスト(クラス数・理解コスト)と、得られる利益(差し替え/テスト/変更容易性)を天秤にかける。
- パターンが必要になる“兆候”を3つ言語化する(例:分岐が増える、初期化が複雑、組合せが爆発)。
- AIで雛形を作るなら、禁止事項(過剰抽象化、汎用フレームワーク化)をプロンプトに明記する。
- レビューで“最小の抽象”になっているかを確認し、不要なら戻す。
よくある落とし穴
- AI出力をそのまま採用して“謎抽象”が増える。
- “便利そう”で導入し、変更が減らない。
ミニ演習(10〜30分)
- 自分の演習コードで、追加した抽象が本当に必要か“削除してみる”実験をする。
- 必要性が残る場合だけ復活させ、その理由を1行で書く(ADRメモでも可)。
自己チェック
- 導入前より、読むべきファイルが増えすぎていないか?
- 抽象(interface/基底)が“利用者にとって”自然な言葉になっているか?
第60章. Command ①:操作をオブジェクト化する🎮
ねらい
- Commandが解く困りごと(操作を“実行”から切り離し、Undo/履歴/キューイングしたい。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Commandの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- WPF ICommand
- Func/Action
- Task/Channel(発展)
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- コマンドが肥大化してサービスのコピーになる
- 状態(引数)の持ち方が曖昧
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをCommandで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第61章. Command ②:標準(ICommand)で体験(WPFのミニ)🖱️✨
ねらい
- .NETの“現実のCommandっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- WPF ICommand
- Func/Action
- Task/Channel(発展)
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第62章. Command ③:Consoleでも使う(Func/Actionで軽量Command)⚡
ねらい
- Commandを“最小実装”で手を動かして体に入れる。
- テストで“差し替え可能性”を守る練習をする。
前提
- MSTest(またはxUnit)の基本。
- DIの最小(サービス登録/解決)の感覚(任意)。
到達目標
- 演習が“動く・テストが通る・責務が薄い”の3点を満たす。
- パターン導入前後で、呼び出し側の分岐/依存が減ったことを説明できる。
扱うAPI / 言語機能(標準・デファクト中心)
- WPF ICommand
- Func/Action
- Task/Channel(発展)
進め方(アウトライン)
- まず“導入前”の素朴実装を作り、テストで現状を固定する(失敗を再現できる形)。
- Commandの役割に合わせてクラス/関数を追加し、呼び出し側のif/switchを移動する。
- テストを追加し、差し替えたいパターン(スタブ/フェイク)で挙動を検証する。
- 最後に命名と責務の整理(1クラス1責務、薄い変換/薄い委譲)を行う。
よくある落とし穴
- コマンドが肥大化してサービスのコピーになる
- 状態(引数)の持ち方が曖昧
- 演習のために汎用化しすぎて難しくする。
ミニ演習(10〜30分)
- “追加したクラスは何を守るために存在するか”を1行コメントで書く(後で消してOK)。
- 導入前後の差分をGitコミットで分ける。
自己チェック
- テストで差し替えたい点を1箇所で差し替えできるか?
- 新規クラスのpublic APIが最小か?
第63章. Iterator ①:foreachの裏側を知る🚶♀️
ねらい
- Iteratorが解く困りごと(走査のやり方を統一し、内部構造を隠したい。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Iteratorの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- IEnumerable
- yield return
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- 遅延評価で例外のタイミングが分かりづらい
- 多重列挙で副作用が出る
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをIteratorで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第64章. Iterator ②:C#本命(IEnumerable / yield return)🌟
ねらい
- .NETの“現実のIteratorっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- IEnumerable
- yield return
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第65章. Iterator ③:演習(注文のフィルタ列挙をyieldで)🛒
ねらい
- Iteratorを“最小実装”で手を動かして体に入れる。
- テストで“差し替え可能性”を守る練習をする。
前提
- MSTest(またはxUnit)の基本。
- DIの最小(サービス登録/解決)の感覚(任意)。
到達目標
- 演習が“動く・テストが通る・責務が薄い”の3点を満たす。
- パターン導入前後で、呼び出し側の分岐/依存が減ったことを説明できる。
扱うAPI / 言語機能(標準・デファクト中心)
- IEnumerable
- yield return
進め方(アウトライン)
- まず“導入前”の素朴実装を作り、テストで現状を固定する(失敗を再現できる形)。
- Iteratorの役割に合わせてクラス/関数を追加し、呼び出し側のif/switchを移動する。
- テストを追加し、差し替えたいパターン(スタブ/フェイク)で挙動を検証する。
- 最後に命名と責務の整理(1クラス1責務、薄い変換/薄い委譲)を行う。
よくある落とし穴
- 遅延評価で例外のタイミングが分かりづらい
- 多重列挙で副作用が出る
- 演習のために汎用化しすぎて難しくする。
ミニ演習(10〜30分)
- “追加したクラスは何を守るために存在するか”を1行コメントで書く(後で消してOK)。
- 導入前後の差分をGitコミットで分ける。
自己チェック
- テストで差し替えたい点を1箇所で差し替えできるか?
- 新規クラスのpublic APIが最小か?
第66章. Observer ①:変化を知らせる📣
ねらい
- Observerが解く困りごと(状態変化を疎結合に通知し、購読者を追加しやすくしたい。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Observerの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- event / EventHandler
- IObservable
(発展)
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- 購読解除漏れでメモリリーク
- 通知順序や例外の扱いが曖昧
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをObserverで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第67章. Observer ②:C#標準(event / EventHandler)🔔
ねらい
- .NETの“現実のObserverっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- event / EventHandler
- IObservable
(発展)
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第68章. Observer ③:発展(IObservable / Reactive系の入口)🌊
ねらい
- Observerを“最小実装”で手を動かして体に入れる。
- テストで“差し替え可能性”を守る練習をする。
前提
- MSTest(またはxUnit)の基本。
- DIの最小(サービス登録/解決)の感覚(任意)。
到達目標
- 演習が“動く・テストが通る・責務が薄い”の3点を満たす。
- パターン導入前後で、呼び出し側の分岐/依存が減ったことを説明できる。
扱うAPI / 言語機能(標準・デファクト中心)
- event / EventHandler
- IObservable
(発展)
進め方(アウトライン)
- まず“導入前”の素朴実装を作り、テストで現状を固定する(失敗を再現できる形)。
- Observerの役割に合わせてクラス/関数を追加し、呼び出し側のif/switchを移動する。
- テストを追加し、差し替えたいパターン(スタブ/フェイク)で挙動を検証する。
- 最後に命名と責務の整理(1クラス1責務、薄い変換/薄い委譲)を行う。
よくある落とし穴
- 購読解除漏れでメモリリーク
- 通知順序や例外の扱いが曖昧
- 演習のために汎用化しすぎて難しくする。
ミニ演習(10〜30分)
- “追加したクラスは何を守るために存在するか”を1行コメントで書く(後で消してOK)。
- 導入前後の差分をGitコミットで分ける。
自己チェック
- テストで差し替えたい点を1箇所で差し替えできるか?
- 新規クラスのpublic APIが最小か?
第69章. Observer ④:演習(注文確定→通知を購読者へ)🎉
ねらい
- Observerを“やりすぎない”ための判断軸を作る。
- AI補助を使う場合のプロンプト設計・レビュー観点を用意する(章タイトルに合う範囲)。
前提
- ここまでの章の演習が1つ以上動く状態。
到達目標
- “この状況なら導入しない/戻す”が言える。
- レビュー観点(責務/命名/テスト/拡張点)をチェックリスト化できる。
扱うAPI / 言語機能(標準・デファクト中心)
- event / EventHandler
- IObservable
(発展)
進め方(アウトライン)
- 導入コスト(クラス数・理解コスト)と、得られる利益(差し替え/テスト/変更容易性)を天秤にかける。
- パターンが必要になる“兆候”を3つ言語化する(例:分岐が増える、初期化が複雑、組合せが爆発)。
- AIで雛形を作るなら、禁止事項(過剰抽象化、汎用フレームワーク化)をプロンプトに明記する。
- レビューで“最小の抽象”になっているかを確認し、不要なら戻す。
よくある落とし穴
- AI出力をそのまま採用して“謎抽象”が増える。
- “便利そう”で導入し、変更が減らない。
ミニ演習(10〜30分)
- 自分の演習コードで、追加した抽象が本当に必要か“削除してみる”実験をする。
- 必要性が残る場合だけ復活させ、その理由を1行で書く(ADRメモでも可)。
自己チェック
- 導入前より、読むべきファイルが増えすぎていないか?
- 抽象(interface/基底)が“利用者にとって”自然な言葉になっているか?
第70章. Strategy ①:方針を差し替える🧠🔁
ねらい
- Strategyが解く困りごと(アルゴリズム(方針)を差し替えたい。if/switchの増殖を止めたい。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Strategyの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- IComparer
- Comparison
- Func<>
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- 戦略の選択条件が別のif地獄になる
- 戦略が細かすぎて把握不能
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをStrategyで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第71章. Strategy ②:標準例(IComparer / Comparison)📏
ねらい
- .NETの“現実のStrategyっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- IComparer
- Comparison
- Func<>
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第72章. Strategy ③:C#らしく(FuncでStrategyを渡す)⚡
ねらい
- Strategyを“最小実装”で手を動かして体に入れる。
- テストで“差し替え可能性”を守る練習をする。
前提
- MSTest(またはxUnit)の基本。
- DIの最小(サービス登録/解決)の感覚(任意)。
到達目標
- 演習が“動く・テストが通る・責務が薄い”の3点を満たす。
- パターン導入前後で、呼び出し側の分岐/依存が減ったことを説明できる。
扱うAPI / 言語機能(標準・デファクト中心)
- IComparer
- Comparison
- Func<>
進め方(アウトライン)
- まず“導入前”の素朴実装を作り、テストで現状を固定する(失敗を再現できる形)。
- Strategyの役割に合わせてクラス/関数を追加し、呼び出し側のif/switchを移動する。
- テストを追加し、差し替えたいパターン(スタブ/フェイク)で挙動を検証する。
- 最後に命名と責務の整理(1クラス1責務、薄い変換/薄い委譲)を行う。
よくある落とし穴
- 戦略の選択条件が別のif地獄になる
- 戦略が細かすぎて把握不能
- 演習のために汎用化しすぎて難しくする。
ミニ演習(10〜30分)
- “追加したクラスは何を守るために存在するか”を1行コメントで書く(後で消してOK)。
- 導入前後の差分をGitコミットで分ける。
自己チェック
- テストで差し替えたい点を1箇所で差し替えできるか?
- 新規クラスのpublic APIが最小か?
第73章. Strategy ④:演習(割引ルールを差し替え)💸
ねらい
- Strategyを“やりすぎない”ための判断軸を作る。
- AI補助を使う場合のプロンプト設計・レビュー観点を用意する(章タイトルに合う範囲)。
前提
- ここまでの章の演習が1つ以上動く状態。
到達目標
- “この状況なら導入しない/戻す”が言える。
- レビュー観点(責務/命名/テスト/拡張点)をチェックリスト化できる。
扱うAPI / 言語機能(標準・デファクト中心)
- IComparer
- Comparison
- Func<>
進め方(アウトライン)
- 導入コスト(クラス数・理解コスト)と、得られる利益(差し替え/テスト/変更容易性)を天秤にかける。
- パターンが必要になる“兆候”を3つ言語化する(例:分岐が増える、初期化が複雑、組合せが爆発)。
- AIで雛形を作るなら、禁止事項(過剰抽象化、汎用フレームワーク化)をプロンプトに明記する。
- レビューで“最小の抽象”になっているかを確認し、不要なら戻す。
よくある落とし穴
- AI出力をそのまま採用して“謎抽象”が増える。
- “便利そう”で導入し、変更が減らない。
ミニ演習(10〜30分)
- 自分の演習コードで、追加した抽象が本当に必要か“削除してみる”実験をする。
- 必要性が残る場合だけ復活させ、その理由を1行で書く(ADRメモでも可)。
自己チェック
- 導入前より、読むべきファイルが増えすぎていないか?
- 抽象(interface/基底)が“利用者にとって”自然な言葉になっているか?
第74章. State ①:状態で振る舞いを分ける🚦
ねらい
- Stateが解く困りごと(状態によって許可される操作や振る舞いが変わる(分岐が増える)。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Stateの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- switch式(対比)
- record/enum(最小で)
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- 汎用状態機械を作り始めて脱線
- 遷移表がコードとズレる
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをStateで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第75章. State ②:C#で自然に(状態クラスは最小限)🧩
ねらい
- .NETの“現実のStateっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- switch式(対比)
- record/enum(最小で)
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第76章. State ③:演習(注文の状態:New→Paid→Shipped)📦🚚
ねらい
- Stateを“最小実装”で手を動かして体に入れる。
- テストで“差し替え可能性”を守る練習をする。
前提
- MSTest(またはxUnit)の基本。
- DIの最小(サービス登録/解決)の感覚(任意)。
到達目標
- 演習が“動く・テストが通る・責務が薄い”の3点を満たす。
- パターン導入前後で、呼び出し側の分岐/依存が減ったことを説明できる。
扱うAPI / 言語機能(標準・デファクト中心)
- switch式(対比)
- record/enum(最小で)
進め方(アウトライン)
- まず“導入前”の素朴実装を作り、テストで現状を固定する(失敗を再現できる形)。
- Stateの役割に合わせてクラス/関数を追加し、呼び出し側のif/switchを移動する。
- テストを追加し、差し替えたいパターン(スタブ/フェイク)で挙動を検証する。
- 最後に命名と責務の整理(1クラス1責務、薄い変換/薄い委譲)を行う。
よくある落とし穴
- 汎用状態機械を作り始めて脱線
- 遷移表がコードとズレる
- 演習のために汎用化しすぎて難しくする。
ミニ演習(10〜30分)
- “追加したクラスは何を守るために存在するか”を1行コメントで書く(後で消してOK)。
- 導入前後の差分をGitコミットで分ける。
自己チェック
- テストで差し替えたい点を1箇所で差し替えできるか?
- 新規クラスのpublic APIが最小か?
第77章. Template Method ①:手順は固定、差分だけ埋める📜
ねらい
- Template Methodが解く困りごと(処理手順は固定だが、部分的な差分だけ差し替えたい。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Template Methodの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- abstract/virtual
- protected hook methods
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- 継承の濫用で拡張が困難
- フックが多すぎて可読性低下
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをTemplate Methodで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第78章. Template Method ②:演習(検証→実行→ログの共通フロー)✅📝
ねらい
- .NETの“現実のTemplate Methodっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- abstract/virtual
- protected hook methods
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第79章. Visitor ①:構造と操作を分離する🧳
ねらい
- Visitorが解く困りごと(構造(Composite等)は固定だが、操作が増え続ける。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Visitorの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- ExpressionVisitor
- Roslyn(発展:C#構文木)
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- 追加する構造(要素)が増えるとVisitor全改修
- 最初の実装が難しく挫折しがち
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをVisitorで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第80章. Visitor ②:標準例(ExpressionVisitor)で学ぶ🧠✨
ねらい
- .NETの“現実のVisitorっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- ExpressionVisitor
- Roslyn(発展:C#構文木)
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第81章. Visitor ③:演習(式ツリーの解析:ノード数える/書き換える)🧾🔍
ねらい
- Visitorを“最小実装”で手を動かして体に入れる。
- テストで“差し替え可能性”を守る練習をする。
前提
- MSTest(またはxUnit)の基本。
- DIの最小(サービス登録/解決)の感覚(任意)。
到達目標
- 演習が“動く・テストが通る・責務が薄い”の3点を満たす。
- パターン導入前後で、呼び出し側の分岐/依存が減ったことを説明できる。
扱うAPI / 言語機能(標準・デファクト中心)
- ExpressionVisitor
- Roslyn(発展:C#構文木)
進め方(アウトライン)
- まず“導入前”の素朴実装を作り、テストで現状を固定する(失敗を再現できる形)。
- Visitorの役割に合わせてクラス/関数を追加し、呼び出し側のif/switchを移動する。
- テストを追加し、差し替えたいパターン(スタブ/フェイク)で挙動を検証する。
- 最後に命名と責務の整理(1クラス1責務、薄い変換/薄い委譲)を行う。
よくある落とし穴
- 追加する構造(要素)が増えるとVisitor全改修
- 最初の実装が難しく挫折しがち
- 演習のために汎用化しすぎて難しくする。
ミニ演習(10〜30分)
- “追加したクラスは何を守るために存在するか”を1行コメントで書く(後で消してOK)。
- 導入前後の差分をGitコミットで分ける。
自己チェック
- テストで差し替えたい点を1箇所で差し替えできるか?
- 新規クラスのpublic APIが最小か?
第82章. Mediator ①:依存の爆発を中央で整理🕊️
ねらい
- Mediatorが解く困りごと(部品同士が直接参照し合い、依存が爆発する。)を“言葉で説明”できるようにする。
- パターン名の暗記ではなく、採用判断の観点(増えるもの・変わるもの・守りたいもの)を作る。
前提
- C#のinterface/抽象クラス、依存の向き(呼ぶ側/呼ばれる側)の感覚。
到達目標
- Mediatorの“使う/使わない”を、具体的な条件で言える。
- 最小構成のクラス図(頭の中レベル)を描ける:役割・責務・依存方向。
扱うAPI / 言語機能(標準・デファクト中心)
- MediatR(NuGet定番)
進め方(アウトライン)
- 困りごとを1つ決める(例:支払い手段の生成、通知先の差し替え等)。
- “変わる点”と“変えたくない点”を分けてメモする(=設計の軸)。
- パターンの役割に沿って、責務を置く場所を決める(呼び出し側のifを減らす)。
- 最後に、テスト視点で差し替えが簡単になったかを確認する。
よくある落とし穴
- Mediatorが神クラス化
- イベント/コマンドの粒度が曖昧
- “パターンっぽいクラス名”を作ることが目的化する。
ミニ演習(10〜30分)
- 現状のif/switchを1つ選び、どの責務が混在しているか3つ列挙する。
- そのうち1つだけをMediatorで解ける形に書き換える案をアウトラインで作る(実装は次章)。
自己チェック
- 呼び出し側が“具体型”を知らなくなったか?
- 差し替えたい理由が1文で言えるか?(テスト/拡張/複雑初期化など)
第83章. Mediator ②:デファクト(MediatR)を使う🤝✨
ねらい
- .NETの“現実のMediatorっぽさ”を読んで体感する。
- APIの使い手として、どこが抽象でどこが差し替え点かを見抜く。
前提
- Visual Studioでソース参照/ドキュメント参照ができる。
到達目標
- 対象APIで“呼び出し側が何を知らないで済むか”を説明できる。
- 自分のコードに落とすときの粒度(小さく始める)を言える。
扱うAPI / 言語機能(標準・デファクト中心)
- MediatR(NuGet定番)
進め方(アウトライン)
- 対象APIを1つ決め、公式ドキュメント/IntelliSenseでシグネチャを確認する。
- 戻り型・生成メソッド名(Create/Factory等)から意図を推測する。
- “呼び出し側が持つべき責務”と“API内部に押し込まれた責務”を箇条書きする。
- ミニ模倣コードを書き、テストで“差し替え点”を確認する。
よくある落とし穴
- “読むだけ”で終わって自分の課題に接続しない。
- 例外やDisposeなど契約(資源管理)を見落とす。
ミニ演習(10〜30分)
- 対象APIを2つ挙げ、共通点(差し替え/隠蔽)と相違点(粒度/責務)を比較メモする。
自己チェック
- 戻り型が抽象寄りになっている理由を説明できるか?
- 利用者が“知らなくてよい情報”を3つ言えるか?
第84章. Mediator ③:演習(注文確定コマンド→複数ハンドラへ)📨🎯
ねらい
- Mediatorを“最小実装”で手を動かして体に入れる。
- テストで“差し替え可能性”を守る練習をする。
前提
- MSTest(またはxUnit)の基本。
- DIの最小(サービス登録/解決)の感覚(任意)。
到達目標
- 演習が“動く・テストが通る・責務が薄い”の3点を満たす。
- パターン導入前後で、呼び出し側の分岐/依存が減ったことを説明できる。
扱うAPI / 言語機能(標準・デファクト中心)
- MediatR(NuGet定番)
進め方(アウトライン)
- まず“導入前”の素朴実装を作り、テストで現状を固定する(失敗を再現できる形)。
- Mediatorの役割に合わせてクラス/関数を追加し、呼び出し側のif/switchを移動する。
- テストを追加し、差し替えたいパターン(スタブ/フェイク)で挙動を検証する。
- 最後に命名と責務の整理(1クラス1責務、薄い変換/薄い委譲)を行う。
よくある落とし穴
- Mediatorが神クラス化
- イベント/コマンドの粒度が曖昧
- 演習のために汎用化しすぎて難しくする。
ミニ演習(10〜30分)
- “追加したクラスは何を守るために存在するか”を1行コメントで書く(後で消してOK)。
- 導入前後の差分をGitコミットで分ける。
自己チェック
- テストで差し替えたい点を1箇所で差し替えできるか?
- 新規クラスのpublic APIが最小か?
第85章. (発展)Interpreter / Memento:標準寄せで“触るだけ”🧠🌱
ねらい
- Interpreterを題材に、変更点を外へ逃がす設計の感覚を強化する。
前提
- Part 0の準備(ソリューション・テスト・ログ)が整っている。
到達目標
- 例題で適用できる。
扱うAPI / 言語機能(標準・デファクト中心)
- Regex
- System.Linq.Expressions(関連)
進め方(アウトライン)
- 章タイトルに沿って、最小の変更でパターンの効果を体験する。
よくある落とし穴
- 自作言語を作り始めて終わらない
- 性能と保守性が破綻
ミニ演習(10〜30分)
- 演習(小)を1つ行う。
自己チェック
- 採用理由を言える。
仕上げ:Capstone(任意・別冊)
Part 0〜3の学びを“実務っぽく”束ねる回収フェーズ。章番号に縛られず、成果物ベースで進めます。
Capstone-1:最小ユースケースを決める
- ユースケース例:
PlaceOrder(注文確定)→ 支払い → 在庫引当 → 通知 → ログ/監査 - “外側(HTTP/DB)”はモックで良い。内側(業務)を守るのが目的。
Capstone-2:コミット単位で改善する(推奨フロー)
- ベースライン(分岐地獄)をテストで固定
- Strategyで“方針”を分ける(送料/割引/並び替え)
- Stateで“状態”を分ける(注文の許可操作/遷移)
- Observer/Mediatorで“通知”を分ける(追加機能を疎結合に)
- Decorator/Proxyで“横断”を付け足す(ログ/リトライ/計測)
Capstone-3:採用判断メモ(軽量ADR)を書く
- 1パターンにつき1〜3行でOK:『なぜ採用?』『代替案は?』『いつ外す?』
- これが“次に同じ問題に当たった時の自分の説明書”になります。
付録:標準/デファクトの“優先リスト”
- Iterator:
IEnumerable<T>/yield return - Decorator:
Stream系(BufferedStream,GZipStream,CryptoStream) - CoR:ASP.NET Core Middleware /
DelegatingHandler - Proxy:
Lazy<T>/DispatchProxy - Observer:
event/EventHandler(発展:IObservable<T>) - Mediator:MediatR(NuGet定番)
- Visitor:
ExpressionVisitor(発展:Roslyn)