導入
23パターンを学びました。しかしパターンは目的ではなく道具です。「痛みを感じてから導入する」のが鉄則。ここでは分類の地図と、標準ライブラリの中に潜むパターンを確認します。
図解
flowchart TB
P["GoF 23パターン"] --> C["生成(5)<br/>Factory系 / Builder / Prototype / Singleton"]
P --> S["構造(7)<br/>Adapter / Bridge / Composite / Decorator<br/>Facade / Flyweight / Proxy"]
P --> B["振る舞い(11)<br/>Strategy / State / Observer / Mediator<br/>Command / CoR / Template / Iterator<br/>Visitor / Interpreter / Memento"]
サンプル
// 標準ライブラリは既にパターンの塊。「知らずに使っていたもの」に名前を付ける
// ・Iterator: foreach(IEnumerable)
foreach (var n in new[] { 1, 2, 3 }) { }
// ・Strategy: LINQ に渡すラムダ(比較・射影のアルゴリズムを差し替え)
var sorted = new[] { 3, 1, 2 }.OrderBy(x => x); // OrderBy に渡す x => x が戦略
// ・Decorator: Stream を包む Stream(BufferedStream 等)
// ・Observer: C# の event
// ・Factory: DateTime.Parse / Enumerable.Range などの生成メソッド
Console.WriteLine(string.Join(", ", sorted)); // 1, 2, 3
Console.WriteLine("標準ライブラリはパターンの宝庫");
- YAGNI(今要らないものは作るな)・KISS(単純に保て)を忘れない
- パターンは「複雑さに耐えるため」に使う。単純な問題に持ち込むと過剰設計になる
- まずは「標準ライブラリやフレームワークが使っているパターンを読める」ことが重要
演習
// foreach(Iterator)と OrderBy(Strategy)を組み合わせる実践
int[] scores = { 72, 95, 60, 88 };
// TODO: 降順に並べ替えて(Strategyとしてラムダを渡す)、1行ずつ出力してください
// (95 / 88 / 72 / 60)
___
- 期待される出力:
95887260(4行)
ヒント1を見る
scores.OrderByDescending(s => s) をforeachで回します
ヒント2を見る
foreach (var s in scores.OrderByDescending(s => s)) Console.WriteLine(s);
まとめ
- パターンは目的でなく道具。YAGNI・KISSを優先する
- 標準ライブラリ・フレームワークはパターンの宝庫
- まず「読める」こと、痛みを感じてから「使う」こと