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.5k
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.2k
Other Decks in Programming
See All in Programming
Webの技術スタックで マルチプラットフォームアプリ開発を可能にするElixirDesktopの紹介
thehaigo
2
1k
役立つログに取り組もう
irof
28
9.6k
TypeScript Graph でコードレビューの心理的障壁を乗り越える
ysk8hori
2
1.1k
Jakarta Concurrencyによる並行処理プログラミングの始め方 (JJUG CCC 2024 Fall)
tnagao7
1
290
AWS Lambdaから始まった Serverlessの「熱」とキャリアパス / It started with AWS Lambda Serverless “fever” and career path
seike460
PRO
1
260
Less waste, more joy, and a lot more green: How Quarkus makes Java better
hollycummins
0
100
macOS でできる リアルタイム動画像処理
biacco42
9
2.4k
シェーダーで魅せるMapLibreの動的ラスタータイル
satoshi7190
1
480
RubyLSPのマルチバイト文字対応
notfounds
0
120
Streams APIとTCPフロー制御 / Web Streams API and TCP flow control
tasshi
2
350
Amazon Qを使ってIaCを触ろう!
maruto
0
400
3 Effective Rules for Using Signals in Angular
manfredsteyer
PRO
0
100
Featured
See All Featured
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
191
16k
Building Applications with DynamoDB
mza
90
6.1k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
131
33k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
28
8.2k
Designing for humans not robots
tammielis
250
25k
Facilitating Awesome Meetings
lara
50
6.1k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
47
2.1k
Docker and Python
trallard
40
3.1k
The Invisible Side of Design
smashingmag
298
50k
10 Git Anti Patterns You Should be Aware of
lemiorhan
654
59k
Optimizing for Happiness
mojombo
376
70k
A Philosophy of Restraint
colly
203
16k
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