Slide 1

Slide 1 text

【連続講座1 】デザインパターンを学 び、ソフトウェア設計に生かそう Adapter ・Factory Method ・Singleton パーソルクロステクノロジー株式会社 エンジニアリング事業管掌 設計統括本部 第2 電子・制御設計本部 第1 設計部 4G  阿部耕二

Slide 2

Slide 2 text

目次 自己紹介 開発環境構築 設計、してますか? 良い設計とはどういう設計か? デザインパターンの学び方のススメ Adapter Factory Method Singleton 参考資料 2

Slide 3

Slide 3 text

自己紹介 名前: 阿部 耕二(あべ こうじ) 所属: パーソルクロステクノロジー株式会社 エンジニアリング事業管掌 設計統括本部 第2 電子・制御設計本部 第1 設計部 4G 医療機器の組込みソフトウェア開発。C 言語。 趣味: 宇宙開発(リーマンサットプロジェクト広報メンバー) LAPRAS ポートフォリオ: https://lapras.com/public/k-abe Twitter: @juraruming 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 3

Slide 4

Slide 4 text

開発環境構築 サンプルコードのコンパイル、実行にjava (JDK )のインストールが 必要です。 下記のページなどを参照し、ご自分のPC のOS に合わせてインストー ルしてください。 【2024 年版】Java JDK のインストール方法(Windows & Mac 対応) 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 4

Slide 5

Slide 5 text

つぎのコマンド実行でバージョンが表示されていればOK です。 私はつぎのバージョンで確認しました。 $ javac -version javac 17.0.8 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 5

Slide 6

Slide 6 text

サンプルプログラムのビルド方法 サンプルプログラムのディレクトリ(Main.java があるディレクトリ) に移動しつぎのコマンドでビルドする。 $ javac Main.java プログラムの実行はつぎのコマンドで行う。 $ java Main 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 6

Slide 7

Slide 7 text

講座のGitHub リポジトリ https://github.com/grace2riku/design_pattern_lesson 今回の講座のディレクトリ https://github.com/grace2riku/design_pattern_lesson/tree/main/le sson_1 参考資料1  ソースコードのダウンロード先 Java 言語で学ぶデザインパターン入門 第3 版 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 7

Slide 8

Slide 8 text

設計、してますか? 設計してますか? 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 8

Slide 9

Slide 9 text

こんなことになってませんか? おばあちゃんのプログラミン グ教室(ばあプロ)As A Service @Pythonist19 より引 用 https://x.com/Pythonist19/sta tus/1845794841269055543 【連続講座1 】デザインパターンを学び、ソフトウェ 9

Slide 10

Slide 10 text

設計の重要性 要素技術にフォーカスしがち、注力しがち → 再利用しにくい、変更しにくいソフトウェアのできあがり 他社との違い・自社の強みを活かしていないソフトウェアが誕生 ビジネス競争力の低下 → 技術的負債に!!! 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 10

Slide 11

Slide 11 text

設計の難しさ お手本がない。 対象製品、装置で個別の事情がある。 製品の特性、開発期間、製品寿命、etc Web システムと組込みソフトウェア 自動車と医療機器では設計思想も違ってきそう。 自動車:変化が早い、開発期間短い、大量生産 医療機器:開発期間長い印象、少量生産 ソフトウェアは柔軟で、自由度が高すぎる。 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 11

Slide 12

Slide 12 text

対象システム、装置に応じた設計手法を学び、身につける そしてチームメンバーと共通認識を持ちたい。 デザインパターン 設計の古典、教科書ともいえる。 プログラミング言語の中に取り込まれて、見えない。    → 学ぶことは意味があると考える。  → 開発時のコミュニケーションに活用する。  ここは「xxx 」パターンを適用してみようか? 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 12

Slide 13

Slide 13 text

良い設計とはどういう設計か? 良い設計のために個人的に大事だと思うキーワード 1. 凝集度 2. 結合度 3. 関心の分離 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 13

