Slide 1

Slide 1 text

2025/04/23 社内勉強会 デザインパターン概論 1

Slide 2

Slide 2 text

2 その前に

Slide 3

Slide 3 text

The Best Programmers I Know 3 最高の開発者になるために

Slide 4

Slide 4 text

● 今回、新人さんの参加があると思われる ● デザインパターンの話があまりピンと来なかったり、 実務で使うまでに忘れてしまったりするかも ● それだともったいないので、最近読んでよかったブログを紹介 ● ※発表者による日本語訳 4 What is it?

Slide 5

Slide 5 text

1. リファレンスを読む 2. ツールを深く理解する 3. エラーメッセージを読む 4. 問題を分解する 5. 手を汚すことを恐れない 6. 常に他者を助ける 7. 書く習慣を持つ 8. 学び続ける 5 The Best Programmers I Know 9. 地位を気にかけない 10. 評判を確立する 11. 忍耐力を持つ 12. コンピューターを責めない 13. 「わからない」と言うことを 恐れない 14. 推測しない 15. シンプルに保つ

Slide 6

Slide 6 text

1. リファレンスを読む 2. ツールを深く理解する 3. エラーメッセージを読む 4. 問題を分解する 5. 手を汚すことを恐れない 6. 常に他者を助ける 7. 書く習慣を持つ 8. 学び続ける 6 The Best Programmers I Know 9. 地位を気にかけない 10. 評判を確立する 11. 忍耐力を持つ 12. コンピューターを責めない 13. 「わからない」と言うことを 恐れない 14. 推測しない 15. シンプルに保つ この7つを紹介

Slide 7

Slide 7 text

7 ● 理解しなくてもツールは使える(それがツール) ● 優れた開発者は、自分が使っている技術を根本的なレベルで理解している ● ツールをただ使っているだけでは、手探りで試行錯誤したり、 すぐに混乱したり、間違った考えを持ってしまう ● ツールを理解するとは、以下を知ること ○ 歴史:誰が作ったもの?なぜ作った?どんな課題を解決するため? ○ 現状:誰が管理している?その人はどこでどんな仕事をしている? ○ 制限:いつ使うべきか、または使わないべきか?どう使うと壊れる? ○ エコシステム:どんなライブラリが存在する?誰が使っている? ツールを深く理解する Know Your Tools Really Well

Slide 8

Slide 8 text

8 ● 大きい問題や複雑な問題は、解決できるまで分解・単純化する ● 習得するのが難しいスキルで、大量の経験が必要 ● プロの開発者の仕事の大部分は問題の分解 問題を分解する Break Down Problems

Slide 9

Slide 9 text

9 ● 最高の開発者は、多くのコードを読み、実践する ● 「自分には向いていない」「自分にできることはない」という前に学び始め ている ● 周囲がその努力に気づく前に、その技術について頼りになる存在に なっている 手を汚すことを恐れない Don’t Be Afraid To Get Your Hands Dirty

Slide 10

Slide 10 text

10 ● 優れたエンジニアはいつも忙しいが、常に助けようとする ● なぜなら、彼らは好奇心旺盛で、その助けようとする心によって 優れたエンジニアになったから 常に他者を助ける Always Help Others

Slide 11

Slide 11 text

11 ● コンピューターと人間、特に自分自身に対する忍耐が大切 ● 学習には時間がかかる ○ 能力が低いわけではなく、ただ不完全な情報を持っているだけ ● 難しい問題を解決したり、プロジェクトを終わらせるためには 努力が必要 ● 忍耐力、集中力、献身を持って臨みましょう 忍耐力を持つ Have Patience

Slide 12

Slide 12 text

12 ● コンピューターの動作がどんなに不安定でいたずらに見えても、 常に論理的な理由がある ● 最高の開発者は、理由が見つかるまで深掘りする ● 理由はすぐには見つからないかもしれないし、結局見つからずに 終わるかもしれない ● 見つけられなくても、彼らは外部の状況のせいにしない ● この態度によって、彼らは大きく成長し、他の人にはできないことを学ぶ コンピューターを責めない Never Blame the Computer

