Slide 1

Slide 1 text

@PHP Conference Japan 2025(2025/6/28) プログラミングをするパンダ(@Panda_Program) 設計やレビューに悩んでいるPHPerに贈る、 クリーンなオブジェクト設計の指針たち 1

Slide 2

Slide 2 text

ペチコン25周年おめでとうございます! PHP Conference Japan 25周年 おめでとうございます! 22

Slide 3

Slide 3 text

3 © 2012-2025 BASE, Inc. 自己紹介 ● BASE株式会社 ● 所属:BASE / Product Dev / feature dev1 ● 現在の仕事:Advanced Enginner(ジュニアテックリード相当) ○ フロントエンドもバックエンドも書くフルスタックです ○ スクラム開発やチーム開発のプロセス改善が好きです ○ 今はフロント中心にサイトリニューアルPJを担当しています(8ヶ月目) ● 活動実績 ○ 執筆 ○ CodeZine様で「バックエンドエンジニアのためのフロントエンド入門」を連載 ○ 2024/12に「アジャイル開発」で一人アドベントカレンダーを完走しました ○ 登壇実績 ○ Developers Summit 2025、PHPerKaigi 2025、TSKaigi 2025, PHP Conference JP 2022 など ○ twitter: @Panda_Program プログラミングをするパンダ(@Panda_Program)

Slide 4

Slide 4 text

4 © 2012-2025 BASE, Inc. 宣伝 技術書典18(6/1)で良いチームの作り方の書籍を出しました ● 『成功する開発チームの作りかた 対話と信頼 の好循環 』(全85ページ) ○ 心理的安全性のあるチームを作る話 ● 技術書典マーケットで販売中です ○ PDF版のみ ○ https://techbookfest.org/product/p mc1tu6jc5YzbP1pmN3mfH

Slide 5

Slide 5 text

5 © 2012-2025 BASE, Inc. 宣伝 YouTubeでエンジニア向けのラジオを配信してます(@dialog-radio) https://www.youtube.com/@dialog-radio/videos ● ブログや登壇とはまた違った内容です ○ プロダクトエンジニアって何だろう? ○ プロダクトオーナーとエンジニアの違い とは? ○ 勉強会のスキルアップ以外の意義とは? ● 毎週月曜日、朝7時配信 ○ ぜひご視聴 & チャンネル登録お願 いします!

Slide 6

Slide 6 text

6 © 2012-2025 BASE, Inc. 宣伝 BASEはリアーキテクチャ中です ● BASEはモジュラーモノリスで開発している ○ 各モジュールはクリーンアーキテクチャ ○ 業務領域の理解をして、コードに反映さ せる取り組み(DDD)で開発している ● (ただ、レガシーなモノリスもまだ全然ある)

Slide 7

Slide 7 text

本発表の背景

Slide 8

Slide 8 text

8 © 2012-2025 BASE, Inc. モジュラーモノリスの話 @PHPerKaigi 2025 クリーンアーキテクチャの話 @TSKaigi 2025 オブジェクト設計の話 @今回 本発表の背景 本発表は3部構成の最後 https://speakerdeck.com/panda_program

Slide 9

Slide 9 text

© 2012-2025 BASE, Inc. 本発表の背景 PHPer 必携の 2 冊 99

Slide 10

Slide 10 text

© 2012-2025 BASE, Inc. 本発表の背景 ● リーダブルコードの次に読んでほしい 書籍 ● クラス設計、実装に使える ○ 自然にSOLID原則が身につく ■ 自然にクリーンアーキテク チャも身につく ○ 自然に”Always-Valid Domain Model”が書ける ○ 自然にCQS、CQRSが身につく ● チームで読んだら、同じ視点・同じレ ベルで相互にコードレビューができる 本発表はスタイルガイド本を参考にしている 10 10

Slide 11

Slide 11 text

© 2012-2025 BASE, Inc. 本発表の背景 ● 理解できること ○ MVC フレームワークから疎結合な アプリケーションとは何か ○ サービス層とドメイン層という言 葉が意味すること ● 持ち帰れること ○ クリーンなコードを書くこと ○ レビュー時にコードの良し悪しを 言語化できること ○ AI が出力するコードを採用するか 判断できること 本発表のプロポーザル 11 11

