SlideShare a Scribd company logo
1 of 59
Download to read offline
導入から10 年、PHP のtrait は滅びるべきなのか

その適切な使いどころと弱点、将来について
五十嵐進士/ sji / sj-i / @sji_ch
自己紹介
@sji_ch
SNS 上でのアイコンはGitHub が自動生成した奴
生まれも育ちも仙台
PHP カンファレンス仙台とかやった
ふつうのサラリーマン


株式会社インフィニットループ仙台支社所属
スマホゲーのサーバサイドプログラマ
二歳児の父
かわいい
絵本好き
最近わりと会話が成立する
WEB+DB PRESS の現PHP 連載担当
昨年6 月からWEB+DB PRESS のPHP 連載
だいたいわりと真面目な話をしてる
Agenda
trait とは
trait の性質
trait の使いどころ
trait の将来
その前に
PHP 8.2 に日本人が乱数拡張入れてたよ!
twitter のTL にRFC の話とphpcon の話と両方同時にでてきた
そうだ締め切り駆動でPHP のRFC も投げよう??
よしTrait で定数定義できるようにしたろ!
議論フェーズに目立った反対もない、これは勝つる、投票開始や
ちょ待てよ
ちょ
投票が始まってから吹き上がる反対
なんやかんやあって結局PHP 8.2 への取り込みはされました!
trait とは
trait ってこういうやつ
2012 年リリースのPHP 5.4 で導入
クラスへ追加するメンバーを切り出して定義
プロパティ、メソッド、定数(8.2から)を定義可能
クラスやtrait、Enum からuse
use 先へコピペされたよう振る舞う
直接インスタンスを作れない
複数trait を同時にuse できる
型宣言に使えない


trait T { // トレイトの定義

public string $property = self::class;

public function method(): void {

echo $this->property, PHP_EOL;

}

}

class C {
use T; // トレイトの利用

}
trait の来歴
もともとPHP 専用とかではない
2002 年にNathanael Schärli らがECOOP2002 向けに出した論文で提案
いくつかの言語でアイディアが取り入れられた
https://www.cs.cmu.edu/~aldrich/courses/819/Scha03aTraits.pdf
単一継承と多重継承
単一継承: 一つの親クラスしか持てない
多重継承: 複数の親クラスを持てる
それぞれ別の面倒くささがある
多重継承の反省からtraitが生まれた
ちなみに当初論文の案ではtraitは状態を持たなかった
多重継承は状態の衝突への対応が難しいので、あえて外されてた
プロパティが定義できるのはPHP が独自に入れた変更
元論文ではtrait がabstract で実装クラス側へアクセッサ提供を要求する形を提案
それだとボイラープレートが増えるので辛いとはみんな思ってた
アカデミアのほうでもStateful Traits のような拡張が後追いで提案された
https://link.springer.com/chapter/10.1007/978-3-540-71836-9_4
trait の性質
ソフトウェアの部品が満たすべき性質: 品質について
trait はクラスの部品
クラスはプログラムの部品
プログラムは部品を組み合わせて作る
良いプログラムは良い部品の良い組み合わせ方で作られる
良いといっても基準は色々
合目的性と言い換えるとスッキリ?
良さは品質とも呼ばれる
品質とは
バートランド・メイヤーさんの『オブジェクト指向入門第2
版原則・コンセプト』(訳:酒匂寛さん)は品質とはなんぞ
やで始まる
品質: 外的要因+ 内的要因
外的要因: 性能とか使いやすさとか、ユーザが認識する部分
内的要因: 外的要因の達成に必要な専門家だけが見る部分
達成すべきは目標は外的要因
品質の外的要因
正確さ
頑丈さ
拡張性
再利用性
互換性
効率性
可搬性
使いやすさ
機能性
適時性
そのほか(実証性、統合性、修復性、経済性)
品質要因のトレードオフ
機能を増やそうとしたらお金がかかるとか
バランスをとる必要がある
特に気にする部分
信頼性
正確さ
頑丈さ
モジュール性
拡張性
再利用性
正確さ
仕様で定義されているとおりに仕事を実行するソフトウェア製品の能力
ちゃんと動かないと全部が台無し
仕様を厳密に記述するというのがまず難しい
仕様への合致度を検証する方法も必要
小分けに関心を分離して「この範囲では正しい」という保証を重ねる
テストとか型とかアサーションとか
頑丈さ
異常な条件に対して適切に対応するソフトウェアシステムの能力
仕様に書かれてないからって鼻から悪魔が出ていいわけがない
エラー吐いてさっさと行儀よく終了してくれるほうが嬉しかったり
拡張性
仕様の変更に対するソフトウェア製品の適応のしやすさ
自然のなりゆきでは規模が大きくなるほど修正の影響を見積もりづらくなる
より設計を単純に
より構成する部品それぞれの独立性を高く
再利用性
多数多様なアプリケーションの構築に使うことのできる、ソフトウェア要素の能力
コードが減ると他の品質にコストを使えるようにもなる
5 つの基準、5 つの規則、5 つの原則
『オブジェクト指向入門』の重点はモジュール性(拡張性と再利用性)
モジュール性についての5 * 3 の15 の確認事項
5 つの基準(criteria)
部品の設計手法に求められるもの
分解しやすさ
組み合わせやすさ
分かりやすさ
連続性
保護性
5 つの規則(rule)
5 つの基準から導き出されるもの
部品の良さを保証するために守らねばならないルール
問題領域の直接的な写像であること
少ないインタフェース
小さなインタフェース
明示的なインタフェース
情報隠蔽
5 つの原則(principle)
5 つの基準と5 つの規則から導き出されるもの
ソフトウェア構築にあたって守るべき原則
言語としてのモジュール単位の原則
自己文書化の原則
統一形式の原則
開放/閉鎖の原則
単一責任選択の原則
trait の性質をあてはめてみる
5 つの基準から見るtrait
分解しやすさ: ○
組み合わせやすさ: ○
分かりやすさ: ☓
traitは利用クラスの中でメンバの名前空間を共有
自身の中にスコープの閉じたメンバを持てない
プロパティは名前衝突時に定義がマージ
自身の定義したプロパティを操作するだけで他部品の不変
条件が壊れる可能性がある
連続性: ○
保護性: △