Slide 14

Slide 14 text

1. 凝集度 関心ごとの集まり 凝集度が高い方(関心ごとが一箇所に集まっている)が良い設計と 言われる 1 つの目的・責務になっていることが望ましい 例)料理を作る場面 キッチン周りには料理に必要な設備が配置される(水道、冷蔵庫、コ ンロ、食器棚、その他) 。 →必要なものが凝集している状態 キッチン周りに洗濯機はいらない。料理をつくるという関心ごとに洗 濯機は不要。 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 14

Slide 15

Slide 15 text

2. 結合度 他のモジュールとの関連の度合い 結合度が低い方(他のモジュールとの関連が少ない方)が良い設計 と言われる あるファイルのグローバル変数が他の複数のファイルから参照され ている状況は結合度が低い。 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 15

Slide 16

Slide 16 text

3. 関心の分離 関心ごとを分離し、境界を設ける 関心の分離が表現されている例としてOSI 参照モデル・TCP/IP に注 目する 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 画像引用元 OSI 参照モデルとは?TCP/IP との違いを図解で解説 “ “ 16

Slide 17

Slide 17 text

役割ごとに階層が分かれている 下の層がハードウェアに近い 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 17

Slide 18

Slide 18 text

【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 18

Slide 19

Slide 19 text

上の階層ほど抽象的。目的・知識・Why 。 下の階層ほど具体的。目的を達成する手段・How 。 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 19

Slide 20

Slide 20 text

デザインパターンの学び方のススメ デザインパターンがどんな課題を解決できて、どのような構成なの かイメージを捉える 参考資料1 の章題はデザインパターンを短く端的に表現してい る。 参考資料3 では各デザインパターンを短く、わかりやすく解説し てくれている。 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 20

Slide 21

Slide 21 text

クラス図とコードの写経をセットで行う コードだけ見ていても各クラスの全体の関係性がわかりずらい。 クラス図だけを見ていても抽象的で本当に動くのか疑問がわく。 設計図(抽象)  ⇔ コード(具体的)の世界を行ったり来たり することで整理できたり、気づきが得られることがあると思う。 今回のサンプルコードはJava 。デザインパターンの考え方・実装 は特定のプログラミング言語に限定されないと思うので自分が得 意な言語で実装してみると理解が深まると思う。 参考資料2 ではC# 、 C++ 、 Go 、 Java 、 PHP 、 Python 、 Ruby 、 Rust 、 Swift 、 TypeScript で実装例を提示してくれている。 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 21

Slide 22

Slide 22 text

デザインパターンに登場するクラスの相互関係に注目する 複数のクラスが関係してパターンを構成している。各クラスの役 割、関係性に注目する。 デザインパターンがどのように振る舞うか? に加えて、デザインパタ ーンはどのように使われるか? の視点も大事だと思う。 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 22

Slide 23

Slide 23 text

Adapter 参考資料1  章題  【一皮かぶせて再利用】 すでに提供されているものがそのまま使えないときに、必要な形に 変換してから利用する パソコンのAC アダプター(直流12V で動く製品とする) 提供されているもの -> 交流100V AC アダプタが変換するもの -> 交流を直流に変換。交流100V をパソ コンが動作する12V に変換する 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 23

Slide 24

Slide 24 text

例)Apple AC アダプタ Apple のAC アダプタの構造 【連続講座1 】デザインパターンを学び、ソフトウェ 24

Slide 25

Slide 25 text

アダプタのプラグ部分は取り 外し可能で海外でも使えるよ うに考慮されている(設計し た)と予想できる。 調べてみたらApple ワールド トラベルアダプタキットなる 製品があり、7 種類のプラグ形 状があることがわかった。 プラグ部分を容易に変更でき る構造になっている。 このように容易に変更できる 構造をソフトウェアにも持ち 込みたい!!! 【連続講座1 】デザインパターンを学び、ソフトウェ 25

