SlideShare ist ein Scribd-Unternehmen logo
1 von 44
Downloaden Sie, um offline zu lesen
trait を使って
楽したい話
Infiniteloop Masaru - capy - Yamagishi 2014/08/01
こういう経験
ありませんか?
シングルトンするマネージャクラス作ったよ!
↓
じゃあその調子でもう一個同じようなの作って
↓
オーケー!楽勝だぜ!
/lib/managers/SomeManager.php
<?php
class SomeManager {
static private $_instance = null;
private function __construct() {}
public function getSomething() {
// ...
}
static public function getInstance() {
if (!isset(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
}
<?php
class OtherManager {
static private $_instance = null;
private function __construct() {}
public function getAnything() {
// ...
}
static public function getInstance() {
if (!isset(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
}
/lib/managers/SomeManager.php /lib/managers/OtherManager.php
コピペ
コピペ
コピペ
コピペ
コピペ
コピペ
コピペ
コピペ
<?php
class SomeManager {
static private $_instance = null;
private function __construct() {}
public function getSomething() {
// ...
}
static public function getInstance() {
if (!isset(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
}
<?php
class OtherManager {
static private $_instance = null;
private function __construct() {}
public function getAnything() {
// ...
}
static public function getInstance() {
if (!isset(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
}
/lib/managers/SomeManager.php /lib/managers/OtherManager.php
コピペ
コピペ
コピペ
コピペ
コピペ
コピペ
コピペ
コピペ
<?php
class SomeManager {
static private $_instance = null;
private function __construct() {}
public function getSomething() {
// ...
}
static public function getInstance() {
if (!isset(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
}
これを
trait
化すると
<?php
class SomeManager {
use Singletonnable;
public function getSomething() {
// ...
}
}
<?php
class OtherManager {
use Singletonnable;
public function getAnything() {
// ...
}
}
実際シンプル!!
/lib/managers/SomeManager.php /lib/managers/OtherManager.php
What is trait?
“トレイトは、単一継承の制約を減らすために作られたも
ので、 いくつかのメソッド群を異なるクラス階層にある
独立したクラスで再利用できるようにします。”
http://php.net/manual/ja/language.oop5.traits.php
ちなみに trait : 発音記号/tréɪt|tréɪ, tréɪt/【名詞】【可算名詞】(人・ものの)特性,特色,特徴.
つまり
コピペ代行
fin.
fin.
trait を調べると良く出てくる
サンプル
<?php
trait Singletonnable {
static private $_instance = null;
private function __construct() {}
static public function getInstance() {
if (!isset(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
}
Singleton trait
<?php
class SomeManager {
use Singletonnable;
public function getSomething() {
// ...
}
}
<?php
$mngr = SomeManager::getInstance();
$mngr->getSomething();
/lib/traits/Singletonnable.php /lib/managers/SomeManager.php
/main.php
適用
利用
usage
大体クラスと同じ
○ インターフェイスと異なり実装が出来る
○ 継承と異なり単体クラス内で複数のトレイトを利用出来る
○ トレイトを使うトレイトを実装出来る
○ メンバに abstract, static が使える
× トレイト実装に対して implement, extends, const は不可
× トレイトのインスタンス化は不可
optional usage
複数トレイトの利用で method 名が被った場合も、
などして衝突回避可能
重複メソッド(override)の優先順位は 現クラス実装->trait実装->親クラス実装
use TraitA, TraitB {
TraitA::methodA insteadof TraitB;
TraitB::methodC as methodM;
}
Why we use trait?
1. “複数クラスで実装される同一機能”を単位化し、再利用可能にする
<?php
// シングルトンデザインパターンは共通の機能
SomeClass::getInstance();
OtherClass::getInstance();
// 何かの抽選はガチャやドロップ品などのランダム要素で共通の機能
$got_item_id = $gacha->lot($lot_item_list);
$got_item_id = $drop_reward->lot($lot_item_list);
// DB取得や設定はDBのレコード一行を保持するクラスで共通の機能
// マジックメソッドでうまいことやったり
$user_name = $user_table->getUserName();
$unit_attack = $unit_table->getAttack();
Why we use trait?
2. 共通機能を抜き出すことでメンテナンス性の向上
こんなコードがいくつかのクラスにあったとして、
「randではなくmt_randを使うように変更」
となった場合に、traitで抜き出しておけば 一か所の変更 でOK
function lot($item_list) {
$r = rand(0, count($item_list) - 1);
foreach ($item_list as $key => $item) {
if ($key == $r) { return $item; }
}
}
要するに
コピペ代行
Why we use insteadof delegate?
trait で出来ることは、委譲や静的メソッドでも実装出来る
<?php
class Player {
private $attacker;
public function __construct() {
$attacker = new Attacker();
}
public function attackTo($to) {
$attacker->attack($to);
}
}
<?php
class Player {
public function attackTo($to) {
Attacker::attack($this, $to);
}
}
でも
めんどくさいじゃん
コピペ代行
に任せればいいじゃん
When we use trait?
共通に使える単機能をパーツ化して、クラスにガチャコンするイメージ
a. デザインパターンの実装(singleton, composite, …)
b. 様々な場所で使われる処理(DBアクセス、バリデート、特定データ保持…)
c. 上記機能を提供するようなフレームワーク・ライブラリ作成
(CakePHP3は trait が活用されているそうです)
Implements Design Pattern
パターン化された処理の実装
<?php
trait Compositable {
private $_childs = [];
public function addChild($child) {
$this->_childs[] = $child;
}
public function removeChild($child) {
foreach ($i = 0; $i < count($this->_childs); $i++) {
if ($this->_childs[$i] === $child) {
$this->_childs = array_splice($this->_childs, $i, 1);
break;
}
}
}
}
<?php
trait Observable {
private $_listeners = [];
public function addListener($listener) {
$this->_listeners[] = $listener;
}
public function notify() {
foreach ($this->_listeners as $listener) {
$listener->notified();
}
}
}
Implements Common Behavior
様々な場所で使われるライブラリ的な振る舞いの実装
<?php
trait Queriable {
private $_db_accessor;
private function query($select, $from, $where, $option = '') {
if (!isset($this->_db_accessor)) {
$this->_db_accessor = DatabaseAccessor::getInstance();
}
// クエリを投げる処理...
}
}
<?php
trait Loggable {
private function logError($str, $throw_exception = false) {
// ログを出力したり、例外を排出したり
}
}
Summary of trait
ソースコードをコピペしようとした時に
「これって trait になりませんか?(CV:八嶋智人)」
と考えてみる
※ 但し PHP 5.4 以降に限る
P.S. Solarized colorscheme
http://ethanschoonover.com/solarized
P.S. Solarized colorscheme
P.S. Solarized colorscheme
色々なエディタ・ターミナル用の設定が配布中
• vim
• emacs
• IntelliJ IDEA
• NetBeans
• Visual Studio
• Xcode
• iTeam2
• OS X Terminal.app
• …
fin.
※
When we shouldn’t use trait?
trait はオブジェクト指向的な「関係」を構築しない
あくまで「水平方向」での拡張
trait は
abstract class / interface
を置き換えうる?
trait replaces ‘abstract class’
Template Method デザインパターンは trait で十分
<?php
trait GachaPlayer {
private $lot_items = array();
private $elected = null;
public function lot() {
$this->setLotItems();
$this->lot();
return $this->elected;
abstract private function setLotItems();
private function lot() { /* 抽選する処理 */ }
}
class BattleGachaPlayer {
use GachaPlayer;
private function setLotItems() { /* バトル用の抽選データ設定 */ }
}
class AdventureGachaPlayer {
use GachaPlayer;
private function setLotItems() { /* 冒険用の抽選データ設定 */ }
}
trait replaces ‘abstract class’?
但し、「機能を再利用するための継承」ではなく、「オブジェクトの派生と
しての継承(本質的)」の場合は使わない方が良い
(オブジェクト指向の考え方の問題)
<?php
abstract class CharacterJob {
private $job_name;
public function acquireSkill($skill_type) { /* ... */ }
public function addExperience($amount) { /* ... */ }
// ...
}
class WarriorJob extends CharacterJob {
const SKILL_TYPE_SLASH = 1;
// ...
}
trait > extends
PHPの継承は「多重継承」が出来ない
<?php
class Singletonnable { /* ... */ }
class WorldMapBase { /* ... */ }
class DQ1WorldMap extends Singletonnable, WorldMapBase {
// ...
}
trait > implements
PHPのインターフェイスは「実装」が出来ない
<?php
interface Singletonnable {
static public function getInstance();
}
class SomeManager implements Singletonnable {
static public function getInstance() {
// 結局実装しないといけない
}
}
class OtherManager implements Singletonnable {
static public function getInstance() {
// 結局実装しないといけない
}
}
trait > static
クラス間の依存性が高まり保守性に欠ける
<?php
final class SomeManager {
static public getSomeDataList($data_type) {
// ...
}
}
class SomeProcessor {
public function process() {
// 引数が変わる?スコープ変わってアクセス出来なくなる?
$data = SomeManager::getSomeDataList(DATA_TYPE_SOMETHING);
}
}
逆に
extends > trait
定数を持てない
インターフェイスを implement 出来ない
タイプヒントに使えない
トレイト自身をインスタンス化出来ない
<?php
trait SomeFunc implements SomeInterface {
const SOME_DATA = 'somesome';
public function someInterfaceMethod() { }
}
function getSomeFunc(SomeFunc some) {
some->someInterfaceMethod();
}
SomeFunc::SOME_DATA;
implements > trait
絶対にそこで実装しなければならないメソッドを定義出来ない
※ trait は “実装付きインターフェイス” とも呼べる
http://stackoverflow.com/questions/9205083/php-traits-vs-interfaces
<?php
interface SomeInterface {
public function SomeInterfaceMethod();
}
trait SomeTrait {
public function SomeTraitMethod() { /* ... */ }
}
class SomeClass implements SomeInterface {
use SomeTrait;
public function SomeInterfaceMethod() { /* must implement */ }
public function SomeTraitMethod() { /* don’t have to implement */ }
}
static > trait
同一 trait を使っても、変数を共有出来るわけではない

Weitere ähnliche Inhalte

Was ist angesagt?

レガシーコード改善のススメ
レガシーコード改善のススメレガシーコード改善のススメ
レガシーコード改善のススメAkira Hirasawa
 
Spring bootでweb バリデート編
Spring bootでweb バリデート編Spring bootでweb バリデート編
Spring bootでweb バリデート編なべ
 
オブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメオブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメYoji Kanno
 
OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話Daichi Koike
 
オブジェクト指向プログラミングのためのモデリング入門
オブジェクト指向プログラミングのためのモデリング入門オブジェクト指向プログラミングのためのモデリング入門
オブジェクト指向プログラミングのためのモデリング入門増田 亨
 
決済サービスのSpring Bootのバージョンを2系に上げた話
決済サービスのSpring Bootのバージョンを2系に上げた話決済サービスのSpring Bootのバージョンを2系に上げた話
決済サービスのSpring Bootのバージョンを2系に上げた話Ryosuke Uchitate
 
Spring Boot × Vue.jsでSPAを作る
Spring Boot × Vue.jsでSPAを作るSpring Boot × Vue.jsでSPAを作る
Spring Boot × Vue.jsでSPAを作るGo Miyasaka
 
モジュールの凝集度・結合度・インタフェース
モジュールの凝集度・結合度・インタフェースモジュールの凝集度・結合度・インタフェース
モジュールの凝集度・結合度・インタフェースHajime Yanagawa
 
怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション土岐 孝平
 
Scalaで型クラス入門
Scalaで型クラス入門Scalaで型クラス入門
Scalaで型クラス入門Makoto Fukuhara
 
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Springドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring増田 亨
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーyoku0825
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろうKota Mizushima
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪Takuto Wada
 
Laravel の paginate は一体何をやっているのか
Laravel の paginate は一体何をやっているのかLaravel の paginate は一体何をやっているのか
Laravel の paginate は一体何をやっているのかShohei Okada
 
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みJavaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みChihiro Ito
 
はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)Masatoshi Tada
 
今から始める Lens/Prism
今から始める Lens/Prism今から始める Lens/Prism
今から始める Lens/PrismNaoki Aoyama
 
Java開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovyJava開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovyYasuharu Nakano
 
社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPI社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPIAkihiro Ikezoe
 

Was ist angesagt? (20)

レガシーコード改善のススメ
レガシーコード改善のススメレガシーコード改善のススメ
レガシーコード改善のススメ
 
Spring bootでweb バリデート編
Spring bootでweb バリデート編Spring bootでweb バリデート編
Spring bootでweb バリデート編
 
オブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメオブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメ
 
OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
 
オブジェクト指向プログラミングのためのモデリング入門
オブジェクト指向プログラミングのためのモデリング入門オブジェクト指向プログラミングのためのモデリング入門
オブジェクト指向プログラミングのためのモデリング入門
 
決済サービスのSpring Bootのバージョンを2系に上げた話
決済サービスのSpring Bootのバージョンを2系に上げた話決済サービスのSpring Bootのバージョンを2系に上げた話
決済サービスのSpring Bootのバージョンを2系に上げた話
 
Spring Boot × Vue.jsでSPAを作る
Spring Boot × Vue.jsでSPAを作るSpring Boot × Vue.jsでSPAを作る
Spring Boot × Vue.jsでSPAを作る
 
モジュールの凝集度・結合度・インタフェース
モジュールの凝集度・結合度・インタフェースモジュールの凝集度・結合度・インタフェース
モジュールの凝集度・結合度・インタフェース
 
怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション
 
Scalaで型クラス入門
Scalaで型クラス入門Scalaで型クラス入門
Scalaで型クラス入門
 
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Springドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキー
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろう
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
Laravel の paginate は一体何をやっているのか
Laravel の paginate は一体何をやっているのかLaravel の paginate は一体何をやっているのか
Laravel の paginate は一体何をやっているのか
 
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みJavaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組み
 
はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)
 
今から始める Lens/Prism
今から始める Lens/Prism今から始める Lens/Prism
今から始める Lens/Prism
 
Java開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovyJava開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovy
 
社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPI社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPI
 

Andere mochten auch

Trait とは? その使い道を考えてみる
Trait とは? その使い道を考えてみるTrait とは? その使い道を考えてみる
Trait とは? その使い道を考えてみるTakuya Fujimura
 
PSR-1 と PSR-2 を 5分でざっくり理解する
PSR-1 と PSR-2 を5分でざっくり理解するPSR-1 と PSR-2 を5分でざっくり理解する
PSR-1 と PSR-2 を 5分でざっくり理解するWataru Terada
 
第7回こども病院移転計画調査委員会資料
第7回こども病院移転計画調査委員会資料第7回こども病院移転計画調査委員会資料
第7回こども病院移転計画調査委員会資料f_kodomo
 
Twilio を使えば簡単にできる アプリケーションと電話/SMS連携
Twilio を使えば簡単にできる アプリケーションと電話/SMS連携Twilio を使えば簡単にできる アプリケーションと電話/SMS連携
Twilio を使えば簡単にできる アプリケーションと電話/SMS連携Masashi Shinbara
 
Laravelのeloquent だけ入れた話
Laravelのeloquent だけ入れた話Laravelのeloquent だけ入れた話
Laravelのeloquent だけ入れた話Masataka Kono
 
新標準PSRに学ぶきれいなPHP
新標準PSRに学ぶきれいなPHP新標準PSRに学ぶきれいなPHP
新標準PSRに学ぶきれいなPHPYusuke Ando
 
【ハンズオン】初めてのUnityで作る「3D野球盤」_"8a1"20150204発表資料
【ハンズオン】初めてのUnityで作る「3D野球盤」_"8a1"20150204発表資料【ハンズオン】初めてのUnityで作る「3D野球盤」_"8a1"20150204発表資料
【ハンズオン】初めてのUnityで作る「3D野球盤」_"8a1"20150204発表資料8a1
 
Composer による依存管理 と Packagist によるライブラリの公開
Composer による依存管理 と Packagist によるライブラリの公開Composer による依存管理 と Packagist によるライブラリの公開
Composer による依存管理 と Packagist によるライブラリの公開Shogo Kawahara
 
先取り!PHP 7 と WordPress
先取り!PHP 7 と WordPress先取り!PHP 7 と WordPress
先取り!PHP 7 と WordPressMasashi Shinbara
 
東京から沖縄に移住したからこそわかるクラウドとコミュニティの有り難み 〜人はもっと自由になれる〜
東京から沖縄に移住したからこそわかるクラウドとコミュニティの有り難み 〜人はもっと自由になれる〜東京から沖縄に移住したからこそわかるクラウドとコミュニティの有り難み 〜人はもっと自由になれる〜
東京から沖縄に移住したからこそわかるクラウドとコミュニティの有り難み 〜人はもっと自由になれる〜龍治 常盤木
 
NetBeans、FuelPHP と過ごしたこの 2 ヶ月
NetBeans、FuelPHP と過ごしたこの 2 ヶ月NetBeans、FuelPHP と過ごしたこの 2 ヶ月
NetBeans、FuelPHP と過ごしたこの 2 ヶ月suno88
 
はじめて作ったアプリが10,000ダウンロード達成したから自慢する
はじめて作ったアプリが10,000ダウンロード達成したから自慢するはじめて作ったアプリが10,000ダウンロード達成したから自慢する
はじめて作ったアプリが10,000ダウンロード達成したから自慢するNatsumi Oki
 
SwiftとReactNativeで似たようなUIを作った際の記録
SwiftとReactNativeで似たようなUIを作った際の記録SwiftとReactNativeで似たようなUIを作った際の記録
SwiftとReactNativeで似たようなUIを作った際の記録Fumiya Sakai
 
Electronで社内ツールを作ったお話
Electronで社内ツールを作ったお話Electronで社内ツールを作ったお話
Electronで社内ツールを作ったお話sters
 
レイヤードアーキテクチャを意識した PHPアプリケーションの構築 ver2
レイヤードアーキテクチャを意識した PHPアプリケーションの構築 ver2レイヤードアーキテクチャを意識した PHPアプリケーションの構築 ver2
レイヤードアーキテクチャを意識した PHPアプリケーションの構築 ver2Masashi Shinbara
 
Docker ComposeでMastodonが必要なものを梱包する話
Docker ComposeでMastodonが必要なものを梱包する話Docker ComposeでMastodonが必要なものを梱包する話
Docker ComposeでMastodonが必要なものを梱包する話Masahito Zembutsu
 

Andere mochten auch (19)

Trait とは? その使い道を考えてみる
Trait とは? その使い道を考えてみるTrait とは? その使い道を考えてみる
Trait とは? その使い道を考えてみる
 
PSR-1 と PSR-2 を 5分でざっくり理解する
PSR-1 と PSR-2 を5分でざっくり理解するPSR-1 と PSR-2 を5分でざっくり理解する
PSR-1 と PSR-2 を 5分でざっくり理解する
 
第7回こども病院移転計画調査委員会資料
第7回こども病院移転計画調査委員会資料第7回こども病院移転計画調査委員会資料
第7回こども病院移転計画調査委員会資料
 
Twilio を使えば簡単にできる アプリケーションと電話/SMS連携
Twilio を使えば簡単にできる アプリケーションと電話/SMS連携Twilio を使えば簡単にできる アプリケーションと電話/SMS連携
Twilio を使えば簡単にできる アプリケーションと電話/SMS連携
 
Laravelのeloquent だけ入れた話
Laravelのeloquent だけ入れた話Laravelのeloquent だけ入れた話
Laravelのeloquent だけ入れた話
 
新標準PSRに学ぶきれいなPHP
新標準PSRに学ぶきれいなPHP新標準PSRに学ぶきれいなPHP
新標準PSRに学ぶきれいなPHP
 
【ハンズオン】初めてのUnityで作る「3D野球盤」_"8a1"20150204発表資料
【ハンズオン】初めてのUnityで作る「3D野球盤」_"8a1"20150204発表資料【ハンズオン】初めてのUnityで作る「3D野球盤」_"8a1"20150204発表資料
【ハンズオン】初めてのUnityで作る「3D野球盤」_"8a1"20150204発表資料
 
Composer による依存管理 と Packagist によるライブラリの公開
Composer による依存管理 と Packagist によるライブラリの公開Composer による依存管理 と Packagist によるライブラリの公開
Composer による依存管理 と Packagist によるライブラリの公開
 
先取り!PHP 7 と WordPress
先取り!PHP 7 と WordPress先取り!PHP 7 と WordPress
先取り!PHP 7 と WordPress
 
東京から沖縄に移住したからこそわかるクラウドとコミュニティの有り難み 〜人はもっと自由になれる〜
東京から沖縄に移住したからこそわかるクラウドとコミュニティの有り難み 〜人はもっと自由になれる〜東京から沖縄に移住したからこそわかるクラウドとコミュニティの有り難み 〜人はもっと自由になれる〜
東京から沖縄に移住したからこそわかるクラウドとコミュニティの有り難み 〜人はもっと自由になれる〜
 
Play jjug2012spring
Play jjug2012springPlay jjug2012spring
Play jjug2012spring
 
NetBeans、FuelPHP と過ごしたこの 2 ヶ月
NetBeans、FuelPHP と過ごしたこの 2 ヶ月NetBeans、FuelPHP と過ごしたこの 2 ヶ月
NetBeans、FuelPHP と過ごしたこの 2 ヶ月
 
はじめて作ったアプリが10,000ダウンロード達成したから自慢する
はじめて作ったアプリが10,000ダウンロード達成したから自慢するはじめて作ったアプリが10,000ダウンロード達成したから自慢する
はじめて作ったアプリが10,000ダウンロード達成したから自慢する
 
SwiftとReactNativeで似たようなUIを作った際の記録
SwiftとReactNativeで似たようなUIを作った際の記録SwiftとReactNativeで似たようなUIを作った際の記録
SwiftとReactNativeで似たようなUIを作った際の記録
 
DMMの闇に触れた話
DMMの闇に触れた話DMMの闇に触れた話
DMMの闇に触れた話
 
Electronで社内ツールを作ったお話
Electronで社内ツールを作ったお話Electronで社内ツールを作ったお話
Electronで社内ツールを作ったお話
 
レイヤードアーキテクチャを意識した PHPアプリケーションの構築 ver2
レイヤードアーキテクチャを意識した PHPアプリケーションの構築 ver2レイヤードアーキテクチャを意識した PHPアプリケーションの構築 ver2
レイヤードアーキテクチャを意識した PHPアプリケーションの構築 ver2
 
Docker ComposeでMastodonが必要なものを梱包する話
Docker ComposeでMastodonが必要なものを梱包する話Docker ComposeでMastodonが必要なものを梱包する話
Docker ComposeでMastodonが必要なものを梱包する話
 
コンテンツ作りの三原則
コンテンツ作りの三原則コンテンツ作りの三原則
コンテンツ作りの三原則
 

Ähnlich wie traitを使って楽したい話

Web技術勉強会 20100925
Web技術勉強会 20100925Web技術勉強会 20100925
Web技術勉強会 20100925龍一 田中
 
第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」yoshiaki iwanaga
 
WordPress のキャッシュ機構
WordPress のキャッシュ機構WordPress のキャッシュ機構
WordPress のキャッシュ機構katanyan
 
Best practice laravel
Best practice laravelBest practice laravel
Best practice laravelRisa Ohnishi
 
再考:列挙型
再考:列挙型再考:列挙型
再考:列挙型do_aki
 
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in TokyoGrails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in TokyoTsuyoshi Yamamoto
 
「Html sql」で図書館hpにアクセスしてみよう
「Html sql」で図書館hpにアクセスしてみよう「Html sql」で図書館hpにアクセスしてみよう
「Html sql」で図書館hpにアクセスしてみようKentaro Matsui
 
PHP Object Injection入門
PHP Object Injection入門PHP Object Injection入門
PHP Object Injection入門Yu Iwama
 
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」Tsuyoshi Yamamoto
 
pi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピングpi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピングkunihikokaneko1
 
速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-Kazunari Hara
 
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)Hiroaki KOBAYASHI
 
Backbone model collection (jscafe 8)
Backbone model collection (jscafe 8)Backbone model collection (jscafe 8)
Backbone model collection (jscafe 8)Ryuma Tsukano
 

Ähnlich wie traitを使って楽したい話 (20)

Web技術勉強会 20100925
Web技術勉強会 20100925Web技術勉強会 20100925
Web技術勉強会 20100925
 
OSC京都2011
OSC京都2011OSC京都2011
OSC京都2011
 
Testman
TestmanTestman
Testman
 
第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」
 
WordPress のキャッシュ機構
WordPress のキャッシュ機構WordPress のキャッシュ機構
WordPress のキャッシュ機構
 
Best practice laravel
Best practice laravelBest practice laravel
Best practice laravel
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
再考:列挙型
再考:列挙型再考:列挙型
再考:列挙型
 
Try Jetpack
Try JetpackTry Jetpack
Try Jetpack
 
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in TokyoGrails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
 
「Html sql」で図書館hpにアクセスしてみよう
「Html sql」で図書館hpにアクセスしてみよう「Html sql」で図書館hpにアクセスしてみよう
「Html sql」で図書館hpにアクセスしてみよう
 
PHP Object Injection入門
PHP Object Injection入門PHP Object Injection入門
PHP Object Injection入門
 
JSクラス定義
JSクラス定義JSクラス定義
JSクラス定義
 
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」
 
emc++ chapter32
emc++ chapter32emc++ chapter32
emc++ chapter32
 
pi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピングpi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピング
 
速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-
 
Inside Movable Type
Inside Movable TypeInside Movable Type
Inside Movable Type
 
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
 
Backbone model collection (jscafe 8)
Backbone model collection (jscafe 8)Backbone model collection (jscafe 8)
Backbone model collection (jscafe 8)
 

Mehr von infinite_loop

ChatGPT触ってみた
ChatGPT触ってみたChatGPT触ってみた
ChatGPT触ってみたinfinite_loop
 
社内ソフトスキルを考える
社内ソフトスキルを考える社内ソフトスキルを考える
社内ソフトスキルを考えるinfinite_loop
 
3Dプリンタって いいね
3Dプリンタって いいね3Dプリンタって いいね
3Dプリンタって いいねinfinite_loop
 
VRChatでお酒が注げる飲み物アセットの紹介
VRChatでお酒が注げる飲み物アセットの紹介VRChatでお酒が注げる飲み物アセットの紹介
VRChatでお酒が注げる飲み物アセットの紹介infinite_loop
 
アニメーションとスキニングをBurstで独自実装する.pdf
アニメーションとスキニングをBurstで独自実装する.pdfアニメーションとスキニングをBurstで独自実装する.pdf
アニメーションとスキニングをBurstで独自実装する.pdfinfinite_loop
 
I ❤ Virtual Machines 仮想環境をより便利に使うツールたち
I ❤ Virtual Machines 仮想環境をより便利に使うツールたちI ❤ Virtual Machines 仮想環境をより便利に使うツールたち
I ❤ Virtual Machines 仮想環境をより便利に使うツールたちinfinite_loop
 
500万行のPHPプロジェクトにおけるログ出力の歩み
500万行のPHPプロジェクトにおけるログ出力の歩み500万行のPHPプロジェクトにおけるログ出力の歩み
500万行のPHPプロジェクトにおけるログ出力の歩みinfinite_loop
 
ADRという考えを取り入れてみて
ADRという考えを取り入れてみてADRという考えを取り入れてみて
ADRという考えを取り入れてみてinfinite_loop
 
リファクタリングで実装が○○分短縮した話
リファクタリングで実装が○○分短縮した話リファクタリングで実装が○○分短縮した話
リファクタリングで実装が○○分短縮した話infinite_loop
 
ゲームのインフラをAwsで実戦tips全て見せます
ゲームのインフラをAwsで実戦tips全て見せますゲームのインフラをAwsで実戦tips全て見せます
ゲームのインフラをAwsで実戦tips全て見せますinfinite_loop
 
楽しいVR空間を作る技術と支える技術 #osc19do
楽しいVR空間を作る技術と支える技術 #osc19do楽しいVR空間を作る技術と支える技術 #osc19do
楽しいVR空間を作る技術と支える技術 #osc19doinfinite_loop
 
Start rl with_unity_machine_learning_agents
Start rl with_unity_machine_learning_agentsStart rl with_unity_machine_learning_agents
Start rl with_unity_machine_learning_agentsinfinite_loop
 
がんばれ PHP Fiber
がんばれ PHP Fiberがんばれ PHP Fiber
がんばれ PHP Fiberinfinite_loop
 
心に残った名前ランキング
心に残った名前ランキング心に残った名前ランキング
心に残った名前ランキングinfinite_loop
 
プログラムと名前にまつわる座談会
プログラムと名前にまつわる座談会プログラムと名前にまつわる座談会
プログラムと名前にまつわる座談会infinite_loop
 
名は体を表していますか
名は体を表していますか名は体を表していますか
名は体を表していますかinfinite_loop
 
大切な名前[Intro]公開版
大切な名前[Intro]公開版大切な名前[Intro]公開版
大切な名前[Intro]公開版infinite_loop
 
JupyterNotebookとMySQLでゼロからはじめるデータサイエンス
JupyterNotebookとMySQLでゼロからはじめるデータサイエンスJupyterNotebookとMySQLでゼロからはじめるデータサイエンス
JupyterNotebookとMySQLでゼロからはじめるデータサイエンスinfinite_loop
 

Mehr von infinite_loop (20)

ChatGPT触ってみた
ChatGPT触ってみたChatGPT触ってみた
ChatGPT触ってみた
 
社内ソフトスキルを考える
社内ソフトスキルを考える社内ソフトスキルを考える
社内ソフトスキルを考える
 
3Dプリンタって いいね
3Dプリンタって いいね3Dプリンタって いいね
3Dプリンタって いいね
 
VRChatでお酒が注げる飲み物アセットの紹介
VRChatでお酒が注げる飲み物アセットの紹介VRChatでお酒が注げる飲み物アセットの紹介
VRChatでお酒が注げる飲み物アセットの紹介
 
アニメーションとスキニングをBurstで独自実装する.pdf
アニメーションとスキニングをBurstで独自実装する.pdfアニメーションとスキニングをBurstで独自実装する.pdf
アニメーションとスキニングをBurstで独自実装する.pdf
 
I ❤ Virtual Machines 仮想環境をより便利に使うツールたち
I ❤ Virtual Machines 仮想環境をより便利に使うツールたちI ❤ Virtual Machines 仮想環境をより便利に使うツールたち
I ❤ Virtual Machines 仮想環境をより便利に使うツールたち
 
500万行のPHPプロジェクトにおけるログ出力の歩み
500万行のPHPプロジェクトにおけるログ出力の歩み500万行のPHPプロジェクトにおけるログ出力の歩み
500万行のPHPプロジェクトにおけるログ出力の歩み
 
ADRという考えを取り入れてみて
ADRという考えを取り入れてみてADRという考えを取り入れてみて
ADRという考えを取り入れてみて
 
リファクタリングで実装が○○分短縮した話
リファクタリングで実装が○○分短縮した話リファクタリングで実装が○○分短縮した話
リファクタリングで実装が○○分短縮した話
 
ゲームのインフラをAwsで実戦tips全て見せます
ゲームのインフラをAwsで実戦tips全て見せますゲームのインフラをAwsで実戦tips全て見せます
ゲームのインフラをAwsで実戦tips全て見せます
 
楽しいVR空間を作る技術と支える技術 #osc19do
楽しいVR空間を作る技術と支える技術 #osc19do楽しいVR空間を作る技術と支える技術 #osc19do
楽しいVR空間を作る技術と支える技術 #osc19do
 
Start rl with_unity_machine_learning_agents
Start rl with_unity_machine_learning_agentsStart rl with_unity_machine_learning_agents
Start rl with_unity_machine_learning_agents
 
UniRx の1歩目
UniRx の1歩目UniRx の1歩目
UniRx の1歩目
 
がんばれ PHP Fiber
がんばれ PHP Fiberがんばれ PHP Fiber
がんばれ PHP Fiber
 
心に残った名前ランキング
心に残った名前ランキング心に残った名前ランキング
心に残った名前ランキング
 
プログラムと名前にまつわる座談会
プログラムと名前にまつわる座談会プログラムと名前にまつわる座談会
プログラムと名前にまつわる座談会
 
名は体を表していますか
名は体を表していますか名は体を表していますか
名は体を表していますか
 
名前の力
名前の力名前の力
名前の力
 
大切な名前[Intro]公開版
大切な名前[Intro]公開版大切な名前[Intro]公開版
大切な名前[Intro]公開版
 
JupyterNotebookとMySQLでゼロからはじめるデータサイエンス
JupyterNotebookとMySQLでゼロからはじめるデータサイエンスJupyterNotebookとMySQLでゼロからはじめるデータサイエンス
JupyterNotebookとMySQLでゼロからはじめるデータサイエンス
 

Kürzlich hochgeladen

論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 

Kürzlich hochgeladen (9)

論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 

traitを使って楽したい話

  • 3. シングルトンするマネージャクラス作ったよ! ↓ じゃあその調子でもう一個同じようなの作って ↓ オーケー!楽勝だぜ! /lib/managers/SomeManager.php <?php class SomeManager { static private $_instance = null; private function __construct() {} public function getSomething() { // ... } static public function getInstance() { if (!isset(self::$_instance)) { self::$_instance = new self(); } return self::$_instance; } }
  • 4. <?php class OtherManager { static private $_instance = null; private function __construct() {} public function getAnything() { // ... } static public function getInstance() { if (!isset(self::$_instance)) { self::$_instance = new self(); } return self::$_instance; } } /lib/managers/SomeManager.php /lib/managers/OtherManager.php コピペ コピペ コピペ コピペ コピペ コピペ コピペ コピペ <?php class SomeManager { static private $_instance = null; private function __construct() {} public function getSomething() { // ... } static public function getInstance() { if (!isset(self::$_instance)) { self::$_instance = new self(); } return self::$_instance; } }
  • 5. <?php class OtherManager { static private $_instance = null; private function __construct() {} public function getAnything() { // ... } static public function getInstance() { if (!isset(self::$_instance)) { self::$_instance = new self(); } return self::$_instance; } } /lib/managers/SomeManager.php /lib/managers/OtherManager.php コピペ コピペ コピペ コピペ コピペ コピペ コピペ コピペ <?php class SomeManager { static private $_instance = null; private function __construct() {} public function getSomething() { // ... } static public function getInstance() { if (!isset(self::$_instance)) { self::$_instance = new self(); } return self::$_instance; } }
  • 7. <?php class SomeManager { use Singletonnable; public function getSomething() { // ... } } <?php class OtherManager { use Singletonnable; public function getAnything() { // ... } } 実際シンプル!! /lib/managers/SomeManager.php /lib/managers/OtherManager.php
  • 8. What is trait? “トレイトは、単一継承の制約を減らすために作られたも ので、 いくつかのメソッド群を異なるクラス階層にある 独立したクラスで再利用できるようにします。” http://php.net/manual/ja/language.oop5.traits.php ちなみに trait : 発音記号/tréɪt|tréɪ, tréɪt/【名詞】【可算名詞】(人・ものの)特性,特色,特徴.
  • 11. fin.
  • 12. fin.
  • 14. <?php trait Singletonnable { static private $_instance = null; private function __construct() {} static public function getInstance() { if (!isset(self::$_instance)) { self::$_instance = new self(); } return self::$_instance; } } Singleton trait <?php class SomeManager { use Singletonnable; public function getSomething() { // ... } } <?php $mngr = SomeManager::getInstance(); $mngr->getSomething(); /lib/traits/Singletonnable.php /lib/managers/SomeManager.php /main.php 適用 利用
  • 15. usage 大体クラスと同じ ○ インターフェイスと異なり実装が出来る ○ 継承と異なり単体クラス内で複数のトレイトを利用出来る ○ トレイトを使うトレイトを実装出来る ○ メンバに abstract, static が使える × トレイト実装に対して implement, extends, const は不可 × トレイトのインスタンス化は不可
  • 16. optional usage 複数トレイトの利用で method 名が被った場合も、 などして衝突回避可能 重複メソッド(override)の優先順位は 現クラス実装->trait実装->親クラス実装 use TraitA, TraitB { TraitA::methodA insteadof TraitB; TraitB::methodC as methodM; }
  • 17. Why we use trait? 1. “複数クラスで実装される同一機能”を単位化し、再利用可能にする <?php // シングルトンデザインパターンは共通の機能 SomeClass::getInstance(); OtherClass::getInstance(); // 何かの抽選はガチャやドロップ品などのランダム要素で共通の機能 $got_item_id = $gacha->lot($lot_item_list); $got_item_id = $drop_reward->lot($lot_item_list); // DB取得や設定はDBのレコード一行を保持するクラスで共通の機能 // マジックメソッドでうまいことやったり $user_name = $user_table->getUserName(); $unit_attack = $unit_table->getAttack();
  • 18. Why we use trait? 2. 共通機能を抜き出すことでメンテナンス性の向上 こんなコードがいくつかのクラスにあったとして、 「randではなくmt_randを使うように変更」 となった場合に、traitで抜き出しておけば 一か所の変更 でOK function lot($item_list) { $r = rand(0, count($item_list) - 1); foreach ($item_list as $key => $item) { if ($key == $r) { return $item; } } }
  • 21. Why we use insteadof delegate? trait で出来ることは、委譲や静的メソッドでも実装出来る <?php class Player { private $attacker; public function __construct() { $attacker = new Attacker(); } public function attackTo($to) { $attacker->attack($to); } } <?php class Player { public function attackTo($to) { Attacker::attack($this, $to); } }
  • 25. When we use trait? 共通に使える単機能をパーツ化して、クラスにガチャコンするイメージ a. デザインパターンの実装(singleton, composite, …) b. 様々な場所で使われる処理(DBアクセス、バリデート、特定データ保持…) c. 上記機能を提供するようなフレームワーク・ライブラリ作成 (CakePHP3は trait が活用されているそうです)
  • 26. Implements Design Pattern パターン化された処理の実装 <?php trait Compositable { private $_childs = []; public function addChild($child) { $this->_childs[] = $child; } public function removeChild($child) { foreach ($i = 0; $i < count($this->_childs); $i++) { if ($this->_childs[$i] === $child) { $this->_childs = array_splice($this->_childs, $i, 1); break; } } } } <?php trait Observable { private $_listeners = []; public function addListener($listener) { $this->_listeners[] = $listener; } public function notify() { foreach ($this->_listeners as $listener) { $listener->notified(); } } }
  • 27. Implements Common Behavior 様々な場所で使われるライブラリ的な振る舞いの実装 <?php trait Queriable { private $_db_accessor; private function query($select, $from, $where, $option = '') { if (!isset($this->_db_accessor)) { $this->_db_accessor = DatabaseAccessor::getInstance(); } // クエリを投げる処理... } } <?php trait Loggable { private function logError($str, $throw_exception = false) { // ログを出力したり、例外を排出したり } }
  • 28. Summary of trait ソースコードをコピペしようとした時に 「これって trait になりませんか?(CV:八嶋智人)」 と考えてみる ※ 但し PHP 5.4 以降に限る
  • 31. P.S. Solarized colorscheme 色々なエディタ・ターミナル用の設定が配布中 • vim • emacs • IntelliJ IDEA • NetBeans • Visual Studio • Xcode • iTeam2 • OS X Terminal.app • …
  • 32. fin.
  • 33.
  • 34. When we shouldn’t use trait? trait はオブジェクト指向的な「関係」を構築しない あくまで「水平方向」での拡張
  • 35. trait は abstract class / interface を置き換えうる?
  • 36. trait replaces ‘abstract class’ Template Method デザインパターンは trait で十分 <?php trait GachaPlayer { private $lot_items = array(); private $elected = null; public function lot() { $this->setLotItems(); $this->lot(); return $this->elected; abstract private function setLotItems(); private function lot() { /* 抽選する処理 */ } } class BattleGachaPlayer { use GachaPlayer; private function setLotItems() { /* バトル用の抽選データ設定 */ } } class AdventureGachaPlayer { use GachaPlayer; private function setLotItems() { /* 冒険用の抽選データ設定 */ } }
  • 37. trait replaces ‘abstract class’? 但し、「機能を再利用するための継承」ではなく、「オブジェクトの派生と しての継承(本質的)」の場合は使わない方が良い (オブジェクト指向の考え方の問題) <?php abstract class CharacterJob { private $job_name; public function acquireSkill($skill_type) { /* ... */ } public function addExperience($amount) { /* ... */ } // ... } class WarriorJob extends CharacterJob { const SKILL_TYPE_SLASH = 1; // ... }
  • 38. trait > extends PHPの継承は「多重継承」が出来ない <?php class Singletonnable { /* ... */ } class WorldMapBase { /* ... */ } class DQ1WorldMap extends Singletonnable, WorldMapBase { // ... }
  • 39. trait > implements PHPのインターフェイスは「実装」が出来ない <?php interface Singletonnable { static public function getInstance(); } class SomeManager implements Singletonnable { static public function getInstance() { // 結局実装しないといけない } } class OtherManager implements Singletonnable { static public function getInstance() { // 結局実装しないといけない } }
  • 40. trait > static クラス間の依存性が高まり保守性に欠ける <?php final class SomeManager { static public getSomeDataList($data_type) { // ... } } class SomeProcessor { public function process() { // 引数が変わる?スコープ変わってアクセス出来なくなる? $data = SomeManager::getSomeDataList(DATA_TYPE_SOMETHING); } }
  • 42. extends > trait 定数を持てない インターフェイスを implement 出来ない タイプヒントに使えない トレイト自身をインスタンス化出来ない <?php trait SomeFunc implements SomeInterface { const SOME_DATA = 'somesome'; public function someInterfaceMethod() { } } function getSomeFunc(SomeFunc some) { some->someInterfaceMethod(); } SomeFunc::SOME_DATA;
  • 43. implements > trait 絶対にそこで実装しなければならないメソッドを定義出来ない ※ trait は “実装付きインターフェイス” とも呼べる http://stackoverflow.com/questions/9205083/php-traits-vs-interfaces <?php interface SomeInterface { public function SomeInterfaceMethod(); } trait SomeTrait { public function SomeTraitMethod() { /* ... */ } } class SomeClass implements SomeInterface { use SomeTrait; public function SomeInterfaceMethod() { /* must implement */ } public function SomeTraitMethod() { /* don’t have to implement */ } }
  • 44. static > trait 同一 trait を使っても、変数を共有出来るわけではない