■シングルトンパターン(Singleton Pattern)
シングルトンパターンとは、ある特定のクラスのインスタンスが特定の数しか生成されない事を保証するパターンである。
<?php class Db { protected static $dbh; protected static $instance; protected __construct(){ self::$dbh = new PDO($dsn, DB_USER, DB_PASS); } public static function getDbh(){ if(!$dbh){ self::$instance = new self(); } return self::$dbh; } } $dbh = Db::getDbh(); ?>
但し、上述の例はいささか不完全でもある。何故ならば$dbhがDbクラスのインスタンスでない限り、クローン化はどうしても防げないからだ。
<?php final class ForbiddenClonePDO extends PDO { final public function __clone(){ throw new RuntimeException(); } } class Db { protected static $dbh; protected static $instance; protected __construct(){ try{ $dsn = 'mysql:host=localhost;dbname=dbname'; self::$dbh = new ForbiddenClonePDO($dsn, DB_USER, DB_PASS); self::$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); self::$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } cacth(PDOException $e){ //code } } public static function getDbh(){ if(!$dbh){ self::$instance = new self(); } return self::$dbh; } } $dbh = Db::getDbh(); ?>
■ファクトリーパターン(Factory Pattern)
似たようなタスクを違った手法で行う
<?php class Configuration { const STORE_INI = 1; const STORE_DB = 2; const STORE_XML = 3; public static function getStore($type = self::STORE_XML){ switch($type){ case self::STORE_INI: return new Configuration_Ini(); case self::STORE_DB: return new Configuration_Db(); case self::STORE_XML: return new Configuration_Xml(); default: throw new Exception(); } } } class Configuration_Ini { //code } class Configuration_Db { //code } class Configuration_Xml { //code } $config = Configuration::getStore(Configuration::STORE_XML); ?>
■レジストリパターン(Registry Pattern)
<?php class Registry { private static $_register; public static function add(&$item, $name = null){ if(is_object($item) && is_null($name)){ $name = getClass($item); } elseif(is_null($name)){ throw new Exception(); } $name = strtolower($name); self::$_register[$name] = $item; } public static function &get($name){ $name = strtolower($name); if(array_key_exists($name, self::$_register)){ return self::$_register[$name]; } else{ throw new Exception(); } } public static function exists($name){ $name = strtolower($name); if(array_key_exists($name, self::$register)){ return true; } else{ return false; } } } $db = new DB(); Registry::add($db); if(Registry::exists('DB')){ $db = Registry::get('DB'); } else{ die(); } ?>