Slide 26

Slide 26 text

Adapter パターンのサンプルプログラム例 テーマ:既にある加算に下限・上限の制限を追加する。 例えば、下限O 、上限100 のときに加算の計算結果が上限値を超えた ら上限値の100 にする。 加算の計算結果が下限値を下回ったら下限値の0 に固定する。 表 電源の比喩とサンプルプログラムの対応関係 \ 電源の比喩 サンプルプログラム 提供されているもの 交流100 ボルト Calc クラス 変換装置 アダプター LimitCalc クラス 必要なもの 直流12 ボルト Limiter クラス 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 26

Slide 27

Slide 27 text

サンプルプログラムのクラス図 サンプルプログラムのディレク トリ https://github.com/grace2riku /design_pattern_lesson/tree/ main/lesson_1/adapter/LimitC alc 【連続講座1 】デザインパターンを学び、ソフトウェ 27

Slide 28

Slide 28 text

サンプルプログラムのビルド方法 サンプルプログラムのディレクトリ(Main.java があるディレクトリ) に移動しつぎのコマンドでビルドする。 $ javac Main.java プログラムの実行はつぎのコマンドで行う。 $ java Main 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 28

Slide 29

Slide 29 text

Adapter サンプルプログラムの実行結果 $ java Main /***** Calc *****/ ret_val(0 + 101) = 101 ret_val(0 + (-1)) = -1 /***** LimitCalc *****/ limit min value = 0/limit max value = 100 ret_val(0 + 50) = 50 ret_val(0 + 100) = 100 ret_val(0 + 101) = 100 ret_val(0 + 0) = 0 ret_val(0 + (-1)) = 0 Calc はリミットなしの加算。LimitCalc はリミットありの加算 LimintCalc の下限は0 、上限は100 に設定 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 29

Slide 30

Slide 30 text

Adapter パターンの登場人物を 抽象的に書く 【連続講座1 】デザインパターンを学び、ソフトウェ 30

Slide 31

Slide 31 text

Adapter パターンの使いところ 既にあるクラスを変更せずに再利用できる 変動部(Target )をバリエーション化すれば素早く多くのバリエー ションに対応できる(競合他社との差別化) 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 31

Slide 32

Slide 32 text

Factory Method 参考資料1  章題  【インスタンス作成をサブクラスにまかせる】 インスタンス作成するクラスを用意する(あちこちでインスタン作 成せずに、インスタンス作成役に任せる) 。 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 32

Slide 33

Slide 33 text

サンプルプログラムのクラス図 サンプルプログラムのディレク トリ https://github.com/grace2riku /design_pattern_lesson/tree/ main/lesson_1/Factory_Meth od 【連続講座1 】デザインパターンを学び、ソフトウェ 33

Slide 34

Slide 34 text

サンプルプログラムのビルド方法 サンプルプログラムのディレクトリ(Main.java があるディレクトリ) に移動しつぎのコマンドでビルドする。 $ javac Main.java プログラムの実行はつぎのコマンドで行う。 $ java Main 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 34

Slide 35

Slide 35 text

Adapter サンプルプログラムの実行結果 $ java Main /***** IDCardのFactory *****/ Hiroshi Yukiのカードを作ります。 IDCard [owner=Hiroshi Yuki]を登録しました。 Tomuraのカードを作ります。 IDCard [owner=Tomura]を登録しました。 Hanako Satoのカードを作ります。 IDCard [owner=Hanako Sato]を登録しました。 IDCard [owner=Hiroshi Yuki]を使います。 IDCard [owner=Tomura]を使います。 IDCard [owner=Hanako Sato]を使います。 /***** BussinesCardのFactory *****/ Koji Abeの名刺を作ります。 BusinessCard [owner=Koji Abe]を登録しました。 Riku Abeの名刺を作ります。 BusinessCard [owner=Riku Abe]を登録しました。 BusinessCard [owner=Koji Abe]を使います。 BusinessCard [owner=Riku Abe]を使います。 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 35