Slide 12

Slide 12 text

© 2012-2025 BASE, Inc. 本発表の背景 ● クリーンなコードを書く・読む・説明 できる ● アプリケーションの3つの構成要素 ○ レイヤーとオブジェクトとメソッ ド ● なぜ MVC フレームワークから距離を置 く手法が流行っているのか ○ appendix これには 3 つの視点がある 12 12

Slide 13

Slide 13 text

1 2 3 © 2012-2025 BASE, Inc. 目次 クリーンなコードを書く・読む・ 説明する オブジェクト指向アプリケーション の構成要素 オブジェクトとメソッドのコード例 13 13

Slide 14

Slide 14 text

1. クリーンなコードを 書く・読む・説明する

Slide 15

Slide 15 text

© 2012-2025 BASE, Inc. クリーンなコードを書く・読む・説明する クリーンなコードとは何か ● そもそもクリーンなコードとは何か ○ 認知負荷が低いコード ○ (ただし、クリーンなコードは認知負荷が低いが、認知負荷が低いコード は必ずしもクリーンなコードとは限らない) ● 認知負荷が低いコードとは何か ○ 自分が過去に見たことがある書き方をしているコードである(既知) ○ コードと仕様の対応関係がわかる(意図) ○ 処理内容がわかりやすい 15 15

Slide 16

Slide 16 text

© 2012-2025 BASE, Inc. クリーンなコードとは何か ● 何が処理内容がわかりやすいコードなのか ○ 定量・定性の両面がある ○ 定量: 「凝集度が高く、結合度が低い」「循環的複雑度(Cyclomatic Complexity)が低い」 ○ 定性: 「構造を表現している」「整頓されたコード(Tidy)」「命名がわ かりやすい」 ● つまり ○ 「予想と一致する」「直感的にわかる」が認知負荷の低いコード ○ パターン化されているコード(パターンランゲージ) ● チーム開発では自分一人が書ければいいというものではない 16 16 クリーンなコードを書く・読む・説明する

Slide 17

Slide 17 text

© 2012-2025 BASE, Inc. 具体的なエピソード ● 転職者の若手と同じチームになった ○ Laravel でコントローラーにロジックを全部書いていたとのこと ● コードレビューで「これは VO に切り出すと管理が楽ですよ」とコメントした ● 「VO ってValue Objectですか?なぜ VO にしないといけないんですか?」 ○ 説明したり、ネットの記事を渡してもいまいち納得していない様子 ● 自分一人が「クリーンなコードを書ければいい」のではない ● 「チーム全員」が「同じ基準」でコードを書くことが重要 ○ 一般的な原則を基準とする ○ 他の人が書くコードと「自分ならこう書く」が一致する ○ = パターン化されている ● このために「スタイルガイド本」が最適 17 17 クリーンなコードを書く・読む・説明する

Slide 18

Slide 18 text

© 2012-2025 BASE, Inc. 改めてクリーンなコードとは ● コードが一般的な原則に従っていること ○ CQS, SOLID 原則, DRY 原則 etc. ○ 「プリンシプルオブプログラミング」がおすすめ ● パターン化されていること ○ 人間のパターンマッチング ○ 「この場合はこう書く」が浸透している ○ 説明不要の共通言語を使える → コミュニケーションコストの低減 ● 自分のみならず、チーム内、チーム外の人も理解しやすいこと → AI も理解しやすい ● 第2, 3章で、オブジェクト設計の一般原則に則りパターン化されたコードを解説 18 18 クリーンなコードを書く・読む・説明する

Slide 19

Slide 19 text

2. オブジェクト指向 アプリケーションの構成要素

Slide 20

Slide 20 text

© 2012-2025 BASE, Inc. オブジェクト指向アプリケーションの構成要素 構成要素(パターン) ● レイヤー ○ インフラ層 ○ アプリケーション層 ○ ドメイン層 ● オブジェクト ○ サービス ○ それ以外のオブジェクト ● メソッド ○ コマンドメソッド ○ クエリメソッド ○ モディファイアメソッド 20 20

Slide 21

Slide 21 text

