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?

やはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているやはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているKoichi Tanaka
 
ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説増田 亨
 
ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方増田 亨
 
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発慎一 古賀
 
オブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメオブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメYoji Kanno
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」Takuto Wada
 
C#実装から見るDDD(ドメイン駆動設計)
C#実装から見るDDD(ドメイン駆動設計)C#実装から見るDDD(ドメイン駆動設計)
C#実装から見るDDD(ドメイン駆動設計)Takuya Kawabe
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話Koichiro Matsuoka
 
継承やめろマジやめろ。 なぜイケないのか 解説する
継承やめろマジやめろ。 なぜイケないのか 解説する継承やめろマジやめろ。 なぜイケないのか 解説する
継承やめろマジやめろ。 なぜイケないのか 解説するTaishiYamada1
 
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかDDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかKoichiro Matsuoka
 
イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)Yoshitaka Kawashima
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugMasatoshi Tada
 
デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣Masahiro Nishimi
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方増田 亨
 
Xamarin.forms navigation overview
Xamarin.forms navigation overviewXamarin.forms navigation overview
Xamarin.forms navigation overviewAtsushi Nakamura
 
ドメイン駆動で開発する ラフスケッチから実装まで
ドメイン駆動で開発する ラフスケッチから実装までドメイン駆動で開発する ラフスケッチから実装まで
ドメイン駆動で開発する ラフスケッチから実装まで増田 亨
 
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture世界一わかりやすいClean Architecture
世界一わかりやすいClean ArchitectureAtsushi Nakamura
 
オブジェクト指向プログラミングのためのモデリング入門
オブジェクト指向プログラミングのためのモデリング入門オブジェクト指向プログラミングのためのモデリング入門
オブジェクト指向プログラミングのためのモデリング入門増田 亨
 
イミュータブルデータモデルの極意
イミュータブルデータモデルの極意イミュータブルデータモデルの極意
イミュータブルデータモデルの極意Yoshitaka Kawashima
 
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門Tadahiro Ishisaka
 

Was ist angesagt? (20)

やはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているやはりお前らのMVCは間違っている
やはりお前らのMVCは間違っている
 
ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説
 
ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方
 
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
 
オブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメオブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメ
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
 
C#実装から見るDDD(ドメイン駆動設計)
C#実装から見るDDD(ドメイン駆動設計)C#実装から見るDDD(ドメイン駆動設計)
C#実装から見るDDD(ドメイン駆動設計)
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
 
継承やめろマジやめろ。 なぜイケないのか 解説する
継承やめろマジやめろ。 なぜイケないのか 解説する継承やめろマジやめろ。 なぜイケないのか 解説する
継承やめろマジやめろ。 なぜイケないのか 解説する
 
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかDDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
 
イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsug
 
デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方
 
Xamarin.forms navigation overview
Xamarin.forms navigation overviewXamarin.forms navigation overview
Xamarin.forms navigation overview
 
ドメイン駆動で開発する ラフスケッチから実装まで
ドメイン駆動で開発する ラフスケッチから実装までドメイン駆動で開発する ラフスケッチから実装まで
ドメイン駆動で開発する ラフスケッチから実装まで
 
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture
 
オブジェクト指向プログラミングのためのモデリング入門
オブジェクト指向プログラミングのためのモデリング入門オブジェクト指向プログラミングのためのモデリング入門
オブジェクト指向プログラミングのためのモデリング入門
 
イミュータブルデータモデルの極意
イミュータブルデータモデルの極意イミュータブルデータモデルの極意
イミュータブルデータモデルの極意
 
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
 

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

業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)Hiroshi Tomioka
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案sugiuralab
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NTT DATA Technology & Innovation
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 

Kürzlich hochgeladen (9)

業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 

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 を使っても、変数を共有出来るわけではない