trait HeightModifiable { // 身長操作trait

private int $value;

public function modifyHeight(int $value): void {

$this->value += $value

}

}

trait WeightModifiable { // 体重操作trait

private int $value;

public function modifyWeight(int $value): void {

$this->value += $value

}

}

class C { // わかりづらいことが起きる!

use HeightModifiable, WeightModifiable;

}
5 つの規則から見るtrait
問題領域の直接的な写像: ○
少ないインタフェース: △
小さいインタフェース: ☓
利用クラス内で全てのメンバへのアクセスが全開放
同居する他trait のメンバにも自由にアクセス
明示的なインタフェース: ☓
利用クラス側のprivate メンバへのアクセスさえ断りなく可能
プロパティの名前衝突のマージに問題がある場合も気づけない
情報隠蔽: ☓
trait local なメンバを定義できない
private / protected / public は利用クラス側の可視性としてコピペ展開される
5 つの原則とtrait
5 つの原則とtrait: 言語としてのモジュール単位の原則: ○
部品は使用される言語の構文単位として表されなければならないという原則
trait はまさにそれそのもの
5 つの原則とtrait: 自己文書化の原則: ☓
部品についてのすべての情報を部品の一部として持つようにするという原則
かなりクラスに近い表現力はある
PHP 8.2 からは定数定義もできる
「特定のinterface を実装するために使われるもの」をコメントでしか書けない
信頼性高く書けるクラスより弱い
5 つの原則とtrait: 統一形式アクセスの原則: △
プロパティの値を読み書きする時もメソッドを呼ぶ時も同じ表記を使うという原則
できないが、クラスもできないのでクラスより悪くはない
将来クラスで可能になればtrait でも可能になる
internals でProperty Accessors の議論を進めている人もいる
5 つの原則とtrait: 開放/閉鎖の原則: ☓
既存の部品への修正をせず部品を拡張できるという原則
abstract メソッドでtrait 中心の部品構成でも一応可能
interface 側とtrait 側で同じシグネチャを記述するようなこ
とが起きがち
特定のinterface を実装していることの要求をできるクラス
とくらべるとやや弱い


trait T1 {

abstract public function f1(): void;

public function f2(): void {

f1();

}

}

trait T2 {

use T1;

public function f1(): void { echo 'T2';}

}

trait T3 {

use T1;

public function f1(): void { echo 'T3';}

}
5 つの原則とtrait: 単一責任選択の原則: ☓
選択肢を提供する際、システム内の1 つの部品だけがその選択肢のすべてを把握すべきという原則
言語的にサポートされているとは言い難い
どのtrait を使うかが利用側の各クラスなどへ静的にuse で分散して埋め込まれる
use 先を分岐するような仕組みがtrait にはない
trait の性質まとめ
クラス(の継承)より良いところ
部品を小分けにして組み合わせられる
ただしDI / 合成が同等の能力
クラス(の継承)より悪いところ
意図しない部品間の干渉を防ぐ仕組みが弱い
interface が付けられない
trait の使いどころ
その前に前提として
DI (合成)で済むならそっちのほうがよい
DTO っぽいのにちょっとデータ取得メソッド生やしたいとか
にはDI より向く
他に頼れるやつがいない時に使う最終兵器


