Slide 1

Slide 1 text

インターフェースの目的別分類 レイヤー分離 / 特性表現 / 差替可能性 Object-Oriented Conference 2024 1 Hirosugu Takeshita @fuwasegu

Slide 2

Slide 2 text

2 Object-Oriented Conference 2024 • 竹下 拓秀 / ふわせぐ (@fuwasegu) • 株式会社ゆめみ / 21卒 – コーポレートエンジニア – PHP テックリード • PHP / Laravel がメイン – Svelte(TS)が好き • 長崎県出身 / 愛知県在住 • 👶(4 歳)の父 自己紹介

Slide 3

Slide 3 text

3 Object-Oriented Conference 2024

Slide 4

Slide 4 text

4 今日は Interface のお話 Object-Oriented Conference 2024

Slide 5

Slide 5 text

5 Interface を何に使ってますか? Object-Oriented Conference 2024

Slide 6

Slide 6 text

6 どんなときに 「あ, Interface 定義しよう.」 ってなりますか? Object-Oriented Conference 2024

Slide 7

Slide 7 text

7 今日は そのアイディアの引き出しが増やせたらいいな, というお話 Object-Oriented Conference 2024

Slide 8

Slide 8 text

その前に • そもそも Interface の基礎知識が無い! Object-Oriented Conference 2024 8 https://speakerdeck.com/togishima/monlognoshi- zhuang-nixue-buinterfacenotukaidokoro https://speakerdeck.com/togishima/shi-jian-interface

Slide 9

Slide 9 text

こんな本も Object-Oriented Conference 2024 9

Slide 10

Slide 10 text

• 特性表現 – オブジェクトの振る舞いや能力にフォーカス • 差替可能性 – 実装の切り替えにフォーカス • レイヤー分離 – 影響範囲の最小化と切り離し容易化にフォーカス 10 Interface を使う3つの目的 Object-Oriented Conference 2024

Slide 11

Slide 11 text

• 特性表現 – オブジェクトの振る舞いや能力にフォーカス • 差替可能性 – 実装の切り替えにフォーカス 境界分離 – 影響範囲の最小化と切り離し容易化にフォーカス 11 Interface を使う3つの目的 Object-Oriented Conference 2024 言い訳は後ほど

Slide 12

Slide 12 text

• 差替可能性 • 境界分離 12 Interface を使う3つの目的 Object-Oriented Conference 2024 密接に関係

Slide 13

Slide 13 text

• 差替可能性 – 視点がミクロ – コンポーネントレベルの差し替えを想定 • 境界分離 – 視点がマクロ – モジュール同士の境界を明確に分離することを想定 13 差替可能性と境界分離 Object-Oriented Conference 2024

Slide 14

Slide 14 text

• 境界分離 → 差替可能性 – 境界を明確に分離した結果,実装詳細に依存しなくなる ため差替が可能になる • 差替可能性 → 境界分離 – 差し替え可能なコンポーネントの範囲を考えること ≒ 責任の境界をはっきりさせること 14 差替可能性と境界分離の相互作用 Object-Oriented Conference 2024

Slide 15

Slide 15 text

• 排他的ではない – 同時に複数の目的を達成する Inteface の使い 方は存在する • 必ず3つに分類できるわけではない – こんな使い方もあるよ!是非シェアしてください! 15 Interface を目的で分類するということ Object-Oriented Conference 2024

Slide 16

Slide 16 text

• PHPer が話す内容です – 構造的部分型ではそんな必要ありませーん – G◯ の文化圏ではそんなことしませーん – Ru◯t はそんなゆるふわな型ゆるしませーん 全てのマサカリを受け入れる覚悟です 逆に,「PHP だとそうなるのね」を知ってもらいたい 16 詳しい話に入る前に Object-Oriented Conference 2024

Slide 17

Slide 17 text

• Interface の3つの使い方を簡単に紹介 – 特性表現 – 差替可能性 – 境界分離 • 実際にありそうな要件で Interface を使ってみる 17 ここからの流れ Object-Oriented Conference 2024

Slide 18

Slide 18 text

18 特性表現 Object-Oriented Conference 2024

Slide 19

Slide 19 text

• オブジェクトの機能や振る舞いを明示する – 数えられる(Countable) – string にキャストできる(Stringable) • マーカーインタフェースもこの類 – メソッドやフィールドが一切定義されていないイン タフェース(Wikipedia より) – Java だと Serializable とか Cloneable とか 19 特性表現としての Interface Object-Oriented Conference 2024

Slide 20

Slide 20 text

