
残念ながら私は毎日業務でプログラムを書いているわけではないので、色々やっているうちに忘れてしまう危険があります・・・!!そんなわけで、プログラム系もぼちぼち記事にしていこうと思います。
今回はPHPのメソッドチェーンを記事にします。
チェーンで書くとコード量はシンプルになりますが、読むのが複雑になるので自分で書く必要はあまりないかも。複雑に書くと数か月後の自分が読めるかわからない自信があります。
しかし、他の人が書いたコードやフレームワークでは使われるので小難しい書き方も覚えておく必要があります。
難しい漢字みたいなもの
書ける必要はないけれど、本によくある漢字は知らないと読むのが辛くなるのに似ています。感じましょう。
メソッドチェーン
- Aクラス、Bクラスのインスタンスを生成。
- Bクラスのadd()メソッドにAインスタンスを投入して、get()メソッドでリターンします。
- Bインスタンスー>Bget()メソッド->A()メソッドの記述で利用します。
やっていることは継承に似ています。
$fr = $japaripark->getFriend("かばん");
$fr->MyName();
↓メソッドチェーン化
$japaripark->getFriend("かばん")->MyName();
すっごーい。どんどん長くなる、へびのフレンズなんだね。
get()で取得したインスタンスを変数に入れてバウンドさせる必要がなくなります。変数にインスタンスを代入する記述を省略しているんだな~っと覚えればOK
シングルトンパターン
class Japaripark {
private static $instance;
(略)
public static function getInstance(){
static $instance;
if(!isset($instance)){
$instance = new Japaripark();
}
return $instance;
}
(略)
}
getInstance()関数を作って呼び出すことで、Japariparkインスタンスを生成します。1つだけインスタンスを生成するのが特徴。private static $instance;がインスタンス生成を1つに制限して保証する部分。
- $instanceにJapariparkインスタンスを格納する
- $instanceはstaticで指定しているので値が初期化されなくなる。
これで何をするかというと、getInstance()で作ったJapariparkインスタンスのadd()なメソッドに他のインスタンスを入れて、関数を呼び出したり。上記2つとも、インスタンスのメソッドの引数に別クラスのインスタンスを代入して、returnで返しているからチェーンとして利用できるという仕組みですね!
書いてみた
コードにするネタが思い浮かばなかったので、けもフレで。
Japaripark::getInstance()メソッドを起点としてはじまります。
JapariparkインスタンスはJaparipark::getInstance()メソッドから1つだけ生成されます。
<?php
class Animal {
protected $name;
protected $koe;
public function setName($name) {
$this->name = $name;
}
public function getName(){
return $this->name;
}
public function setKoe($koe) {
$this->koe = $koe;
}
public function getKoe(){
return $this->koe;
}
}
class Friends extends Animal{
public function myName() {
return $this->name;
}
public function naku() {
return $this->koe;
}
}
class Japaripark {
private $friends;
private static $instance;
private function __construct() {
$this->friends = array();
}
public static function getInstance(){
static $instance;
if(!isset($instance)){
$instance = new Japaripark();
}
return $instance;
}
public function addFriend($friend) {
$this->friends[] = $friend;
}
public function getFriend($name){
foreach($this->friends as $friend){
if($friend->getName() == $name){
return $friend;
}
}
return null;
}
public function resisterFriendDB() {
foreach($this->friends as $friend){
//Database resister
//登録要素
//$friend->getName(); //例:かばん
//$friend->getKoe(); //例:食べないで下さい
}
return null;
}
}
//Japariparkインスタンスを生成するよ!
$japaripark = Japaripark::getInstance();
$friend = new Friends();
$friend->setName("かばん");
$friend->setKoe("食べないでください");
$japaripark->addFriend($friend);
$friend = new Friends();
$friend->setName("サーバル");
$friend->setKoe("すっごーい");
$japaripark->addFriend($friend);
//DB登録
$japaripark->resisterFriendDB();
echo <<< EOM
フレンズ:{$japaripark->getFriend("かばん")->myName()}<br/>
鳴き声:{$japaripark->getFriend("かばん")->naku()} # メソッドチェーン
<hr/>
フレンズ:{$japaripark->getFriend("サーバル")->myName()}<br/>
鳴き声:{$japaripark->getFriend("サーバル")->naku()} # メソッドチェーン
<hr/>
EOM;
var_dump($japaripark);
exit();
出力してみる

インフラとしてプロジェクトに関わる場合もコードが読めないと、障害が起きた時に根本原因がサーバ側なのか、プログラム側なのか切り分けが難しいです。とりあえずの復旧として一時対応的にはサービスを再起動させれば大丈夫なことが多いですが・・・、根本原因を改善しないといつかは同じことが起こります。
また、世界的にメジャーなCMSやパッケージではなく、オリジナルのシステムだと、障害原因の8割以上はアプリ側の要因で起こっている気がする。プログラムが原因の場合、コードが読めればプログラマさんと一緒になって2馬力?で対応に当たれます。
もっと仕事の幅が広がるフレンズになれるかな~。
