Slide 1

Slide 1 text

オレがオブジェクト指向をやめるために必要な 3つのPHP RFC 2023/6/22 PHPカンファレンス福岡 全然野菜 LINE Fukuoka きしだ なおき

Slide 2

Slide 2 text

2023/06/22 2 自己紹介 ● きしだ なおき ● LINE Fukuoka ● twitter: @kis ● 「プロになるJava」という Java入門書を書いてます

Slide 3

Slide 3 text

2023/06/22 3 オブジェクト指向とは ● オブジェクト指向は状態管理技術 ● 状態遷移の共通化が行いやすい ● 状態遷移を管理しない場合 他の技法でも十分可能

Slide 4

Slide 4 text

状態管理はどこにあらわれるか ● モジュール境界では状態管理が必要 GUI ロジック データ ストア ユーザー アプリケーション

Slide 5

Slide 5 text

現代的アプリケーションはモジュール化済 ● Webクライアント+マイクロサービスでモジュール化 ● DOM管理やDB接続は世界に数個あればいい ● アプリケーションプログラマが状態管理を共通化する必要がない GUI ロジック データ ストア ユーザー アプリケーション DOM HTTP DB接続

Slide 6

Slide 6 text

オブジェクト指向からデータ指向へ ● データ指向プログラミング ● データをデータとして扱う ● 抽象データ型 ● 代数的データ型 ● パターンマッチング

Slide 7

Slide 7 text

抽象データ型と代数的データ型 ● 抽象データ型 ● 型の定義の指針 ● 代数的データ型 ● 型の組み合わせの指針

Slide 8

Slide 8 text

抽象データ型 ● データの操作だけ公開することで変更に強く柔軟な型を定義 ● データ特化の「カプセル化」 ● 操作としてデータ操作だけを含む class PersonName { function __construct( string $surname, string $givenName); function getFullName(); function getSurname(); function getGivenName(); } class PersonName { private string $surname; private string $givenName; function __construct ( string $surname, string $givenName) { $this->surname = $surname; $this->givenName = $givenName; } function getFullName() { return "%s %s".formatted(surname, givenName); } ... class PersonName { private string $fullName; function __construct ( string $surname, string $givenName) { $this→fullName = $surname.” “.$givenName; } function getFullName() { return $fullName; } String getSurname() { return explode(“ “, $fullName)[0]; } ... どちらでもOK

Slide 9

Slide 9 text

データ型のルール ● 純粋関数をデータ型に拡張する ● 純粋データ型? ● 参照等価 ● 戻り値が引数だけで決まる ● 副作用なし ● 状態の変更や外部への入出力なし ● 参照等価 ● 戻り値が引数とフィールドだけで決まる ● 副作用なし ● フィールド変更以外の状態の変更や 外部への入出力なし

Slide 10

Slide 10 text

代数的データ型 ● 直積型 ● クラス ● 配列 ● 直和型 ● 継承 ● union

Slide 11

Slide 11 text

直積型 ● 値を組み合わせる型 ● 値のとりうるパターンがそれぞれの値のパターン数の積になる ● class A{ function __construct(bool $a1, byte $a2) {} } ● 2 x 256で512とおり

Slide 12

Slide 12 text

直和型 ● いずれかの型になる ● int | float ● 継承

Slide 13

Slide 13 text

Tagged Unions ● 継承を使う場合 ● 可能な型を限定できない ● enumで限定 ● https://wiki.php.net/rfc/tagged_unions enum Distance { case Kilometers(int $km); case Miles(int $miles); }

Slide 14

Slide 14 text

パターンマッチング ● isによるパターンマッチング ● https://wiki.php.net/rfc/pattern-matching class Point { public function __construct(public int $x, public int $y, public int $z) {} } $result = match ($p) is { // These will match only some Point objects, depending on their property values. Point{x: 3, y: 9, %$z} => "x is 3, y is 9, z is $z", Point{%$z, %$x, y: 4} => "x is $x, y is 4, z is $z", Point{x: 5, %$y} => "x is 5, y is $y, and z doesn't matter", // This will match any Point object. Point{%$x, %$y, %$z} => "x is $x, y is $y, z is $z", };

Slide 15

Slide 15 text

データの処理を考える ● こんな値を合計する record Product(String name, Type type) {} record Item(Product product, int amount) {} var cart = List.of( new Item(new Product("餃子", new Packed(300)), 3), new Item(new Product("牛肉", new Bulk(250, 100)), 230));

Slide 16

Slide 16 text

継承で実装してみる ● 継承での実装 sealed interface Type { /** 量り売り */ record Bulk(int price, int unit) implements Type { int calc(int amount) { return price * amount / unit; } } /** パッケージ */ record Packed(int price) implements Type { int calc(int amount) { return price * amount; } } int calc(int amount); } int total = cart.stream() .mapToInt(item -> item.product().type().calc(item.amount())) .sum();

Slide 17

Slide 17 text

継承のほうがいい? ● すっきりして見える int total = cart.stream() .mapToInt(item -> item.product().type().calc(item.amount())) .sum();

Slide 18

Slide 18 text

継承で実現したときの欠点 ● 追うときにいろいろなクラスを見る必要がある ● 他のデータが関係あるときに対応できない ● 1パック170円、3パック500円とか ● 場合わけの型が2つあるときれいにかけない ● どちらかの型に場合わけが必要 ● 業務処理では一箇所にすべての型の処理をまとめるほうがいい ● システム境界では他の型が関係することがすくないので継承が有効 ● OracleConnectionがMySQLConnectionを気にしたりとかはない

Slide 19

Slide 19 text

継承で実現したときの欠点 ● 追うときにいろいろなクラスを見る必要がある ● 他のデータが関係あるときに対応できない ● 1パック170円、3パック500円とか ● 場合わけの型が2つあるときれいにかけない ● どちらかの型に場合わけが必要 ● 業務処理では一箇所にすべての型の処理をまとめるほうがいい ● システム境界では他の型が関係することがすくないので継承が有効 ● OracleConnectionがMySQLConnectionを気にしたりとかはない

Slide 20

Slide 20 text

詳しくはWEB+DB PRESS vol.134 ● Javaだけど。 ● 在庫なしっぽいので、電子版を ● もしくは 「データ指向プログラミング」