Slide 1

Slide 1 text

第一部 クラスの使い方 2025/2/27 社内勉強会 オブジェクト指向入門 1

Slide 2

Slide 2 text

今日のテーマ 2 simple, small

Slide 3

Slide 3 text

3 はじめに

Slide 4

Slide 4 text

4 ● 人類は様々な考え方や方法論を生 み出し、バグと戦ってきた ● すべてはバグを殲滅するため 人類の (システム開発の) 歴史はバグとの戦い

Slide 5

Slide 5 text

5 戦いの中で人類が 手に入れた武器のひとつ ● オブジェクト指向 ● およびその基礎となるクラス

Slide 6

Slide 6 text

6 オブジェクト指向 およびその基礎となるクラス 🗡🛡⚔🏹🔫

Slide 7

Slide 7 text

7 ● オブジェクト指向/クラスってなに? ● 面倒だから/難しいから使いたくない という人に ● オブジェクト指向の良さを知ってもらう ● クラスを使って実装したくなってもらう ことを目指す 想定読者とねらい

Slide 8

Slide 8 text

8 ● サンプルプログラムはJavaで書いています ○ 言語によらない内容なのでJavaを知らなくても大丈夫 ● 説明のために簡略化している場合があります 前置き

Slide 9

Slide 9 text

9 オブジェクト指向とは?

Slide 10

Slide 10 text

10 オブジェクトとは、プログラミング視点ではデータ構造とその専属手続きを一 つにまとめたものを(中略)指している。(中略)オブジェクト間の相互作用を 重視して、ソフトウェア全体を構築しようとする考え方がオブジェクト指向で ある。 Wikipediaより オブジェクト指向とは?

Slide 11

Slide 11 text

11 ● オブジェクトとは、数値などのデータと、それらを扱うロジックをひとまとめ にしたもの ● オブジェクト同士を連携させてシステム全体を構築する考え方を オブジェクト指向という ※オブジェクト≒クラス オブジェクト指向とは?(意訳)

Slide 12

Slide 12 text

例えばこんなかんじ: Moneyクラス 12

Slide 13

Slide 13 text

例えばこんなかんじ: Moneyクラス 13 金額を表すデータ 金額データを扱う ロジック

Slide 14

Slide 14 text

14 データとロジックを ひとまとめにして、 それを組み合わせる オブジェクト指向とは

Slide 15

Slide 15 text

15 戦いの中で人類が 手に入れた武器のひとつ ● オブジェクト指向 ● およびその基礎となるクラス

Slide 16

Slide 16 text

16 オブジェクト指向が なぜバグに有効なのか? データとロジックをひとまとめにする

Slide 17

Slide 17 text

17 そもそも、バグはなぜ発生する?

Slide 18

Slide 18 text

18 人間の 1. 勘違い 2. 考慮もれ これらはプログラムの「複雑さ」「大きさ」 に起因する そもそも、バグはなぜ発生する?

Slide 19

Slide 19 text

19 ● if文の範囲を把握しづらい ○ 勘違いしやすい ● 処理のパターンが多い ○ 考慮もれに繋がる 例えば: 何重にもネストした if文

Slide 20

Slide 20 text

20 ● if文の範囲を把握しづらい ○ 勘違いしやすい ● 処理のパターンが多い ○ 考慮もれに繋がる 例えば: 何重にもネストした if文 金額が1000円以上なら割引する、 という処理を追加したい場合 どこに書く?

Slide 21

Slide 21 text

21 ● どこで何が行われているか 把握できない ○ 勘違い ○ 修正もれ(考慮もれ) 例えば:長〜い関数

Slide 22

Slide 22 text

22 ● どこで何が行われているか 把握できない ○ 勘違い ○ 修正もれ(考慮もれ) 例えば:長〜い関数 ここで定義された変数が ここで使われていたら?

Slide 23

Slide 23 text

23 ● そこでオブジェクト指向 ● 例えば「金額」クラス プログラムの 「複雑さ」「大きさ」 を抑制したい