© 2012-2025 BASE, Inc. オブジェクト指向アプリケーションの構成要素 構成要素 - レイヤー ● インフラ層 ○ コントローラー ○ レポジトリとクエリサービスの実装 ● アプリケーション層 ○ コマンドオブジェクト, リードモデル ○ クエリサービスのインターフェース ○ イベントリスナー ● ドメイン層 ○ エンティティ ○ バリューオブジェクト ○ レポジトリのインターフェース 出典:『オブジェクト指向設計スタイルガイド』 レイヤーとそれに属するオブジェクト 21 21

Slide 22

Slide 22 text

© 2012-2025 BASE, Inc. オブジェクト指向アプリケーションの構成要素 ● サービス ○ アプリケーションサービス ○ レポジトリ ○ コントローラー ○ イベントリスナー(本発表では省 略) ● それ以外のオブジェクト ○ エンティティ ○ バリューオブジェクト ○ DTO オブジェクト - 分類 22 22

Slide 23

Slide 23 text

© 2012-2025 BASE, Inc. ● サービスの特徴 ○ オブジェクトを呼び出すオブジェ クト ○ オブジェクトが協調してタスクを 実行する ○ 「オブジェクトがダンスする場」 ● それ以外のオブジェクトの特徴 ○ オブジェクトから呼び出されるオ ブジェクト ● 以下のコード例はブログ作成システム を想定 オブジェクト指向アプリケーションの構成要素 オブジェクト - 特徴 23 23

Slide 24

Slide 24 text

© 2012-2025 BASE, Inc. オブジェクト指向アプリケーションの構成要素 ● タスクを実行する ○ 返り値は void ○ 副作用がある ○ クラスの状態を変える ○ クエリメソッドを呼び出せる ○ (サービスの場合)テストには モックを使う メソッド - コマンドメソッド 24 24

Slide 25

Slide 25 text

© 2012-2025 BASE, Inc. オブジェクト指向アプリケーションの構成要素 ● データを取得する ○ 返り値は何かの型の値 ○ 副作用がない ○ アプリケーションの状態を変 えない ○ 状態が同じなら結果も同じ ○ コマンドメソッドを呼び出しては いけない ○ (サービスの場合)テストにはス タブを使う メソッド - クエリメソッド 25 25

Slide 26

Slide 26 text

© 2012-2025 BASE, Inc. オブジェクト指向アプリケーションの構成要素 ● Value Object の値を書き換える ○ 値の変更は新オブジェクトの作成 である ○ 一つの値に対して、一つのオ ブジェクトを作る ○ 返り値は自身と同じクラスのオブ ジェクト ○ 値の更新はプロパティの上書きで はない メソッド - モディファイアメソッド(Value Object 限定) 26 26

Slide 27

Slide 27 text

3.オブジェクトとメソッドの コード例

Slide 28

Slide 28 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 アプリケーションの構成要素とコード例(パターン) ● サービス ○ コントローラー ○ アプリケーションサービス ○ クエリサービス ○ レポジトリ ● それ以外のオブジェクト ○ Entity ○ Value Object ○ DTO ● その他 ○ Interface 28 28

Slide 29

Slide 29 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 ● 特徴 ○ コントローラーはサービスのエン トリーポイントである ○ アプリケーションサービスかクエ リサービスを呼び出している ○ Web の Controller の場合、必ず 返り値(レスポンス)が必要 ● レビューの視点 ○ ドメインロジックが書かれていな いか? (ドメインロジックはEntityかValue Objectに書く) サービス - コントローラー 29 29

Slide 30

Slide 30 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 ● 特徴 ○ 単一のタスクを実行する ○ ドメイン層にのみ依存する ○ インフラ層のコードを含まない ● レビューの視点 ○ 複数のタスクを実行していない か? ○ 抽象(Interface)ではなく具象 (クラス)に依存していないか? ○ ドメインモデルの呼び出しかトラ ンザクションスクリプトか? サービス - アプリケーションサービス 30 30

Slide 31

Slide 31 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 サービス - アプリケーションサービス 31 31

Slide 32