Slide 36

Slide 36 text

Adapter サンプルプログラムの実行結果 IDCard のFactory は参考資料1 のサンプルコード BussinesCard のFactory は今回追加した名刺のFactory と商品の名刺 フレームワークのパッケージ内は変更せず、具体的な工場・商品の 追加で新しい種類のインスタンス作成ができた 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 36

Slide 37

Slide 37 text

Factory_Method パターンの登 場人物を抽象的に書く 【連続講座1 】デザインパターンを学び、ソフトウェ 37

Slide 38

Slide 38 text

Factory_Method パターンの使いところ インスタンス生成を専門にするクラスを用意することでコードを整 理できる 工場に使えばインスタンスを作成できる。 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 38

Slide 39

Slide 39 text

static Factory Method インスタンス生成のためのクラスメソッド(クラスをインスタンス 化しなくても呼び出し可能なメソッド) GoF のFactory Method パターン違うが、インスタンス生成でよく使 われる手法。 (個人的に開発シーンでFactory と呼ぶときはこちらを指すことが 多いと思っている) 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 参考資料1 より引用 “ “ 39

Slide 40

Slide 40 text

static Factory Method java のAPI のstatic Factory Method として参考資料1 で紹介されてい るものは以下のとおり java.security.SecureRandom のgetInstance メソッド java.util.List のof メソッド java.util.Arrays のasList メソッド java.lang.String のvalueOf メソッド java.time.Instant のnow メソッド 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 40

Slide 41

Slide 41 text

Singleton 参考資料1  章題  【たった1 つのインスタンス】 システムにインスタンスが1 つしかないことを保証する。 プログラマがインスタンスを1 つしかつくらないように気を付ける のではなく、インスタンスが1 つしかつくれないような仕組みにす る。 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 41

Slide 42

Slide 42 text

システムの中で複数あると困りそうなもの プリンタのジョブ管理 デバイスドライバ Factory Method のFactory 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 42

Slide 43

Slide 43 text

Singleton パターンのサンプルプログラム例 テーマ:システムに1 つのものを対象にする。今回はプリンタのジョブ 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 43

Slide 44

Slide 44 text

サンプルプログラムのクラス図 サンプルプログラムのディレク トリ https://github.com/grace2riku /design_pattern_lesson/tree/ main/lesson_1/Singleton/Prin tJob 【連続講座1 】デザインパターンを学び、ソフトウェ 44

Slide 45

Slide 45 text

サンプルプログラムのビルド方法 サンプルプログラムのディレクトリ(Main.java があるディレクトリ) に移動しつぎのコマンドでビルドする。 $ javac Main.java プログラムの実行はつぎのコマンドで行う。 $ java Main 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 45

Slide 46

Slide 46 text

Singleton サンプルプログラムの実行結果 $ java Main Start. インスタンスを生成しました。 printjob1とprintjob2は同じインスタンスです。 End. 「インスタンスを生成しました。 」のメッセージが1 つなので、イン スタンスは1 つのみ生成されている。 getInstance メソッドで取得したインスタンスは同じことを確認でき た 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 46

Slide 47

Slide 47 text

Singleton パターンの使いところ インスタンスが1 つであることを保証したい時 組込みソフトウェアのデバイスドライバなど。 データベースのアクセス Factory Method のFactory (インスタンスを作成する工場はひと つでよいことが多いと思う) 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 47

Slide 48

Slide 48 text

おまけ:Singleton の実装を変更してみる サンプルコード: https://github.com/grace2riku/design_pattern_lesson/tree/main/less on_1/Singleton/PrintJob_2_1 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 48

Slide 49

Slide 49 text