Slide 24

Slide 24 text

プログラムの 「複雑さ」「大きさ」 を抑制したい 24 金額に関するデータと 金額に関する処理を 切り出してまとめる

Slide 25

Slide 25 text

25 複雑で大きい プログラムを 意味的にまとまった 小さいクラスに分割し、 クラスの中に 複雑さを閉じ込める オブジェクト指向が示した解決策

Slide 26

Slide 26 text

26 複雑で大きいプログラムを 意味的にまとまった 小さいクラスに分割し、 クラスの中に複雑さを閉じ込める おや?

Slide 27

Slide 27 text

27 ● 無秩序な複雑さから 複雑さは変わらない? 複雑で大きい プログラム

Slide 28

Slide 28 text

28 ● 無秩序な複雑さからコントロールされた複雑さへ 複雑さは変わらない? 抽出 複雑な 金額クラス 複雑で大きい (金額以外の) プログラム

Slide 29

Slide 29 text

29 同じ100行の処理でも、、、 金額の計算をしてたり 在庫数を調整してたり よくわかんない よくわかんないけど、 とにかく金額の計算をしている A B

Slide 30

Slide 30 text

30 同じ100行の処理でも、、、 金額の計算をしてたり 在庫数を調整してたり よくわかんない よくわかんないけど、 とにかく金額の計算をしている A B こっちの方が 安心じゃないですか?

Slide 31

Slide 31 text

31 同じ100行の処理でも、、、 金額の計算をしてたり 在庫数を調整してたり よくわかんない よくわかんないけど、 とにかく金額の計算をしている A B こっちの方が 安心じゃないですか? =同時に気にするべき  ことが少ない

Slide 32

Slide 32 text

32 同じ100行の処理でも、、、 金額の計算をしてたり 在庫数を調整してたり よくわかんない よくわかんないけど、 とにかく金額の計算をしている A B こっちの方が 安心じゃないですか? =同時に気にするべき  ことが少ない =コントロールされた  複雑さ

Slide 33

Slide 33 text

抽出 複雑な 金額クラス 複雑で大きい (金額以外の) プログラム 33 オブジェクト指向が提供する単純さ ここに現れる金額の処理は 単純になる この金額の処理は複雑だが コントロールされている

Slide 34

Slide 34 text

34 ● 使う側の単純さ オブジェクト指向が提供する単純さ

Slide 35

Slide 35 text

35 ● 使う側の単純さ オブジェクト指向が提供する単純さ 税率が何%とか、税額の計算方法を 考えなくてよい 税率を変更しても、計算方法を変えても、 使う側に全く影響がない

Slide 36

Slide 36 text

36 複雑で大きい プログラムを 意味的にまとまった 小さいクラスに分割し、 クラスの中に 複雑さを閉じ込めて 使う側を単純にする オブジェクト指向がバグに有効な理由

Slide 37

Slide 37 text

37 simple, small 出ました✌

Slide 38

Slide 38 text

38 ● バグは「複雑さ」と「大きさ」から生まれる ● オブジェクト指向はプログラムの複雑さを 小さいクラスの中に閉じ込めて、使う側の単純さを担保する考え方 ここまでのまとめ

Slide 39

Slide 39 text

39 どうやって simple, small を 実現するの?

Slide 40

Slide 40 text

40 1. 値オブジェクト ○ 値を扱うための専用クラス 2. コレクションオブジェクト(ファーストクラスコレクション) ○ コレクションを扱うための専用クラス 2つのテクニック

Slide 41

Slide 41 text

41 1. 値オブジェクト ○ 値を扱うための専用クラス 2. コレクションオブジェクト(ファーストクラスコレクション) ○ コレクションを扱うための専用クラス 2つのテクニック

Slide 42

Slide 42 text

