だから僕は(クラス)設計をやめた 2025年 4 月 11 日 (金) PHPカンファレンス小田原2025 @stwile871 1
スタヰル (@stwile871) public const ZAYU_NO_MEI = '天然パーマに悪い奴はいない'; public const HOBBY = ['🥃', '#ztmy', 'JOJO💂']; public const HOME = '名古屋'; public const WORK = 'Software Engineer'; public const FAVORITE_ODAWARA = '🍢'; 2
タイトルに籠めた思い 3
タイトルに籠めた思い ● `◯◯アーキテクチャ` や `XX設計` が跋扈する現代 4
タイトルに籠めた思い ● `◯◯アーキテクチャ` や `XX設計` が跋扈する現代 ● 設計をあえてしない設計があっても良いんじゃないか 5
タイトルに籠めた思い ● `◯◯アーキテクチャ` や `XX設計` が跋扈する現代 ● 設計をあえてしない設計があっても良いんじゃないか 6
タイトルに籠めた思い ● `◯◯アーキテクチャ` や `XX設計` が跋扈する現代 ● 設計をあえてしない設計があっても良いんじゃないか 💡逆張りをしてみたくなッた!!!💡 7
なぜクラス設計をやめたのか? 8
なぜクラス設計をやめたのか? ● 設計したとして、正解があるわけじゃない 9
なぜクラス設計をやめたのか? ● 設計したとして、正解があるわけじゃない ● クラス設計しないときと比べて、コストがかかる 10
なぜクラス設計をやめたのか? ● 設計したとして、正解があるわけじゃない ● クラス設計しないときと比べて、コストがかかる ● クラス設計をする時間がなかったから😇 11
なぜクラス設計をやめたのか? ● 設計したとして、正解があるわけじゃない ● クラス設計しないときと比べて、コストがかかる ● クラス設計をする時間がなかったから😇 要件: 早く作って、早くフィードバックがほしい!! 12
なぜクラス設計をやめたのか? ● 設計したとして、正解があるわけじゃない ● クラス設計しないときと比べて、コストがかかる ● クラス設計をする時間がなかったから😇 要件: 早く作って、早くフィードバックがほしい!! 使われなかったらすぐ消してほしい!! 13
なぜクラス設計をやめたのか? ● 設計したとして、正解があるわけじゃない ● クラス設計しないときと比べて、コストがかかる ● クラス設計をする時間がなかったから😇 要件: 早く作って、早くフィードバックがほしい!! 使われなかったらすぐ消してほしい!! 14
クラス設計のコスト 15
クラス設計のコスト Ⅰ. 名前付けのコスト Ⅱ. モデリングのコスト 16
クラス設計のコスト Ⅰ. 名前付けのコスト Ⅱ. モデリングのコスト 17
名前付けはコストがかかる 18
名前付けはコストがかかる ● クラス名・ディレクトリ名を都度考えねばならない 19
名前付けはコストがかかる ● クラス名・ディレクトリ名を都度考えねばならない ● 命名手法が多様にあり、選び、決める必要がある 20
名前付けはコストがかかる ● クラス名・ディレクトリ名を都度考えねばならない ● 命名手法が多様にあり、選び、決める必要がある ● 名前付けに失敗した場合、修正コストがかかる 21
名前付けはコストがかかる ● クラス名・ディレクトリ名を都度考えねばならない ● 命名手法が多様にあり、選び、決める必要がある ● 名前付けに失敗した場合、修正コストがかかる 22
名前付けはコストがかかる 思ったより大変 ● クラス名・ディレクトリ名を都度考えねばならない ● 命名手法が多様にあり、選び、決める必要がある ● 名前付けに失敗した場合、修正コストがかかる 23
名前付けが重要な理由 24
名前付けが重要な理由 ● コードの大部分を占める 25
名前付けが重要な理由 ● コードの大部分を占める ● コードレビューで、4件に1件は命名に関する指摘 26
名前付けが重要な理由 ● コードの大部分を占める ● コードレビューで、4件に1件は命名に関する指摘 ● 最も重要なドキュメントの役割 27
名前付けが重要な理由 ● コードの大部分を占める ● コードレビューで、4件に1件は命名に関する指摘 ● 最も重要なドキュメントの役割 ● どんなドキュメントよりも正確 28
名前付けが重要な理由 ● コードの大部分を占める ● コードレビューで、4件に1件は命名に関する指摘 ● 最も重要なドキュメントの役割 ● どんなドキュメントよりも正確 ● ビーコンとして機能する 29
名前付けが重要な理由 ● コードの大部分を占める ● コードレビューで、4件に1件は命名に関する指摘 ● 最も重要なドキュメントの役割 ● どんなドキュメントよりも正確 ● ビーコンとして機能する ● 新たなコードを読むときに、コードの意味を理解する識別子 30
名前付けが重要な理由 31
名前付けが重要な理由 ● 表現力がある 32
名前付けが重要な理由 ● 表現力がある ● 何を表しているか読み手に明瞭 33
名前付けが重要な理由 ● 表現力がある ● 何を表しているか読み手に明瞭 ● シンプルである 34
名前付けが重要な理由 ● 表現力がある ● 何を表しているか読み手に明瞭 ● シンプルである ● 長すぎず短すぎない 35
名前付けが重要な理由 ● 表現力がある ● 何を表しているか読み手に明瞭 ● シンプルである ● 長すぎず短すぎない ● 予測可能である 36
名前付けが重要な理由 ● 表現力がある ● 何を表しているか読み手に明瞭 ● シンプルである ● 長すぎず短すぎない ● 予測可能である ● 知識を元に意味を予測し続けられる 37
クラス設計のコスト Ⅰ. 名前付けのコスト Ⅱ. モデリングのコスト 38
クラス設計のモデリング 39
クラス設計のモデリング ● デザインパターンに関する決定 40
クラス設計のモデリング ● デザインパターンに関する決定 ● 時にはデータモデリングが必要 生成AIで画像を作成したら循環参照していた 41
クラス設計のモデリング ● デザインパターンに関する決定 ● 時にはデータモデリングが必要 ● UMLを使ったADRの作成... 生成AIで画像を作成したら循環参照していた 42
クラス設計のモデリング ● デザインパターンに関する決定 ● 時にはデータモデリングが必要 ● UMLを使ったADRの作成... 生成AIで画像を作成したら循環参照していた ちゃんとやろうと思うと、それなりにコストがかかる 💸 43
クラス設計のモデリング n え え え え え ● 時にはデータモデリングが必要 せ ま り あ 間 時 ● UMLを使ったADRの作成... な そん ● デザインパターンに関する決定 生成AIで画像を作成したら循環参照していた ちゃんとやろうと思うと、それなりにコストがかかる 💸 44
だから僕は(クラス)設計をやめた 45
伏線回収 だから僕は(クラス)設計をやめた 46
伏線回収 だから僕は(クラス)設計をやめた じゃあどうしたか?を これから話します 47
具体的にどう開発したのか? 48
具体的にどう開発したのか? ● MVCでORMのレールに乗っかり、APIをつくる🚆 49
具体的にどう開発したのか? ● MVCでORMのレールに乗っかり、APIをつくる🚆 ● Controllerにベタ書き 50
具体的にどう開発したのか? ● MVCでORMのレールに乗っかり、APIをつくる🚆 ● Controllerにベタ書き ● 適切なサイズでprivate メソッドに切り分ける 51
具体的にどう開発したのか? ● MVCでORMのレールに乗っかり、APIをつくる🚆 ● Controllerにベタ書き ● 適切なサイズでprivate メソッドに切り分ける ● テストハーネスはしっかり囲う 52
具体的にどう開発したのか? ● MVCでORMのレールに乗っかり、APIをつくる🚆 ● Controllerにベタ書き ● 適切なサイズでprivate メソッドに切り分ける ● テストハーネスはしっかり囲う ● ディレクトリごと機能を消せる 53
具体的にどう開発したのか? ● MVCでORMのレールに乗っかり、APIをつくる🚆 ● Controllerにベタ書き ● 適切なサイズでprivate メソッドに切り分ける ● テストハーネスはしっかり囲う ● ディレクトリごと機能を消せる https://speakerdeck.com/stwile/fat-controller-haeka-guang-nofat-controlleran-nogaricontroller 54
クラス設計をやめた結果 55
クラス設計をやめた結果 Ⅰ. 動くものを触る時間が増えた Ⅱ. 品質に向き合う時間が増えた 56
クラス設計をやめた結果 Ⅰ. 動くものを触る時間が増えた Ⅱ. 品質に向き合う時間が増えた 57
動くものを触る時間が増えた 58
動くものを触る時間が増えた ソースコードの睨めっこ 59
動くものを触る時間が増えた ソースコードの睨めっこ 60
動くものを触る時間が増えた ソースコードの睨めっこ 動くソフトウェアと向き合う 61
動くものを触る時間が増えた ソースコードの睨めっこ 動くソフトウェアと向き合う 操作感やアクセシビリティなどの本物の体感 62
クラス設計をやめた結果 Ⅰ. 動くものを触る時間が増えた Ⅱ. 品質に向き合う時間が増えた 63
品質に向き合う時間が増えた 64
品質に向き合う時間が増えた QAとテストケースについて議論した miroの図 65
品質に向き合う時間が増えた ● テストケースと向き合う QAとテストケースについて議論した miroの図 66
品質に向き合う時間が増えた ● テストケースと向き合う ● CIに乗せるものを決定 QAとテストケースについて議論した miroの図 67
品質に向き合う時間が増えた ● テストケースと向き合う ● CIに乗せるものを決定 ● そもそも何を担保するか QAとテストケースについて議論した miroの図 68
品質に向き合う時間が増えた ● テストケースと向き合う ● CIに乗せるものを決定 ● そもそも何を担保するか 品質保証しないものの選 別 QAとテストケースについて議論した miroの図 69
品質に向き合う時間が増えた ● テストケースと向き合う ● CIに乗せるものを決定 ● そもそも何を担保するか 品質保証しないものの選 別 QAとテストケースについて議論した miroの図 すべてを保証することは現実的ではない 70
とはいえ、クラス設計はしたい 71
とはいえ、クラス設計はしたい するべき時が来る 72
意味のある、攻めのクラス設計 Ⅰ 73
意味のある、攻めのクラス設計 Ⅰ 再掲: QAとテストケースについて議論した miroの図 74
意味のある、攻めのクラス設計 Ⅰ 集計日付周りが不安 再掲: QAとテストケースについて議論した miroの図 75
意味のある、攻めのクラス設計 Ⅰ 集計日付周りが不安 ● 単体テストを書くために クラスに切り出す 再掲: QAとテストケースについて議論した miroの図 76
意味のある、攻めのクラス設計 Ⅰ 集計日付周りが不安 ● 単体テストを書くために クラスに切り出す 再掲: QAとテストケースについて議論した miroの図 日付のズレは集計に響くので単体テストで抑える 77
意味のある、攻めのクラス設計 Ⅱ 役員の数 再掲: QAとテストケースについて議論した miroの図 78
意味のある、攻めのクラス設計 Ⅱ DRY原則 役員の数 再掲: QAとテストケースについて議論した miroの図 79
意味のある、攻めのクラス設計 Ⅱ DRY原則 役員の数 ● 同じもの同じじゃないもの 再掲: QAとテストケースについて議論した miroの図 80
意味のある、攻めのクラス設計 Ⅱ DRY原則 役員の数 ● 同じもの同じじゃないもの ● 具象→抽象化 ● インタフェース、型 再掲: QAとテストケースについて議論した miroの図 81
意味のある、攻めのクラス設計 Ⅱ DRY原則 役員の数 ● 同じもの同じじゃないもの ● 具象→抽象化 ● インタフェース、型 再掲: QAとテストケースについて議論した miroの図 PHP8.4からはオブジェクトインターフェイスが使える 💜 82
オブジェクトインターフェイス // 従業員インタフェース interface MemberInterface { public string $name { get;} public int $salary { get;} } // 社員 final class Employee implements MemberInterface { public function __construct( private(set) readonly string $name, private(set) readonly int $salary, ){ } } // 役員 final class Exective implements MemberInterface { public function __construct( private(set) readonly string $name, private(set) readonly int $salary, ){ } } 83
まだ僕は躊躇してしまう 84
まだ僕は躊躇してしまう ● このクラス設計が正しいかわからない 85
まだ僕は躊躇してしまう ● このクラス設計が正しいかわからない ● レビューが通るか不安 86
まだ僕は躊躇してしまう ● このクラス設計が正しいかわからない ● レビューが通るか不安 ● いつ実装できるのか、コスト感 87
88
壊して良いオモチャとしてのGithub 89
壊して良いオモチャとしてのGithub Pull Request という発明 90
壊して良いオモチャとしてのGithub PRは Closeしてもイ イ!! Pull Request という発明 91
壊してよいオモチャとしてのGithub 成功と同じ数の失敗を経験するには、 失敗を求めることができるプライベートな 空間を必要とします。 …… 演技の最中に、3つ玉のジャグラーが 決して5つ玉に挑戦しないように、 ソフトウェア開発者は 間違いを行える安全な場所を必要とします。 92
壊してよいオモチャとしてのGithub 成功と同じ数の失敗を経験するには、 失敗を求めることができるプライベートな 空間を必要とします。 …… 演技の最中に、3つ玉のジャグラーが 決して5つ玉に挑戦しないように、 ソフトウェア開発者は 間違いを行える安全な場所を必要とします。 Pull Request という発明 93
まとめ 94
まとめ ● クラス設計を開発当初から取り組むのをやめた 95
まとめ ● クラス設計を開発当初から取り組むのをやめた ● コストとベネフィットを見極める技量が必要 96
まとめ ● クラス設計を開発当初から取り組むのをやめた ● コストとベネフィットを見極める技量が必要 ● とはいえ、経験しないと経験チは生まれない 97
まとめ ● クラス設計を開発当初から取り組むのをやめた ● コストとベネフィットを見極める技量が必要 ● とはいえ、経験しないと経験チは生まれない ● GithubのPull Requestの壊してよいオモチャで クラス設計を試そう! 98
をはり Ask the Speakerや 懇親会で お待ちしています💙 99