Slide 13

Slide 13 text

13 ● 推測は楽なので、我々は推測してしまいがち ● 推測すると何が起きるか? ○ 最良の場合: ■ あなたは間違っていて、間違った仮定がバグを生む ○ 最悪の場合: ■ あなたは正しく、偶然うまくいったことを正解だと思い込んでし まう ● 質問したり、リファレンスを読んだり、デバッグしたりして、 答えを得ることが大事 推測しない Don’t Guess

Slide 14

Slide 14 text

14 気になったら読んでみてね The Best Programmers I Know | Matthias Endler まとめ

Slide 15

Slide 15 text

15 デザインパターン 閑話休題

Slide 16

Slide 16 text

16 ● オブジェクト指向における重要な概念であるデザインパターン ● デザインパターンの概要の説明 ● パターンをいくつか紹介 ○ どんな状況で(When) ○ どんな問題が発生したら(What) ○ どのように解決するか(How) What is it?

Slide 17

Slide 17 text

17 デザインパターンとは

Slide 18

Slide 18 text

18 ある問題に対して、よく使われる効果的な解決方法を抽象化・定型化 した“設計のひな型”のことを指します。 ソフトウェア開発におけるデザインパターンまたは設計パターン(英: design pattern)とは、過去のソフトウェア設計者が発見し編み出し た設計ノウハウを蓄積し、名前をつけ、再利用し やすいように特定の規約に従ってカタログ化したものである。 デザインパターンとは?

Slide 19

Slide 19 text

19 ある問題に対して、よく使われる効果的な解決方法 を抽象化・定型 化した“設計のひな型”のことを指します。 ソフトウェア開発におけるデザインパターンまたは設計パターン(英: design pattern)とは、過去のソフトウェア設計者が発見し編み出し た設計ノウハウを蓄積し、名前をつけ、再利用しやすいように 特定の 規約に従ってカタログ化したもの である。 デザインパターンとは?

Slide 20

Slide 20 text

20 ある問題に対して、よく使われる効果的な解決方法 を抽象化・定型 化した“設計のひな型”のことを指します。 ソフトウェア開発におけるデザインパターンまたは設計パターン(英: design pattern)とは、過去のソフトウェア設計者が発見し編み出し た設計ノウハウを蓄積し、名前をつけ、再利用しやすいように 特定の 規約に従ってカタログ化したもの である。 デザインパターンとは? 名前をつけたことも重要な功績 人間が認識できるようになった

Slide 21

Slide 21 text

21 デザインパターンの原典 今日「デザインパターン」と言うと 左の書籍で紹介された23種類の パターンを指す 著者4人を敬意を込めて “Gang of Four (GoF)” と呼ぶ 本のことはGoF本と 呼んだりする

Slide 22

Slide 22 text

22 デザインパターンの原典 1994年出版(30年前!) Java や C# は生まれていない Webアプリケーションはほとんどない 当時よく使われていた言語は C++ 書籍のサンプルコードも C++ GUIアプリケーションに適用する想定

Slide 23

Slide 23 text

23 日本語の書籍 GoF本の日本語訳(左) 右の書籍が有名、入門書とし ておすすめ 私は読んだことないけど、 みんなそう言ってます

Slide 24

Slide 24 text

24 1. オブジェクト指向の時代背景 2. 実践的な内容 なぜデザインパターンが普及したのか?

Slide 25

Slide 25 text

25 GoF本が出版された当時、オブジェクト指向の認知度が高まっており、言語が いくつも登場するなど注目されていた 再利用性が高いと言われていたが、継承を間違って使っていたり、言語を変え ても設計が古いまま、といった状況が発生していた デザインパターンによって「再利用」の真の有用性が発見され、世間のオブ ジェクト指向に対する理解が深まった なぜデザインパターンが普及したのか? 1. オブジェクト指向の時代背景

