LoginSignup
3
3

More than 5 years have passed since last update.

静的メンバやシングルトンメソッドを使って、トリッキーなことをしてみた

Posted at

概要

個別に何度もインスタンスを生成する必要がないものは、静的(static)に実装した方が、負荷が少なく環境に優しい。

だが、引数を持つ静的メソッドを呼び出す場合、Class::Nethod($arg1,$arg2)みたいな呼び出し方を動的に生成する必要がある。

前置き

ケースごとに異なる処理を外側に書くデザインパターン(生PHPを例に取り上げて)

ここで取り上げた、指定した状態ごとに生成される、異なるクラスのインスタンスを使った処理を行うコードを書いていた時に、都度 new するのが、環境的に負荷が大きかったり、メリットが少ないのでなんとか静的にできないのか 。と考えた

静的(Static)って?

プログラミングやネットワーク界隈では、あらかじめ与えられた状態から変化しないとか、一貫した値を持つとかという意味になる。

プログラム上での使いどころは?

プログラム内で、いつどこでどんなクラスのインスタンスから呼び出されても処理内容が変わらないもの。
例えば、計算処理とか、メールアドレスの書式判定とか。

PHPにおける静的(static)とは?

PHPにおける意味合いでは、下記リンク先が簡潔かつ丁寧にまとまってるかも。

静的メンバ:Objective-PHP.net
http://www.objective-php.net/basic/static

実際に静的メンバを呼び出すケースを書いてみる。

Objective-PHP.netで取り上げられているサンプルソースコードをもとに、
静的メンバを、直接指定やクラス名や変数名を変数にして、動的に書き換えて呼び出してみた。

静的メンバを呼び出してみる
<?php

/*  スタティックなメンバを含む*/
class StaticSample {
  public static function helloStatic($a,$b){
      echo 'static class'.$a.$b;
  }
}

//単純に呼び出す
StaticSample::helloStatic('hoge','fuga');

$c = 'aaaa';
$d = 'zzzz';
$e = '____';
$f = '****';

//クラス名やメソッド名部分を動的に指定することも可能
$var = "StaticSample";
echo ' dynamic class';

$var::helloStatic($c,$d);

//$var = "StaticSample::helloStatic";
$vaz = "helloStatic";
echo ' dynamic class::method';

$var::$vaz($e,$f);

?>
実行して、正しく呼び出されているか試す。
$ php static.php 
static classhogefuga dynamic classstatic classaaaazzzz dynamic class::methodstatic class____****

クラスやメソッド名の部分を変数にしても、静的なメソッドを呼び出せることを確認したかった。OK!!

シングルトンメソッドも試す

PHPにおける、シングルトンな(一つしか存在しない)クラスの作成方法。
確かにトリッキーです。

シングルトンメソッドの実装
/*  スタティックなメンバを含む、シングルトンなクラス*/
class SingletonSample {

  private static $instance;

  /*プライベートなコンストラクタ。外部からnewできない*/
  private static function __counstruct() {}

  /*インスタンスを取得するためのメソッド*/
  private static function getInstance (){
    /*インスタンスの生成がなされていない場合、生成し自己のクラス変数に格納する*/
    if (!isset(self::$instance)) {
      $instance = new SingletonSample();
    }
      /*このシングルトンクラスのインスタンスを返す。*/
      return $instance;
  }

  public static function helloStatic1($a,$b){
      echo 'static class1'.$a.$b."\n";
  }

  public static function helloStatic2($a,$b){
      echo 'static class2'.$a.$b."\n";
  }
}

最初見たときは、何やってんだこりゃ?! と思ったものの、一つ一つ解釈していくと。あ、なるほど・・・ぅてな感じになる。

このクラスのコンストラクタはプライベードメソッドなので、外部からアクセス不可能。なので、外部からnew できない(させたくない)

次に、get instance

静的なメソッドを、クラス名とメソッド名を動的に指定して指定する

ひどい書き方だけど・・・上記のシングルトンクラスを呼び出してみる

静的メソッドを動的に呼び出す
/*よみ出し処理をするクラス*/

class Reader {

  /*どのクラスを読んでいるかを保存*/
  private $my_class = null;
  private $my_method = null;

  /*どのクラスのどのメソッドを参照するか?を指定する*/
  public function set_status($class,$method){
      $this->my_class = $class;
      $this->my_method = $method;
  }

  /*メソッドを呼び出す*/
  public function call_method($a,$b){
    $class = $this->my_class;
    $method = $this->my_method;
    $class::$method($a,$b);
  }

}

/*インスタンスを生成する*/

$rd1 = new Reader();
$rd2 = new Reader();


/*どのクラスのどのメソッドを呼び出すか指定*/

$rd1->set_status('SingletonSample','helloStatic1');
$rd2->set_status('SingletonSample','helloStatic2');

/*クラスに応じた処理を実装*/
$rd1->call_method(' call ',' now !!');
$rd2->call_method(' yobi ',' mashita ?');

実施結果
$ php static2.php 

static class1 call  now !!
static class2 yobi  mashita ?

呼び出す方もトリッキーですが。

3
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3