Stringable(PHP 8 〜) • string にキャストできることを示す – PHP 的に言うと,__toString() の実装を強制する • 良くわからんけどとりあえず文字列化できる奴 – string|Stringable みたいな引数が取れる! 20 特性表現 Interface の例 Object-Oriented Conference 2024

Slide 21

Slide 21 text

Stringable の使用例 Object-Oriented Conference 2024 21

Slide 22

Slide 22 text

特性表現 Interface の活用 Laravel(JsonResponse クラスのデータセット部) Object-Oriented Conference 2024 22 https://github.com/laravel/framework/blob/bd096bcb2e5e45f1d175011028122c0cf3ccfded/src/Illuminate/Http/JsonResponse.php#L75-L94

Slide 23

Slide 23 text

23 差替可能性 Object-Oriented Conference 2024

Slide 24

Slide 24 text

• コンポーネントの実体よりも機能にフォーカス し,実装を後から柔軟に選べるようにする • 最初から複数の実体がある前提で,必要な 共通機能を括りだして抽象化する • 所謂 Strategy Pattern もこの部類 24 差替可能性を持たせる Interface Object-Oriented Conference 2024

Slide 25

Slide 25 text

25 差替前提の Interface 例: Logger Object-Oriented Conference 2024 PSR-3 Logger Interface

Slide 26

Slide 26 text

26 差替前提の Interface 例: Logger Object-Oriented Conference 2024 • PSR (PHP Standards Recommendations) – PHP-FIG という団体が定めている PHP の規約 – Interface だけではなく,スタイリングなどのコーディング規約も ある – 多くの有名 OSS はこの規約を厳守しているため, ライブラリ間での互換性が保たれている • PSR-3 では,ロギングライブラリの共通インタ フェースを定義している

Slide 27

Slide 27 text

• ログの出力先を変える – 標準出力 – ファイル • ログを出すかどうかを変える – 出さない場合は NullLogger を注入する 27 Logger を差し替える Object-Oriented Conference 2024

Slide 28

Slide 28 text

28 PSR の NullLogger Object-Oriented Conference 2024

Slide 29

Slide 29 text

29 境界分離 Object-Oriented Conference 2024

Slide 30

Slide 30 text

• そもそも Interface は「境界面」という意味を 持つ • アーキテクチャ的な layer や package 同士の 依存度を下げる 30 境界を分離する Interface Object-Oriented Conference 2024

Slide 31

Slide 31 text

31 Layer を分離する Object-Oriented Conference 2024 アプリケーション層 ドメイン層 インフラ層 RepositoryImpl RepositoryInterface DomainModel UseCase アプリケーション層や ドメイン層がインフラ層に 依存しない構造に!

Slide 32

Slide 32 text

32 Package を分離する Object-Oriented Conference 2024 packageB packageA Service Impl Repository Impl Service Interface Service Interface Service Impl Repository Impl UseCase 別パッケージに提供する 機能は Interface を通す

Slide 33

Slide 33 text

33 Layer 境界と Package 境界 Object-Oriented Conference 2024 レイヤー A レイヤー B レイヤー C パ ッ ケ ! ジ A パ ッ ケ ! ジ B パ ッ ケ ! ジ C 縦の分離 横の分離

Slide 34

Slide 34 text

• モジュラモノリスにおける横の分離は,疎結合にしておくこ との重要性が高い – そもそも中〜大規模の開発が前提であることが多い • レイヤードアーキテクチャにおける縦の分離は,疎結合に しておくに越したことはないが,規模によってはそこまで重 要性は高くない レイヤーにフォーカスすべきではなかった (・ω<) テヘペロ 34 レイヤー分離 → 境界分離にした言い訳 Object-Oriented Conference 2024

Slide 35

Slide 35 text

35 実践編 Object-Oriented Conference 2024

Slide 36

Slide 36 text

• 見放題だけではなく,個別に動画の購入がある • 割引サービスがある • 毎月5日に,先月分の利用料金を顧客に請求する • 今回は,この請求計算機能を作る 36 架空のプロジェクト: 動画配信サービス Object-Oriented Conference 2024

Slide 37

Slide 37 text

• 多種多様なプラン – 映画見放題プラン 月額 500 円 – アニメ見放題プラン 月額 500 円 – 映画の購入 200 円/作品 – 映画の7日間レンタル 100 円/作品 • 割引サービス – 見放題プランに入っていれば動画の購入が10% OFF – 映画とアニメ両方の見放題プランに入っていれば 100 円 OFF 37 料金体系 Object-Oriented Conference 2024