Slide 26

Slide 26 text

26 GoF本が出版された当時、オブジェクト指向の認知度が高まっており、言語が いくつも登場するなど注目されていた 再利用性が高いと言われていたが、継承を間違って使っていたり、言語を変え ても設計が古いまま、といった状況が発生していた デザインパターンによって「再利用」 の真の有用性が発見され、世間のオブ ジェクト指向に対する理解が深まった なぜデザインパターンが普及したのか? 1. オブジェクト指向の時代背景 オブジェクト指向における 再利用のためのデザインパターン

Slide 27

Slide 27 text

27 デザインパターンは理論ではなく、実際に現場で何度も利用され 洗練された知恵の集大成 「こうすればうまくいく」ノウハウが詰まっている 言語に依存せず、抽象的すぎないのですぐに実践できる なぜデザインパターンが普及したのか? 2. 実践的な内容

Slide 28

Slide 28 text

28 ● デザインパターンとは、ソフトウェア設計における問題に対して、よく使わ れる解決方法をまとめたもの ● 1994年当時、オブジェクト指向が流行りはじめていたが、 使いこなせていない人が多かった ● デザインパターンによって「オブジェクト指向はこうやる」という指針ができ た ● その結果、めっちゃ普及した ここまでのまとめ

Slide 29

Slide 29 text

29 1. 設計の質を高められる 2. 共通言語として利用できる 3. 言語やフレームワークに取り込まれている なぜデザインパターンを学ぶのか?

Slide 30

Slide 30 text

30 ● デザインパターンを活用することで、 保守性、拡張性、再利用性の高い設計をしやすくなる ● パターンに従うことで、変更に強いコードを書ける ● また、根拠をもって実装できる なぜデザインパターンを学ぶのか? 1. 設計の質を高める

Slide 31

Slide 31 text

31 ● 「ここは〇〇パターンを使おう」のような会話ができる ● 具体的な内容に言及しなくても意思疎通が可能 ○ これが名前があることのよさ なぜデザインパターンを学ぶのか? 2. 共通言語として利用できる

Slide 32

Slide 32 text

32 ● 言語自体が機能として提供したり、デザインパターンにしたがって 設計されたフレームワークが増えた ○ 例えば、Java や C# はデザインパターンにかなり影響を受けている ● デザインパターンを使いこなせば、より簡潔に書けたり、 フレームワークの機能を拡張できたりする なぜデザインパターンを学ぶのか? 3. 言語やフレームワークに取り込まれている

Slide 33

Slide 33 text

33 デザインパターンのこと、もっ と知りたくなって 来ましたね?

Slide 34

Slide 34 text

34 デザインパターン・カタログ

Slide 35

Slide 35 text

35 生成 🐣 ● Abstract Factory ● Builder ● Factory Method ● Prototype ● Singleton パターン一覧( 23種) 構造 🏛 ● Adopter ● Bridge ● Composite ● Decorator ● Facade ● Flyweight ● Proxy 振る舞い 🕺 ● Chain of Responsibility ● Command ● Interpreter ● Iterator ● Mediator ● Memento ● Observer ● State ● Strategy ● Template Method ● Visitor 投票 進む 参考:Refactoring.Guru

Slide 36

Slide 36 text

36 生成🐣

Slide 37

Slide 37 text

37 状況と問題 ● たくさんのフィールドをもち、 複雑な初期化が必要なクラス ● 状況に応じたサブクラスを 作るのは非現実的 ● コンストラクタの呼び出しで 使われないパラメータを大量に渡す必要がある Builder 複雑なオブジェクトを段階的に構築する 一覧 参考:Refactoring.Guru 🐣

Slide 38

Slide 38 text