42 ● 数量や金額などを表現したいとき、どうしますか? ● int や BigDecimal などの基本データ型を使うことが多い 1. 値オブジェクト - 基本データ型 の落とし穴 int, BigDecimal, String, LocalDate など はじめから用意されている型

Slide 43

Slide 43 text

43 ● int はマイナス21億からプラス21億までの整数、 BigDecimal は実質無限の範囲の数値を表現できる 1. 値オブジェクト - 基本データ型 の落とし穴 int, BigDecimal, String, LocalDate など はじめから用意されている型

Slide 44

Slide 44 text

44 ● int はマイナス21億からプラス21億までの整数、 BigDecimal は実質無限の範囲の数値を表現できる 1. 値オブジェクト - 基本データ型 の落とし穴 int, BigDecimal, String, LocalDate など はじめから用意されている型 業務上の異常値を表現できてしまうと、 システムが複雑化し、バグが混入する原因になる その範囲、 本当に必要?

Slide 45

Slide 45 text

45 Quantityクラスを使う限り 数値が1〜100であると 保証される 値の範囲を 制限した例

Slide 46

Slide 46 text

46 ● 値を上書きする(できる)=複雑 ● その瞬間にどんな値になっているか、処理を追わないとわからない 1. 値オブジェクト - 不変にする 悪い例

Slide 47

Slide 47 text

47 ● 値を上書きする(できる)=複雑 ● その瞬間にどんな値になっているか、処理を追わないとわからない 1. 値オブジェクト - 不変にする 悪い例 3,000円 1,000円

Slide 48

Slide 48 text

48 ● 値を上書きさせず、変数を分ける=単純 ● 一つひとつのオブジェクトの用途を限定する 1. 値オブジェクト - 不変にする 良い例

Slide 49

Slide 49 text

49 不変にするやり方: 1. コンストラクタで値をすべて設定する 2. 値を変更するメソッド(setterメソッド)を作らない 3. 別の値が必要であれば、別のオブジェクトをつくる 1. 値オブジェクト - 不変にする

Slide 50

Slide 50 text

50 不変な 値オブジェクトの例 1. コンストラクタで 値を全て設定する 2. 値を変更するメソッド (setterメソッド)を作らない 3. 別の値が必要であれば、 別のオブジェクトを作る

Slide 51

Slide 51 text

51 ● 基本データ型だけで書いたプログラムは、思わぬバグをうむ ● 例えば、単価と数量をかけて金額を求める処理 1. 値オブジェクト - 型を使って意図を明確にする

Slide 52

Slide 52 text

52 ● 基本データ型だけで書いたプログラムは、思わぬバグをうむ ● 例えば、単価と数量をかけて金額を求める処理 1. 値オブジェクト - 型を使って意図を明確にする エラーにならず実行できてバグ発生

Slide 53

Slide 53 text

53 ● 基本データ型だけで書いたプログラムは、思わぬバグをうむ ● 例えば、単価と数量をかけて金額を求める処理 1. 値オブジェクト - 型を使って意図を明確にする

Slide 54

Slide 54 text

54 ● 基本データ型だけで書いたプログラムは、思わぬバグをうむ ● 例えば、単価と数量をかけて金額を求める処理 1. 値オブジェクト - 型を使って意図を明確にする 実行前にエラーに気づく

Slide 55

Slide 55 text

55 1. 値オブジェクト ○ 値を扱うための専用クラス 2. コレクションオブジェクト(ファーストクラスコレクション) ○ コレクションを扱うための専用クラス 2つのテクニック

Slide 56

Slide 56 text

56 配列やコレクションを使おうとすると、以下のような処理が頻出する 1. for 文などループ処理のロジック 2. 配列やコレクションの要素の数が変化する(可能性がある) 3. 個々の要素の内容が変化する(可能性がある) 4. ゼロ件の場合の処理 5. 要素の最大件数の制限 2. コレクションオブジェクト -  配列やコレクションはコードを複雑にする このようなコードがあちこちに散らばると、 プログラムが複雑になりがち

Slide 57

Slide 57 text