Slide 38

Slide 38 text

• 計算ロジックは保存しなければならない – 事業方針の転換などで単価や割引率は変更にな る可能性がある – 会計監査の観点から,過去の請求に関しても データとロジックから計算を復元可能な状態にし なければならない 38 追加要件 Object-Oriented Conference 2024

Slide 39

Slide 39 text

• 請求モデル(Billing) – Properties • ユーザー ID • 請求対象年月 • 請求対象項目のリスト – Methods • 請求額計算メソッド 39 ざっくりモデリング Object-Oriented Conference 2024

Slide 40

Slide 40 text

• ロジックが変わってもコードを上書きできない – アプリケーション上で過去のデータを使って同じ 計算ができないといけない = Git によるバージョン管理ではダメ ロジックをコード上でバージョニングする 40 ロジックの保存を実現する Object-Oriented Conference 2024

Slide 41

Slide 41 text

請求金額を計算するメソッドを持つ Interface を 定義する 41 ロジックの保存を実現する Object-Oriented Conference 2024

Slide 42

Slide 42 text

バージョンごとに請求モデルを実装 42 ロジックの保存を実現する Object-Oriented Conference 2024

Slide 43

Slide 43 text

差替可能な設計(StrategyPattern)によりバージョニングを実現 43 ロジックの保存を実現する Object-Oriented Conference 2024 請求インタフェース 請求計算ロジック V1 請求計算ロジック V2 請求計算ロジック V3 ユースケース 任意のバージョンで 請求金額が知りたい 差替可能性!

Slide 44

Slide 44 text

44 データは...? Object-Oriented Conference 2024

Slide 45

Slide 45 text

• ユーザーの購入情報もあとから更新してはなら ない – トランザクションテーブルで十分? → テーブル構造が変わる可能性がある 請求計算に使ったデータも Snapshot を取る 45 データも不変でないといけない Object-Oriented Conference 2024

Slide 46

Slide 46 text

46 請求テーブルの構造 Object-Oriented Conference 2024 ユーザーマスタ ユーザー ID UUID 請求トランザクション 請求 ID UUID ユーザーID UUID 請求対象年月 VARCHAR(6) 請求金額 INT 請求バージョン TEXT 料金構成項目 JSONB

Slide 47

Slide 47 text

47 料金構成項目 Object-Oriented Conference 2024 • 請求金額を算出するのに 必要な要素を JSON 形式に シリアライズしたもの • クーポンなどの割引要素も 含める

Slide 48

Slide 48 text

48 Billing を料金構成項目から作る Object-Oriented Conference 2024 • 単価やバージョンをクラス定数として定義 • 単価が変わればバージョンを切る • 各要素(Subscriptions など)は Countable を実装しておくことで カウントしやすく 特性表現! ※ ID などはスペースの都合で省略

Slide 49

Slide 49 text

• Billing が持っている料金構成項目を JSON に シリアライズして Snapshot として一緒に永続化 したい • でも,これは永続化するときのみに必要な知識 で,インフラ層以外に露出させたくない Interface を分ける 49 Billing の永続化 Object-Oriented Conference 2024

Slide 50

Slide 50 text

JsonSerializable を継承して名前をつけるだけ • json_encode() に渡せばシリアライズできる 50 Snapshot 用 Interface の定義 Object-Oriented Conference 2024

Slide 51

Slide 51 text

51 Snapshotable を Billing が実装 Object-Oriented Conference 2024 • Billing が Snapshotable を実装する • 各要素(Subscriptions など)も JsonSerializable を実装しておくことで コードをスッキリさせる 特性表現!

Slide 52

Slide 52 text

52 永続化層の実装 Object-Oriented Conference 2024 • 永続化メソッドの引数は Billing モデルと Snapshotable の Intersection Types(交差型) で受け取る

Slide 53

Slide 53 text

53 Interface を分けて境界を分離 Object-Oriented Conference 2024 アプリケーション層 ドメイン層 インフラ層 BillingInterface BillingInterface&Snapshotable スナップショットの知識は ドメイン層とインフラ層のみが知る 境界分離!

Slide 54

Slide 54 text

• 特性表現を利用してコードをスッキリ書けた • 差替可能性を持たせてバージョニングを型安 全にできた • 境界分離することで不要な知識を別のレイ ヤーに漏らさずに済んだ 54 Interface の活用結果 Object-Oriented Conference 2024

Slide 55

Slide 55 text

55 Interface で快適な OOP ライフを Object-Oriented Conference 2024