ディレクトリ名:PrintJob_2_1 Singleton のインスタンス生成の実装を下記に変更(インスタンスが生 成済みかnull チェックするようにした) public class PrintJob { private static PrintJob printJob = null; private PrintJob() { System.out.println("インスタンスを生成しました。"); } public static PrintJob getInstance() { if (printJob == null) { printJob = new PrintJob(); } return printJob; } } 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 49

Slide 50

Slide 50 text

サンプルコード:PrintJob_2_1 を動かすとSingleton の動きが確認でき ます。 ・・・確認できますが、このコードには 考慮していないこと 呼び出し方にはよっては意図しない動作をする可能性 があります。 それは何でしょう? つぎのページを見ずに考えてみてくださいね 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 50

Slide 51

Slide 51 text

前ページの解答 マルチスレッド環境でgetInstance を実行すると異なるインスタンス を取得してしまう(Singleton でなくなる) 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 51

Slide 52

Slide 52 text

PrintJob_2_1 をマルチスレッドで実行するように変更したコード (PrintJob_2_2 )で動きを確かめてみる サンプルコード: https://github.com/grace2riku/design_pattern_lesson/tree/main/less on_1/Singleton/PrintJob_2_2 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 52

Slide 53

Slide 53 text

PrintJob_2_2 をコンパイル・実行するとつぎの結果になる。 Start End インスタンスを生成しました。 インスタンスを生成しました。 インスタンスを生成しました。 PrintJob B: obj = PrintJob@1151bbe3 PrintJob C: obj = PrintJob@7b63961c PrintJob A: obj = PrintJob@4230a45b 3 つインスタンスをつくっており、異なるインスタンスになってい る。 ※PC 環境によっては結果が異なるかもしれません。私のPC だと毎 回異なるインスタンスになりました。 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 53

Slide 54

Slide 54 text

何故、Singleton でなくなったのでしょうか? 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 54

Slide 55

Slide 55 text

Q. 何故、Singleton でなくなったのでしょうか? A. このメソッドの条件判断がマルチスレッドで実行されるため public static PrintJob getInstance() { if (printJob == null) { printJob = new PrintJob(); } return printJob; } 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 55

Slide 56

Slide 56 text

PrintJob_2_2 のコードでSingleton に対応する方法 インスタンス作成部分をマルチスレッド環境から呼び出されても唯一 のインスタンスを返すようにする。 参考資料1 に書かれていた手法を紹介する。 コード https://github.com/grace2riku/design_pattern_lesson/tree/main/less on_1/Singleton/PrintJob_2_3 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 56

Slide 57

Slide 57 text

synchronized を付加する public static synchronized PrintJob getInstance() { if (printJob == null) { printJob = new PrintJob(); } return printJob; } 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 57

Slide 58

Slide 58 text

PrintJob_2_3 (synchronized )の実行結果 $ java Main Start End インスタンスを生成しました。 PrintJob B: obj = PrintJob@386514c2 PrintJob A: obj = PrintJob@386514c2 PrintJob C: obj = PrintJob@386514c2 インスタンスが1 個だけ作成されており、Singleton 対応できている ことが確認できた。 PrintJob_2_1 のコードが基本形だと思う。 PrintJob_2_1 のコードをマルチスレッド環境で実行してもSingleton 対応できている。 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 58

Slide 59

Slide 59 text

このことから学べるポイント どう使われるか? 、どう使われる可能性があるか? 、を考慮して実装 者に任せるのではなく設計者が実装者に伝えるようにする。 スレッドセーフではない実装のまま進める場合は、ドキュメントに スレッドセーフではない旨を書いておいた方が良さそう。 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 59

Slide 60

Slide 60 text

参考資料 1. Java 言語で学ぶデザインパターン入門 第3 版 2. 直撃!デザインパターン 3. ぼくにもわかるデザインパターン 第2 章 GoF パターン大カタログ ~パターンがみるみる頭にしみこむ~ 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 60

Slide 61

Slide 61 text

ご清聴ありがとうございました 【連続講座1 】デザインパターンを学び、ソフトウェア設計に生かそう 61