38 解決方法 ● オブジェクトの構築をBuilderクラスに抽出 ● Builderの実装ごとに、各ステップで実施する 内容は異なる ● すべてのステップを呼び出す必要はない ● 構築中にProductにアクセスすることは 禁止する Builder 複雑なオブジェクトを段階的に構築する 一覧 参考:Refactoring.Guru <> Builder reset() buildStepA() buildStepB() buildStepZ() ConcreteBuilder result:Product reset() buildStepA() buildStepB() buildStepZ() getResult():Product 実装 🐣

Slide 39

Slide 39 text

39 状況と問題 ● オブジェクトの正確なコピーをしたいとする ● 新規オブジェクトを作って、フィールドを一つずつコピーして。。。 ○ privateなフィールドに対応できない ○ すべてのフィールドを知っている必要がある 知っている=密結合なので、よくない設計 Prototype コピーを作成する 参考:Refactoring.Guru 🐣 一覧

Slide 40

Slide 40 text

40 解決方法 ● コピーしたいオブジェクト自身に cloneメソッドを実装する ○ 自分のprivateフィールドにはアクセスできる ● 値のコピーだけでなく、コピー元と紐付けたり 特定の値を上書きしたりできる Prototype コピーを作成する 参考:Refactoring.Guru 🐣 一覧 <> Prototype clone():Prototype ConcretePrototype field clone():Prototype 実装

Slide 41

Slide 41 text

41 構造🏛

Slide 42

Slide 42 text

42 状況と問題 ● 2種類のオブジェクト「製品」と「箱」が あるとする ● 箱には、製品や、より小さい箱を入れられる ● 最終的に、一つの大きな箱に入った製品の 合計金額をどうやって計算する? Composite ツリー構造を表現する 一覧 参考:Refactoring.Guru 🏛

Slide 43

Slide 43 text

解決方法 ● LeafとCompositeはどちらも 共通のインターフェースを実装する ● Leafは自分が何をするべきか 知っている ● Compositeはchildrenに処理を 委任する 43 Composite ツリー構造を表現する 一覧 参考:Refactoring.Guru 🏛 <> Component execute() Composite children:Component[] add(Component) remove(Component) getChildren():Component[] execute() 実装 Leaf execute()

Slide 44

Slide 44 text

44 状況と問題 ● 例えば、システム資源を大量に消費するオブジェクトがある ○ データベース ○ 外部のライブラリ ● 遅延初期化のようなテクニックを使う場合、あちこちに似たような処理を書 くことになる ● 処理の前後でログ出力をする場合なども同様 Proxy オブジェクトへのアクセスの前後に処理を行う 一覧 参考:Refactoring.Guru 🏛

Slide 45

Slide 45 text

45 解決方法 ● 元のオブジェクトと同じ インターフェースを持つProxyクラス ● Proxyクラスはリクエストを受けると 必要な処理を行って、元のオブジェクトに 処理を移譲する Proxy オブジェクトへのアクセスの前後に処理を行う 一覧 <> ServiceInterface operation() Proxy realService operation() 実装 Service operation() 参考:Refactoring.Guru 所有 🏛

Slide 46

Slide 46 text

46 振る舞い🕺

Slide 47

Slide 47 text

47 状況と問題 ● 配列やコレクションはよく使う ● 一つずつ取り出すのは自然な要求 ● コレクションの構造は様々 ● 「取り出し方」を毎回実装するのはとても手間がかかる ● 要素を扱う側にとって、取り出される順番には興味がない Iterator たくさんあるものの中から一つずつ取り出す 一覧 参考:Refactoring.Guru 🕺

Slide 48

Slide 48 text

48 解決方法 ● 「取り出し方」をIteratorクラスに抽出する ● 使う側は、コレクションの構造を気にせず インターフェースを通して要素を取得する ● ConcreteIteratorを必要に応じて作る ○ 異なるコレクション ○ 異なる探索方法 Iterator たくさんあるものの中から一つずつ取り出す 一覧 <> Iterator getNext() hasMore():bool ConcreteIterator collection getNext() hasMore():bool 実装 参考:Refactoring.Guru 🕺

