PHPのtraitを使ってラク出来た件
はじめに
traitを使って既存の動作にほぼ影響を与えず機能追加出来たパターンが有った。
使い方例をメモ。
元々有ったコード
ClassBase.php
class ClassBase { private $value; static function getBody(){ return ""; } static function getObjcet() { $className = __CLASS__; return new $className(static::makeArg()); } static function makeArg() { // バイト長を返却 return strlen(static::getBody()); } function __construct($value) { $this->value = $value; } function echoValue(){ echo $this->value, PHP_EOL; } }
ClassA.php
class ClassA extends ClassBase { static function getBody() { return "body"; } 〜 色々なメソッド }
$obj_classA = ClassA::getObjcet();
$obj_classA->echoValue(); // 4
要件(前提条件)
・バイト長では無く特定要素でjsonエンコードした情報を出力する処理を追加する。
・既存のバイト長を出力する処理も残す
・既存の動作にほぼ影響を与えないようにする(既存変更影響のテスト工数はあまり取れない)
・メソッド名(echoValue)は同じで動作させる。
今回は使えなかった解決方法
・ClassBaseを変更
→ 多くのクラスで継承されているので影響範囲が大きく手を入れにくい状態
・ClassBaseを継承する新たなクラスを作成
→ ClassA内のメソッドも使用する場合があるので同じコードをコピペで入れたくない
traitを使って解決
TraitCommon.php
trait TraitCommon
{
static function makeArg()
{
$json = [];
$json["hoge"] = static::getBody();
// jsonに変更
return json_encode($json);
}
}
ClassTraitA.php
class ClassTraitA extends ClassA { use TraitCommon; }
既存処理に影響を与えず追加処理を用意出来た。
$obj_classA = ClassA::getObjcet(); $obj_classA->echoValue(); // 4 $obj_traitA = ClassTraitA::getObjcet(); $obj_traitA->echoValue(); // {"hoge":"body"}
ClassBaseを継承したClassBやClassCが有っても同じように共通処理として簡単に展開していける。