// これより

class C1 {

use FunctionalityTrait1;

use FunctionalityTrait2;

}

// クラスのDIにするほうが楽

class C2 {

public function __construct(

private FunctionalityClass1 $functionality1,

private FunctionalityClass2 $functionality2,

) {

}

}
インタフェースのデフォルト実装
リッチインタフェースを利用者が扱いやすい形で採用可能
利用コードへ影響を与えずにインタフェースをあとから拡張
可能
PSR-3 のLoggerAwareInterface とLoggerAwareTrait、
LoggerInterface とLoggerTrait など


interface HogeInterface {

public function method1(): void;

}

trait HogeDefaultImplementation {

public function method1(): void {

echo 'hoge';

}

}

class Hoge implements HogeInterface {

use HogeDefaultImplementation;

}
インタフェースとあわせての実質的な多重継承の実現
trait は型を伴わない実装
interface は実装を伴わない型
2 つあわせて(だいたい)多重継承


// 単一継承だとこういうのを小分けにできない

// traitなら小分けに分割できる

class P {

public function common_function(): void {}

// A、Bにのみ必要な機能がC、Dにも導入

public function ab_function(): void {}

// C、Dにのみ必要な機能がA、Bにも導入

public function cd_function(): void {}

}

class A extends P {}

class B extends P {}

class C extends P {}

class D extends P {}
クラスの分割実装
機械生成コードに手書きのコードを足したい場合などに嬉し
い
直接修正するとスキーマ変更時の再生成で上書きされる
ORM とかIDL からのコード生成とかへデータアクセス用の
処理をちょっと足したいとか


// 機械生成コードをクラス側に置く構成も可

trait MachineGeneratedCodes {

// 中略(機械生成されたコード)

}

// ↓別ファイルで定義

// 手書きコードをトレイト側に置く構成も可

class HandWrittenCodes {

use MachineGeneratedCodes;

// 中略(手書きのコード)

}
類似機能を持つ他言語からのコード移植
Java やKotlin のinterface のメソッドデフォルト実装
C++ やPython の多重継承
Scala やRust のtrait
C# のpartial
偶然同じ機能を持つクラスの実装の共通化
複数のクラスへ同じ機能を与えたい
が、同じ型を与えたいわけではない
Laravel のMacroable など
コードのユーザに複数クラスの統一インタフェースを提供したいだけの時
trait の将来
たぶんなくなることはない
アカンけど捨てるわけにもいかんよね、はtrait 定数のRFC で再確認できた
メンバの可視性を縛る方法とかinterface と紐付ける機能とかほしい
おしまい
- 宣伝- 

WEB+DB PRESS vol.130 のPHP 連載でも

trait の扱いについて書いてます!
このトークと被る部分もありつつ、切り口は違い、文章としてまとめてあります
興味があればぜひ
https://gihyo.jp/magazine/wdpress/archive/2022/vol130

More Related Content

What's hot

オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
Moriharu Ohzu
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろう
Kota Mizushima
 
イベント・ソーシングを知る
イベント・ソーシングを知るイベント・ソーシングを知る
イベント・ソーシングを知る
Shuhei Fujita
 

What's hot (20)

SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
 
マルチテナントのアプリケーション実装〜実践編〜
マルチテナントのアプリケーション実装〜実践編〜マルチテナントのアプリケーション実装〜実践編〜
マルチテナントのアプリケーション実装〜実践編〜
 
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計
 
SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
「速」を落とさないコードレビュー
「速」を落とさないコードレビュー「速」を落とさないコードレビュー
「速」を落とさないコードレビュー
 
エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
 
Redmine にいろいろ埋め込んでみた
Redmine にいろいろ埋め込んでみたRedmine にいろいろ埋め込んでみた
Redmine にいろいろ埋め込んでみた
 
型安全性入門
型安全性入門型安全性入門
型安全性入門
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
 
ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
 
ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装
 
オンラインゲームの仕組みと工夫
オンラインゲームの仕組みと工夫オンラインゲームの仕組みと工夫
オンラインゲームの仕組みと工夫
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろう
 
Docker Tokyo
Docker TokyoDocker Tokyo
Docker Tokyo
 
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかDDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
 
イベント・ソーシングを知る
イベント・ソーシングを知るイベント・ソーシングを知る
イベント・ソーシングを知る
 
WebSocket / WebRTCの技術紹介
WebSocket / WebRTCの技術紹介WebSocket / WebRTCの技術紹介
WebSocket / WebRTCの技術紹介
 