Slide 49

Slide 49 text

49 状況と問題 ● オブジェクトが状態を持つのは よくあるパターン ● ある状態から別の状態に遷移したり 状態によって処理を切り替える ● if文で実現しようとすると 容易に複雑化する State 状態によって振る舞いを替える 一覧 参考:Refactoring.Guru 🕺

Slide 50

Slide 50 text

50 解決方法 ● 一つの状態ごとに一つのクラスを作り、 状態固有の振る舞いを抽出する ● コンテキストと呼ばれる元々のオブジェクトが、 Stateへの参照を持ち、Stateに状態関連の作業を 委任する ● 特定のState同士はお互いの存在を知っている State 状態によって振る舞いを替える 一覧 参考:Refactoring.Guru <> State render() publish() 実装 Draft document:Document render() publish() Document state:State render() publish() changeState() 所有 🕺

Slide 51

Slide 51 text

51 ● デザインパターンを使ってうまく設計されているソースコードを 読むのがいちばん ● 各パターンの解説を読んだ後に、Javaの実装を読んだりすると 理解が深まるかも ● 自分で実装してみるとなお良し より深く学ぶには

Slide 52

Slide 52 text

52 Design Patterns 15 Years Later: An Interview with Erich Gamma, Richard Helm, and Ralph Johnson GoF本の出版から15年後の2009年に行われた、著者らへのインタビュー この中で、今デザインパターンを再編するなら、という話題が出た 補足:15年後のデザインパターン

Slide 53

Slide 53 text

53 (記事から抜粋) ● Interpreter と Flyweight は、他のパターンとは全く異なる性質を持つ ため、「その他」という別のカテゴリに移動 ● Factory Method は Factory に一般化 ● パターンは「コア」「生成」「周辺」「その他」に分類する ○ 重要なパターンを強調し、あまり使用されないパターンと区別するた め 補足:15年後のデザインパターン

Slide 54

Slide 54 text

54 継続 ● Abstract Factory ● Builder ● Command ● Composite ● Decorator ● Facade ● Flywight ● Interpreter 新旧パターン比較 ● Iterator ● Mediator ● Prototype ● Proxy ● State ● Strategy ● Template Method ● Visitor 新規 ● Dependency Injection ● Extension Object ● Factory※ ● Null Object ● Type Object 削除 ● Adopter ● Bridge ● Chain of Responsibility ● Factory Method※ ● Memento ● Observer ● Singleton ※Factory MethodはFactoryに一般化

Slide 55

Slide 55 text

55 コア ● Command ● Composite ● Facade ● Iterator ● Proxy ● Strategy ● State ● Template Method 新パターン一覧( 21種) 生成 ● Builder ● Dependency Injection ● Factory ● Prototype 周辺 ● Abstract Factory ● Decorator ● Extension Object ● Mediator ● Null Object ● Type Object ● Visitor その他 ● Flyweight ● Interpreter

Slide 56

Slide 56 text

● デザインパターンとは、ソフトウェア設計における問題に対して、よく使わ れる解決方法をまとめたもの ● デザインパターンは時代背景に内容がマッチして、広く普及した ● 現代においても技術的に重要だし、チーム内の意思疎通にも有用 ● 状況、問題、解決方法を理解して、適したパターンを選択することが重要 56 まとめ

Slide 57

Slide 57 text

57 ● リファクタリング ● 自動テスト リファクタリングのゴールとして、デザインパターンを 適用することを目指す リファクタリングを支える自動テスト 次に学ぶとよいもの

Slide 58

Slide 58 text

58 参考資料 ● Refactoring.Guru(Webサイト) ● fukabori.fm #48 #49(ポッドキャスト)