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.4k
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
310
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
6.1k
Other Decks in Programming
See All in Programming
カラム追加で増えるActiveRecordのメモリサイズ イメージできますか?
asayamakk
4
1.6k
Outline View in SwiftUI
1024jp
1
170
レガシーな Android アプリのリアーキテクチャ戦略
oidy
1
170
開発効率向上のためのリファクタリングの一歩目の選択肢 ~コード分割~ / JJUG CCC 2024 Fall
ryounasso
0
370
PLoP 2024: The evolution of the microservice architecture pattern language
cer
PRO
0
1.7k
とにかくAWS GameDay!AWSは世界の共通言語! / Anyway, AWS GameDay! AWS is the world's lingua franca!
seike460
PRO
1
560
EventSourcingの理想と現実
wenas
6
2.1k
LLM生成文章の精度評価自動化とプロンプトチューニングの効率化について
layerx
PRO
2
140
Nuxtベースの「WXT」でChrome拡張を作成する | Vue Fes 2024 ランチセッション
moshi1121
1
530
CSC509 Lecture 08
javiergs
PRO
0
110
PagerDuty を軸にした On-Call 構築と運用課題の解決 / PagerDuty Japan Community Meetup 4
horimislime
1
110
macOS でできる リアルタイム動画像処理
biacco42
7
2k
Featured
See All Featured
Raft: Consensus for Rubyists
vanstee
136
6.6k
Intergalactic Javascript Robots from Outer Space
tanoku
268
27k
Embracing the Ebb and Flow
colly
84
4.4k
Teambox: Starting and Learning
jrom
132
8.7k
Code Review Best Practice
trishagee
64
17k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
Happy Clients
brianwarren
97
6.7k
It's Worth the Effort
3n
183
27k
Optimising Largest Contentful Paint
csswizardry
33
2.9k
We Have a Design System, Now What?
morganepeng
50
7.2k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
14
1.9k
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