Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
object-oriented-conference-2024
Search
ふわせぐ
March 24, 2024
Programming
14
4.3k
object-oriented-conference-2024
OOC(Object-Oriented Conference 2024)の登壇資料です
ふわせぐ
March 24, 2024
Tweet
Share
More Decks by ふわせぐ
See All by ふわせぐ
proud of my organization LT
fuwasegu
1
300
Qiita Night PHP 2023
fuwasegu
0
13k
php conference okinawa 2022
fuwasegu
0
1.5k
QiitaConference2022
fuwasegu
1
1.2k
sleepagotchi
fuwasegu
2
2.6k
何の画像か当てちゃるBot紹介/image_guess_bot
fuwasegu
0
150
新卒 Laravel 初心者が成長していく中で 感じたコレジャナイ感/PHPerKaigi 2022
fuwasegu
10
13k
入社初日に社内サービスを全部一人で引き継いだ新卒フルサイクルエンジニアの話
fuwasegu
4
6k
Other Decks in Programming
See All in Programming
色んなオートローダーを覗き見る #phpcon_okinawa
o0h
PRO
5
380
ECS向けのドリフト検知機構を実装してみた
tkikuc
0
280
"Swarming" をコンセプトに掲げるアジャイルチームのベストプラクティス
boykush
2
240
実践Dash - 手を抜きながら本気で作るデータApplicationの基本と応用 / Dash for Python and Baseball
shinyorke
2
260
ACES Meet におけるリリース作業改善の取り組み
fukucheee
0
130
Real-time message handling and notifications with API Platform and Symfony
alli83
1
100
2024-10-01 dev2next - Observability for Modern JVM Applications
jonatan_ivanov
0
110
CDKを活用した 大規模コンテナ移行 プロジェクトの紹介
yoyoyopg
0
300
VS Code extension: ドラッグ&ドロップでファイルを並び替える
ttrace
0
170
선언형 UI를 학습할 때 알아둬야하는 키워드들
l2hyunwoo
0
140
メルカリ ハロ アプリの技術スタック
atsumo
2
750
pytest プラグインを開発して DRY に自動テストを書こう
inuatsu
2
260
Featured
See All Featured
Building an army of robots
kneath
302
42k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
228
52k
Atom: Resistance is Futile
akmur
261
25k
Fireside Chat
paigeccino
32
3k
Done Done
chrislema
181
16k
Agile that works and the tools we love
rasmusluckow
327
21k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9k
The Language of Interfaces
destraynor
154
24k
WebSockets: Embracing the real-time Web
robhawkes
59
7.3k
Unsuck your backbone
ammeep
668
57k
How to name files
jennybc
77
99k
Automating Front-end Workflow
addyosmani
1365
200k
Transcript
インターフェースの目的別分類 レイヤー分離 / 特性表現 / 差替可能性 Object-Oriented Conference 2024 1
Hirosugu Takeshita @fuwasegu
2 Object-Oriented Conference 2024 • 竹下 拓秀 / ふわせぐ (@fuwasegu)
• 株式会社ゆめみ / 21卒 – コーポレートエンジニア – PHP テックリード • PHP / Laravel がメイン – Svelte(TS)が好き • 長崎県出身 / 愛知県在住 • 👶(4 歳)の父 自己紹介
3 Object-Oriented Conference 2024
4 今日は Interface のお話 Object-Oriented Conference 2024
5 Interface を何に使ってますか? Object-Oriented Conference 2024
6 どんなときに 「あ, Interface 定義しよう.」 ってなりますか? Object-Oriented Conference 2024
7 今日は そのアイディアの引き出しが増やせたらいいな, というお話 Object-Oriented Conference 2024
その前に • そもそも Interface の基礎知識が無い! Object-Oriented Conference 2024 8 https://speakerdeck.com/togishima/monlognoshi-
zhuang-nixue-buinterfacenotukaidokoro https://speakerdeck.com/togishima/shi-jian-interface
こんな本も Object-Oriented Conference 2024 9
• 特性表現 – オブジェクトの振る舞いや能力にフォーカス • 差替可能性 – 実装の切り替えにフォーカス • レイヤー分離
– 影響範囲の最小化と切り離し容易化にフォーカス 10 Interface を使う3つの目的 Object-Oriented Conference 2024
• 特性表現 – オブジェクトの振る舞いや能力にフォーカス • 差替可能性 – 実装の切り替えにフォーカス 境界分離 –
影響範囲の最小化と切り離し容易化にフォーカス 11 Interface を使う3つの目的 Object-Oriented Conference 2024 言い訳は後ほど
• 差替可能性 • 境界分離 12 Interface を使う3つの目的 Object-Oriented Conference 2024
密接に関係
• 差替可能性 – 視点がミクロ – コンポーネントレベルの差し替えを想定 • 境界分離 – 視点がマクロ
– モジュール同士の境界を明確に分離することを想定 13 差替可能性と境界分離 Object-Oriented Conference 2024
• 境界分離 → 差替可能性 – 境界を明確に分離した結果,実装詳細に依存しなくなる ため差替が可能になる • 差替可能性 →
境界分離 – 差し替え可能なコンポーネントの範囲を考えること ≒ 責任の境界をはっきりさせること 14 差替可能性と境界分離の相互作用 Object-Oriented Conference 2024
• 排他的ではない – 同時に複数の目的を達成する Inteface の使い 方は存在する • 必ず3つに分類できるわけではない –
こんな使い方もあるよ!是非シェアしてください! 15 Interface を目的で分類するということ Object-Oriented Conference 2024
• PHPer が話す内容です – 構造的部分型ではそんな必要ありませーん – G◯ の文化圏ではそんなことしませーん – Ru◯t
はそんなゆるふわな型ゆるしませーん 全てのマサカリを受け入れる覚悟です 逆に,「PHP だとそうなるのね」を知ってもらいたい 16 詳しい話に入る前に Object-Oriented Conference 2024
• Interface の3つの使い方を簡単に紹介 – 特性表現 – 差替可能性 – 境界分離 •
実際にありそうな要件で Interface を使ってみる 17 ここからの流れ Object-Oriented Conference 2024
18 特性表現 Object-Oriented Conference 2024
• オブジェクトの機能や振る舞いを明示する – 数えられる(Countable) – string にキャストできる(Stringable) • マーカーインタフェースもこの類 –
メソッドやフィールドが一切定義されていないイン タフェース(Wikipedia より) – Java だと Serializable とか Cloneable とか 19 特性表現としての Interface Object-Oriented Conference 2024
Stringable(PHP 8 〜) • string にキャストできることを示す – PHP 的に言うと,__toString() の実装を強制する
• 良くわからんけどとりあえず文字列化できる奴 – string|Stringable みたいな引数が取れる! 20 特性表現 Interface の例 Object-Oriented Conference 2024
Stringable の使用例 Object-Oriented Conference 2024 21
特性表現 Interface の活用 Laravel(JsonResponse クラスのデータセット部) Object-Oriented Conference 2024 22 https://github.com/laravel/framework/blob/bd096bcb2e5e45f1d175011028122c0cf3ccfded/src/Illuminate/Http/JsonResponse.php#L75-L94
23 差替可能性 Object-Oriented Conference 2024
• コンポーネントの実体よりも機能にフォーカス し,実装を後から柔軟に選べるようにする • 最初から複数の実体がある前提で,必要な 共通機能を括りだして抽象化する • 所謂 Strategy Pattern
もこの部類 24 差替可能性を持たせる Interface Object-Oriented Conference 2024
25 差替前提の Interface 例: Logger Object-Oriented Conference 2024 PSR-3 Logger
Interface
26 差替前提の Interface 例: Logger Object-Oriented Conference 2024 • PSR
(PHP Standards Recommendations) – PHP-FIG という団体が定めている PHP の規約 – Interface だけではなく,スタイリングなどのコーディング規約も ある – 多くの有名 OSS はこの規約を厳守しているため, ライブラリ間での互換性が保たれている • PSR-3 では,ロギングライブラリの共通インタ フェースを定義している
• ログの出力先を変える – 標準出力 – ファイル • ログを出すかどうかを変える – 出さない場合は
NullLogger を注入する 27 Logger を差し替える Object-Oriented Conference 2024
28 PSR の NullLogger Object-Oriented Conference 2024
29 境界分離 Object-Oriented Conference 2024
• そもそも Interface は「境界面」という意味を 持つ • アーキテクチャ的な layer や package
同士の 依存度を下げる 30 境界を分離する Interface Object-Oriented Conference 2024
31 Layer を分離する Object-Oriented Conference 2024 アプリケーション層 ドメイン層 インフラ層 RepositoryImpl
RepositoryInterface DomainModel UseCase アプリケーション層や ドメイン層がインフラ層に 依存しない構造に!
32 Package を分離する Object-Oriented Conference 2024 packageB packageA Service Impl
Repository Impl Service Interface Service Interface Service Impl Repository Impl UseCase 別パッケージに提供する 機能は Interface を通す
33 Layer 境界と Package 境界 Object-Oriented Conference 2024 レイヤー A
レイヤー B レイヤー C パ ッ ケ ! ジ A パ ッ ケ ! ジ B パ ッ ケ ! ジ C 縦の分離 横の分離
• モジュラモノリスにおける横の分離は,疎結合にしておくこ との重要性が高い – そもそも中〜大規模の開発が前提であることが多い • レイヤードアーキテクチャにおける縦の分離は,疎結合に しておくに越したことはないが,規模によってはそこまで重 要性は高くない レイヤーにフォーカスすべきではなかった
(・ω<) テヘペロ 34 レイヤー分離 → 境界分離にした言い訳 Object-Oriented Conference 2024
35 実践編 Object-Oriented Conference 2024
• 見放題だけではなく,個別に動画の購入がある • 割引サービスがある • 毎月5日に,先月分の利用料金を顧客に請求する • 今回は,この請求計算機能を作る 36 架空のプロジェクト:
動画配信サービス Object-Oriented Conference 2024
• 多種多様なプラン – 映画見放題プラン 月額 500 円 – アニメ見放題プラン 月額
500 円 – 映画の購入 200 円/作品 – 映画の7日間レンタル 100 円/作品 • 割引サービス – 見放題プランに入っていれば動画の購入が10% OFF – 映画とアニメ両方の見放題プランに入っていれば 100 円 OFF 37 料金体系 Object-Oriented Conference 2024
• 計算ロジックは保存しなければならない – 事業方針の転換などで単価や割引率は変更にな る可能性がある – 会計監査の観点から,過去の請求に関しても データとロジックから計算を復元可能な状態にし なければならない 38
追加要件 Object-Oriented Conference 2024
• 請求モデル(Billing) – Properties • ユーザー ID • 請求対象年月 •
請求対象項目のリスト – Methods • 請求額計算メソッド 39 ざっくりモデリング Object-Oriented Conference 2024
• ロジックが変わってもコードを上書きできない – アプリケーション上で過去のデータを使って同じ 計算ができないといけない = Git によるバージョン管理ではダメ ロジックをコード上でバージョニングする 40
ロジックの保存を実現する Object-Oriented Conference 2024
請求金額を計算するメソッドを持つ Interface を 定義する 41 ロジックの保存を実現する Object-Oriented Conference 2024
バージョンごとに請求モデルを実装 42 ロジックの保存を実現する Object-Oriented Conference 2024
差替可能な設計(StrategyPattern)によりバージョニングを実現 43 ロジックの保存を実現する Object-Oriented Conference 2024 請求インタフェース 請求計算ロジック V1 請求計算ロジック
V2 請求計算ロジック V3 ユースケース 任意のバージョンで 請求金額が知りたい 差替可能性!
44 データは...? Object-Oriented Conference 2024
• ユーザーの購入情報もあとから更新してはなら ない – トランザクションテーブルで十分? → テーブル構造が変わる可能性がある 請求計算に使ったデータも Snapshot を取る
45 データも不変でないといけない Object-Oriented Conference 2024
46 請求テーブルの構造 Object-Oriented Conference 2024 ユーザーマスタ ユーザー ID UUID 請求トランザクション
請求 ID UUID ユーザーID UUID 請求対象年月 VARCHAR(6) 請求金額 INT 請求バージョン TEXT 料金構成項目 JSONB
47 料金構成項目 Object-Oriented Conference 2024 • 請求金額を算出するのに 必要な要素を JSON 形式に
シリアライズしたもの • クーポンなどの割引要素も 含める
48 Billing を料金構成項目から作る Object-Oriented Conference 2024 • 単価やバージョンをクラス定数として定義 • 単価が変わればバージョンを切る
• 各要素(Subscriptions など)は Countable を実装しておくことで カウントしやすく 特性表現! ※ ID などはスペースの都合で省略
• Billing が持っている料金構成項目を JSON に シリアライズして Snapshot として一緒に永続化 したい •
でも,これは永続化するときのみに必要な知識 で,インフラ層以外に露出させたくない Interface を分ける 49 Billing の永続化 Object-Oriented Conference 2024
JsonSerializable を継承して名前をつけるだけ • json_encode() に渡せばシリアライズできる 50 Snapshot 用 Interface の定義
Object-Oriented Conference 2024
51 Snapshotable を Billing が実装 Object-Oriented Conference 2024 • Billing
が Snapshotable を実装する • 各要素(Subscriptions など)も JsonSerializable を実装しておくことで コードをスッキリさせる 特性表現!
52 永続化層の実装 Object-Oriented Conference 2024 • 永続化メソッドの引数は Billing モデルと Snapshotable
の Intersection Types(交差型) で受け取る
53 Interface を分けて境界を分離 Object-Oriented Conference 2024 アプリケーション層 ドメイン層 インフラ層 BillingInterface
BillingInterface&Snapshotable スナップショットの知識は ドメイン層とインフラ層のみが知る 境界分離!
• 特性表現を利用してコードをスッキリ書けた • 差替可能性を持たせてバージョニングを型安 全にできた • 境界分離することで不要な知識を別のレイ ヤーに漏らさずに済んだ 54 Interface
の活用結果 Object-Oriented Conference 2024
55 Interface で快適な OOP ライフを Object-Oriented Conference 2024