Similar to 導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について

なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い
なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い
なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い
sasezaki
 
Html5 でアプリを作るということ
Html5 でアプリを作るということHtml5 でアプリを作るということ
Html5 でアプリを作るということ
Naruto TAKAHASHI
 

Similar to 導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について (20)

スグにできる!Microsoft Flow でこんな連携あんな連携
スグにできる!Microsoft Flow でこんな連携あんな連携スグにできる!Microsoft Flow でこんな連携あんな連携
スグにできる!Microsoft Flow でこんな連携あんな連携
 
TFLite_and_PyTorch_Mobile
TFLite_and_PyTorch_MobileTFLite_and_PyTorch_Mobile
TFLite_and_PyTorch_Mobile
 
2015/10/17 第10回G-Study発表資料-あの日見たgit_hubなstarを君達はまだ知らない。
2015/10/17 第10回G-Study発表資料-あの日見たgit_hubなstarを君達はまだ知らない。2015/10/17 第10回G-Study発表資料-あの日見たgit_hubなstarを君達はまだ知らない。
2015/10/17 第10回G-Study発表資料-あの日見たgit_hubなstarを君達はまだ知らない。
 
Getting Started with Graph Database with Python
Getting Started with Graph Database with PythonGetting Started with Graph Database with Python
Getting Started with Graph Database with Python
 
今日からはじめるHTML5 ver.2012
今日からはじめるHTML5 ver.2012今日からはじめるHTML5 ver.2012
今日からはじめるHTML5 ver.2012
 
Bot × Office 365 〜 Microsoft Bot Framework と Microsoft Graph API を使った業務システムの新...
Bot × Office 365 〜 Microsoft Bot Framework と Microsoft Graph API を使った業務システムの新...Bot × Office 365 〜 Microsoft Bot Framework と Microsoft Graph API を使った業務システムの新...
Bot × Office 365 〜 Microsoft Bot Framework と Microsoft Graph API を使った業務システムの新...
 
業務の自動化をはじめよう!!
業務の自動化をはじめよう!!業務の自動化をはじめよう!!
業務の自動化をはじめよう!!
 
なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い
なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い
なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い
 
PHP 8 と V8 (JavaScript) で速さを見比べてみよう!
PHP 8 と V8 (JavaScript) で速さを見比べてみよう!PHP 8 と V8 (JavaScript) で速さを見比べてみよう!
PHP 8 と V8 (JavaScript) で速さを見比べてみよう!
 
Html5 でアプリを作るということ
Html5 でアプリを作るということHtml5 でアプリを作るということ
Html5 でアプリを作るということ
 
DartPad+CodePenで、Flutterを体験してみよう
DartPad+CodePenで、Flutterを体験してみようDartPad+CodePenで、Flutterを体験してみよう
DartPad+CodePenで、Flutterを体験してみよう
 
#phpmatsuri LT大会システムの中身
#phpmatsuri LT大会システムの中身#phpmatsuri LT大会システムの中身
#phpmatsuri LT大会システムの中身
 
PHP でファイルシステムを作ろう
PHP でファイルシステムを作ろうPHP でファイルシステムを作ろう
PHP でファイルシステムを作ろう
 
PHP 8 で Web 以外の世界の扉を叩く
PHP 8 で Web 以外の世界の扉を叩くPHP 8 で Web 以外の世界の扉を叩く
PHP 8 で Web 以外の世界の扉を叩く
 
Tizenリリースノート要約とhtml5アプリが動く仕組み
Tizenリリースノート要約とhtml5アプリが動く仕組みTizenリリースノート要約とhtml5アプリが動く仕組み
Tizenリリースノート要約とhtml5アプリが動く仕組み
 
ユーザ・デザイナーから見たPlone CMSのアピールポイント
ユーザ・デザイナーから見たPlone CMSのアピールポイントユーザ・デザイナーから見たPlone CMSのアピールポイント
ユーザ・デザイナーから見たPlone CMSのアピールポイント
 
Choreonoid+ros
Choreonoid+rosChoreonoid+ros
Choreonoid+ros
 
ML system design_pattern
ML system design_patternML system design_pattern
ML system design_pattern
 
YYPHP #13 初めてのコードレビュー
YYPHP #13 初めてのコードレビューYYPHP #13 初めてのコードレビュー
YYPHP #13 初めてのコードレビュー
 
Delphi開発者のためのSencha入門
Delphi開発者のためのSencha入門Delphi開発者のためのSencha入門
Delphi開発者のためのSencha入門
 

Recently uploaded

Recently uploaded (7)

Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 

導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について