Slide 1

Slide 1 text

依存を意識して安定した 変更に強いコードを書こう 良いコードの書き方勉強会 in 京都 2024/8/17 あかつか

Slide 2

Slide 2 text

自己紹介 ● あかつか X: aki_artisan ● 神戸でPHP書いてます ● レガシーPHPをLaravelに移植 ● PHPカンファレンス関西2025実行委員長 2

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

Slide 9

Slide 9 text

「依存」をキーワードに考えてみよう 9

Slide 10

Slide 10 text

「依存」ってなんだか難しい? AがBに依存している→ピンとこない 大胆に「AがBを使っている」と言い換えよう! AがBを使っている。Bがないと機能しない。AはBに依存している。 AはBを使っている。だから、Bの変更の影響を受ける。 10

Slide 11

Slide 11 text

11

Slide 12

Slide 12 text

依存しているとは使っているということ 12

Slide 13

Slide 13 text

「AがBに依存ている」とは A B AがBを使っている状態 13

Slide 14

Slide 14 text

例:「ユーザー登録機能がメール送信機能を使っている」 ユーザー 登録機能 メール送信 機能 AがBを使っている状態 14

Slide 15

Slide 15 text

依存すると何が困るのか 15

Slide 16

Slide 16 text

依存すると変更の影響をうける(A視点) A B AがBを使っている状態 変更 影響が 波及 16

Slide 17

Slide 17 text

依存されると変更しづらくなる(B視点) 共通モジュールを変更したら、いろいろなところでバグが波及した! A B AがBを使っている状態 変更し づらい 17

Slide 18

Slide 18 text

実際のプロダクト開発では 実際の世界では、依存先(われわれが使うもの)は外部のものだったりする メリットの方が大きいので依存することを選んでいるとも言える わたしたちの プロダクト Laravel PHP 18

Slide 19

Slide 19 text

実際のプロダクト開発では わたしたちの プロダクト Laravel PHP LaravelやPHPのバージョンアップに振り回されるのはこのため だからこそ、できるだけ安定なものに依存したい → 依存注入というアプローチが一役買う 19

Slide 20

Slide 20 text

実演:依存性を注入してみよう 20

Slide 21

Slide 21 text

最初の状態 ログ出力処理が べた書き ログ出力の仕様を変えたい時、毎回全ての箇所で変更しないといけない 21

Slide 22

Slide 22 text

level1 : ログ出力を外部に委譲 ログ出力処理を 切り出した 22

Slide 23

Slide 23 text

level1 : ログ出力を外部に委譲 ログ出力処理を 切り出した 直接ロガーを 使っている 23

Slide 24

Slide 24 text

level2 : ログ出力用クラスを外から与える どのロガーを使うかを 外から与えるようにした ログ出力機能との結合が疎になった 24

Slide 25

Slide 25 text

level2 : ログ出力用クラスを外から与える どのロガーを使うかを 外から与えるようにした ログ出力機能との結合が疎になった 25

Slide 26

Slide 26 text

level3 : ログ出力用のインターフェースに依存させる logメソッドを 持てば良い (抽象化) 26

Slide 27

Slide 27 text

level3 : ログ出力用のインターフェースに依存させる logメソッドを 持てば良い (抽象化) 27 抽象に依存するとより安定に

Slide 28

Slide 28 text

依存を外から与えるメリット 28

Slide 29

Slide 29 text

依存を外から与えると差し替えることができる ● テストがしやすい ○ 例えばテストの時はログ出力をオフにしたい、などの場合、 logメソッドの実装が空のモックで置き換 えるなどで、安全にテストが行える ○ 時間がかかる、お金がかかる、副作用が許容できない、など様々なパターンに対応できる ● 拡張性が上がる ○ 既存の部分に影響を与えることなく、別の実装を使うように差し替えることが可能 ● 依存関係が追いやすい 29

Slide 30

Slide 30 text

良いコードの書き方 30

Slide 31

Slide 31 text

良いコードを書くには依存を意識する ● 変更しづらいコードはビジネスとして価値を産みづらい ● 無自覚な依存はコードを変更しづらくする ● 「これに依存して大丈夫?」「これはどのくらい安定?」と問いかける ● 依存しないといけない時は、依存を外から与えるようにする ○ コンストラクタ経由で与える ○ Laravelだと、サービスコンテナを使うなど 31

Slide 32

Slide 32 text

おすすめ資料① https://speakerdeck.com/blue_goheimochi/phperkaigi2024 32

Slide 33

Slide 33 text

おすすめ資料② なぜ依存を注入するのか DIの原理・原則とパ ターン (Compass Booksシリーズ) 33

Slide 34

Slide 34 text

まとめ ● 依存とは使っている ということ ● 変更の影響を受けないように、安定なものに依存しよう ● 依存を外から与える ようにすると疎結合になる(依存注入) ● 何が何を使っているかを意識してプログラミングしよう ● 依存する時は、「それはどのくらい安定?」 を考えるようにしよう 34