57 ● 考え方は値オブジェクトと同じ ● コレクション型の変数を 1つだけ持った専用クラス ● コレクションを操作する ロジックをすべて集める ○ 追加、削除、カウント、 特定条件の絞り込み、etc. 2. コレクションオブジェクト -  コレクションを扱うための専用クラス

Slide 58

Slide 58 text

58 ● 値オブジェクトと同様、できるだけ不変にする 不変にするやり方: 1. コレクション操作のロジックをコレクションオブジェクトに移動する 2. コレクション操作の結果も同じ型のコレクションオブジェクトとして返す 3. コレクションを不変にして外部に渡す 2. コレクションオブジェクト - 不変にする

Slide 59

Slide 59 text

59 ● コレクション変数をそのまま返すメソッドを用意しない ○ クラスの外部でコレクションを操作できてしまう 2. コレクションオブジェクト - 不変にする 悪い例 1. コレクション操作のロジックをコレクションオブジェクトに移動する 2. コレクション操作の結果も同じ型のコレクションオブジェクトとして返す 3. コレクションを不変にして外部に渡す

Slide 60

Slide 60 text

60 ● 外部でやりたい操作を、クラスに集められないか検討する ● 操作の結果を同じ型のコレクションオブジェクトとして返す 2. コレクションオブジェクト - 不変にする 良い例 1. コレクション操作のロジックをコレクションオブジェクトに移動する 2. コレクション操作の結果も同じ型のコレクションオブジェクトとして返す 3. コレクションを不変にして外部に渡す

Slide 61

Slide 61 text

61 ● どうしてもコレクションを渡す必要がある場合、 変更できないコレクションを返す 2. コレクションオブジェクト - 不変にする 良い例 1. コレクション操作のロジックをコレクションオブジェクトに移動する 2. コレクション操作の結果も同じ型のコレクションオブジェクトとして返す 3. コレクションを不変にして外部に渡す

Slide 62

Slide 62 text

62 1. 値オブジェクト 2. コレクションオブジェクト(ファーストクラスコレクション) 2つのテクニック

Slide 63

Slide 63 text

63 1. 値オブジェクト 2. コレクションオブジェクト(ファーストクラスコレクション) → カプセル化 ● データとロジックをひとまとめのクラスにする ● データの操作は、クラス内部のロジックで行う ● クラスの外部からデータを操作させない ● 内部に複雑さを閉じ込めて、外部からの利用を単純にする 2つのテクニック

Slide 64

Slide 64 text

64 ● オブジェクト指向プログラミングの3大要素 a. カプセル化 b. ポリモーフィズム c. 継承 ● SOLID原則 ● デザインパターン ● ドメイン駆動設計 オブジェクト指向を使いこなす次のステップ

Slide 65

Slide 65 text

65 参考文献

Slide 66

Slide 66 text

これだけ覚えて帰ってください 66 simple, small

Slide 67

Slide 67 text

67 Appendix

Slide 68

Slide 68 text

68 ● カプセル化 ● ポリモーフィズム ○ 別々のクラスを同じように扱う ● 継承 ○ 同系統のクラスを分類する オブジェクト指向プログラミングの3大要素

Slide 69

Slide 69 text

69 保守性の高い設計の指針 1. 単一責任の原則 Single-responsibility principle 2. 開放閉鎖の原則 Open/closed principle 3. リスコフの置換原則 Liskov substitution principle 4. インターフェース分離の原則 Interface segregation principle 5. 依存性逆転の原則 Dependency inversion principle SOLID原則

Slide 70

Slide 70 text

70 ● ソフトウェア開発で頻出する設計のパターン集 ○ Strategy パターン ○ Builder パターン etc. ● Iterator パターンが最も身近だと思う ○ Javaの拡張 for 文(for (Foo foo : barList))は これで実装されている ● Composite パターンもイメージしやすいかも ○ ファイルシステムのフォルダとファイルの関係はこれ デザインパターン