Slide 32 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 ● 特徴 ○ 永続化先からデータを取得する (PDOは使わなくても良い) ○ 特定のユースケースに応じて柔軟 にデータを返す ○ 専用の DTO を返す ● レビューの視点 ○ DTO を使い回してはいないか? ○ レポジトリのクエリメソッドで代 用できないか? (単純な値ならクエリサービスを作成する必要なし) サービス - クエリサービス 32 32

Slide 33

Slide 33 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 ● 特徴 ○ Entityが持つデータを永続化先に 保存する ○ 永続化先からデータを取得し、 Entityを復元する ● レビューの視点 ○ ドメインロジックを書いてはいな いか? (ドメインロジックはEntityかValue Objectに書 く) ○ 返り値は DTO ではなく Entity で あるか? サービス - レポジトリ 33 33

Slide 34

Slide 34 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 ● 英語から意味を考える ○ 他と区別できる「実在物」 ○ ex. 会場、座席、テーブル ● Entity は ○ 他と区別するための ID を持つ ○ Entity and Identity ○ 「作成→変更→削除」のライフサ イクルがある ○ 永続化され、復元される ○ プロパティにValue Objectを持つ ○ データの変更ができる サービス以外のオブジェクト - Entity 34 34

Slide 35

Slide 35 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 サービス以外のオブジェクト - Entity をクリーンに書く 35 35

Slide 36

Slide 36 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 ● 英語から意味を考える ○ 「値」「オブジェクト」 ● value(値)との違い ○ value はコンピュータが扱える範 囲で取りうる全ての値(無制限) ○ value はスカラ型、VOは Object ● Value Object は ○ スカラ型の値をラップしているオ ブジェクトである ○ 値の範囲をバリデーションで制限 ○ イミュータブルである ○ サービス以外のオブジェクト - Value Object 36 36

Slide 37

Slide 37 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 サービス以外のオブジェクト - Value Object をクリーンに書く 37 37

Slide 38

Slide 38 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 ● 特徴 ○ DTO は振る舞いを持たないデータ の塊である ○ データの箱 ○ システムの境界で現れる ● レビューの視点 ○ プロパティはプリミティブ型か? (EntityやVOを持たせてはいけない) ○ readonlyにしているか? (ただし、好みがあるので絶対ではない) サービス以外のオブジェクト - DTO 38 38

Slide 39

Slide 39 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 サービス以外のオブジェクト - DTO 39 39

Slide 40

Slide 40 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 ● 特徴 ○ メソッドの具体的な実装ではな く、抽象的なシグニチャを定義 (シグニチャ = メソッド名・引数・返り値の型) ■ 「IFは契約」と呼ばれる理由 ○ ポリモーフィズムを実現するため に使われる(次ページ) ○ 制御できないものを抽象化する ● レビューの視点 ○ メソッドはクエリメソッドかコマ ンドメソッドかわかる命名か? その他 - Interface 40 40

Slide 41

Slide 41 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 その他 - Interface 41 41

Slide 42

Slide 42 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 サービスとEntity, Value Objectの違い ● 他のオブジェクトに仕事をさせる / 呼び出されるまで待機中 ○ サービスは舞台、それ以外のオブジェクトは役者、永続化先は役者の家 ● 依存する側 / 依存される側 ● テストのためにモックやスタブを使う / そのままテストができる ● (大まかに)例外は RuntimeException を投げる / LogicException を投げる (ドメイン層、サービス層などのレイヤーについては TSKaigi 2025のクリーンアー キテクチャの発表をご覧ください) (「クリーンなアプリケーション」を1つのモジュールとした大規模なアプリケー ションについては、PHPer Kaigi 2025のモジュラーモノリスの発表をご覧くださ い) 42 42

Slide 43

Slide 43 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 3つにレイヤーを分けて (Domain Layer, Application Layer, Infrastructure Layer) 4種類のオブジェクトと (Service, Entity, Value Object, DTO) 3種類のメソッドを使って (Command Method, Query Method, Modifier Method) クリーンなコードを書く 43 43

Slide 44

Slide 44 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 ただし、 これが全てではない。 基礎を踏まえて学習を続ける 44 44

Slide 45

