<?php
class SomeManager {
useSingletonnable;
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/【名詞】【可算名詞】(人・ものの)特性,特色,特徴.
Why we useinsteadof 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 usetrait?
共通に使える単機能をパーツ化して、クラスにガチャコンするイメージ
a. デザインパターンの実装(singleton, composite, …)
b. 様々な場所で使われる処理(DBアクセス、バリデート、特定データ保持…)
c. 上記機能を提供するようなフレームワーク・ライブラリ作成
(CakePHP3は trait が活用されているそうです)
26.
Implements Design Pattern
パターン化された処理の実装
<?php
traitCompositable {
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();
}
}
}
trait > implements
PHPのインターフェイスは「実装」が出来ない
<?php
interfaceSingletonnable {
static public function getInstance();
}
class SomeManager implements Singletonnable {
static public function getInstance() {
// 結局実装しないといけない
}
}
class OtherManager implements Singletonnable {
static public function getInstance() {
// 結局実装しないといけない
}
}
40.
trait > static
クラス間の依存性が高まり保守性に欠ける
<?php
finalclass SomeManager {
static public getSomeDataList($data_type) {
// ...
}
}
class SomeProcessor {
public function process() {
// 引数が変わる?スコープ変わってアクセス出来なくなる?
$data = SomeManager::getSomeDataList(DATA_TYPE_SOMETHING);
}
}
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 */ }
}