Slide 45 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 (アドバイス) 「じゃあ仕事でどう書くの?」と 疑問に思ったら、スライドのPDFを AIに突っ込んで質問してください prompt 例 「このスライドのオブジェクトの書き方で xxx の実装をするならどんなコードになる?」 「このスライドのコードに基づいてチームで守るべきコーディングスタイルを作って」 45 45

Slide 46

Slide 46 text

ペチコン25周年盛り上げていきましょう! PHP Conference Japan 25周年 盛り上げていきましょう! 46 46

Slide 47

Slide 47 text

(appendix) MVC フレームワーク vs. 「クリーン」なアプリケーション

Slide 48

Slide 48 text

© 2012-2025 BASE, Inc. MVC FW vs.「クリーン」なアプリケーション SOLID原則に基づいた Clean Way* vs. MVCフレームワーク Way(Rails Way) ● 疎結合 vs. 密結合 ● 高凝集 vs. 低凝集 ● 単一責任 vs. 複数の責務 ● 単体テスト中心 vs. 結合テスト中心 ● アプリケーションの内外を Interface で区別 vs. コントローラーからDBも呼ぶ ● 処理をサービスに移譲 vs. Fat Controller, Fat Model ● etc. (「右はマイナスだ」とされるのは2025年時点の感覚。2000年代後半には左のア ンチテーゼとしてWeb開発むけのMVCフレームワークが登場した。もちろん現代で もMVCフレームワークの良さはある) (* サービス層とドメイン層を分けるレイヤードアーキテクチャとClean Architectureの設計に着目し、オブジェクト 指向の一般的な原則に則った設計をRails Way と対比する形でここでは便宜的にClean Wayと呼ぶ(他では通じないの でご注意)) 48 48

Slide 49

Slide 49 text

© 2012-2025 BASE, Inc. MVC FW vs.「クリーン」なアプリケーション 49 49

Slide 50

Slide 50 text

© 2012-2025 BASE, Inc. MVC FW vs.「クリーン」なアプリケーション Q. なぜ MVC フレームワークから距離を置く手法が流行っているのか? A.スタートアップが成長した結果、設計が見直されたから(SaaS隆盛で加速) — 2000年代中盤まで: エンタープライズ向けの重厚なアプリケーション設計が主流(?) 2000年代中盤: Rails 登場、軽量な Rails Way で爆速開発(スタートアップの世界) 2010年代: スタートアップで事業の成長から Fat Model + Fat Controller へ 2010年代後半: → DDD再脚光、Clean Architecture 広まる 私見 ● フレームワークからアプリケーションを分離する手段 ● スタートアップ特有の事情 ○ 戦略的DDDが軽視された理由 ■ 実装だけに注目・事業成長優先・モデリング軽視 先に整頓する? 50 50

Slide 51

Slide 51 text

© 2012-2025 BASE, Inc. MVC FW vs.「クリーン」なアプリケーション Clean Way と Rails Way の違いは「アプリケーション」の捉え方の違いと思われる ● Rails Way では Controller や Database までアプリケーションとして捉えて いるのでは? ○ ex. リクエストのバリデーションをモデルでやる ● クリーンアーキテクチャは、ドメイン層とUseCase層しかアプリケーションと 捉えていない ● クリーンアーキテクチャに対する「DBは外側ではないでしょ?」に対する回答 51 51

Slide 52

Slide 52 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 単純な業務ロジック → Active Record 複雑な業務ロジック → Domain Model 52 52

Slide 53

Slide 53 text

© 2012-2025 BASE, Inc. オブジェクトとメソッドのコード例 チームで認識をそろえて 一貫したコードを書こう 53 53

Slide 54

Slide 54 text

© 2012-2025 BASE, Inc. 参考資料 ● スライドに掲載した各書籍 ● 「1. Software Development in 2003(技術顧問の和田卓人さんと、DDD、デー タソースのアーキテクチャに関するパターンなどについて話しました)」 texta.fm ○ https://open.spotify.com/episode/1Ka5Fnoe89SyRLPea5twPA ● Special Thanks to ○ Claude Code(サンプルコード生成) ○ k1LoW/deck(スライド作成) ■ https://github.com/k1LoW/deck 54 54

Slide 55

Slide 55 text

ペチコン25周年盛り上げていきましょう! PHP Conference Japan 25周年 盛り上げていきましょう! 55 55