クラスとオブジェクト
PHP Manual

パターン

パターンは、最善の手順と良い設計を記述するための手段です。 パターンは、一般的なプログラム上の課題に柔軟な解決策を提供します。

Factory

Factory パターンにより、実行時にオブジェクトを初期化できるようになります。 オブジェクトを"製造する"ことに似ているため、これは Factory パターンと呼ばれています。 パラメータ化された Factory が、生成するクラス名を引数として受け取ります。

例1 パラメータ化された Factory メソッド

<?php
class Example
{
    
// パラメータ化された Factory メソッド
    
public static function factory($type)
    {
        if (include_once 
'Drivers/' $type '.php') {
            
$classname 'Driver_' $type;
            return new 
$classname;
        } else {
            throw new 
Exception('Driver not found');
        }
    }
}
?>

このメソッドをクラス内で定義することで、実行時に ロードされるドライバを作成できるようになります。 Example クラスが、データベース抽象化クラスで、 MySQL および SQLite ドライバをロードするとすると以下のように行うことができます。

<?php
// MySQL ドライバをロード
$mysql Example::factory('MySQL');

// SQLite ドライバをロード
$sqlite Example::factory('SQLite');
?>

Singleton

Singleton は、あるクラスのインスタンスがひとつだけしかないことを保証し、 そのインスタンスに対してどこからでもアクセスできるようにします。 Singleton は、いわゆる "Gang of Four" による Creational Pattern のひとつです。

Singleton パターンを使って実装されることが多いのは、 データベースクラスやロガー、フロントコントローラ、あるいは リクエストやレスポンスを表すオブジェクトです。

例2 Singleton の例

<?php
class Example
{
    private static 
$instance;
    private 
$count 0;

    private function 
__construct()
    {
    }

    public static function 
singleton()
    {
        if (!isset(
self::$instance)) {
            echo 
'Creating new instance.';
            
$className __CLASS__;
            
self::$instance = new $className;
        }
        return 
self::$instance;
    }

    public function 
increment()
    {
        return 
$this->count++;
    }

    public function 
__clone()
    {
        
trigger_error('Clone is not allowed.'E_USER_ERROR);
    }

    public function 
__wakeup()
    {
        
trigger_error('Unserializing is not allowed.'E_USER_ERROR);
    }
}
?>

Singleton の挙動は、このようになります。

<?php
$singleton 
Example::singleton(); // "Creating new instance." と表示
echo $singleton->increment(); // 0
echo $singleton->increment(); // 1

$singleton Example::singleton(); // 既存のインスタンスを再利用
echo $singleton->increment(); // 2
echo $singleton->increment(); // 3

// これらはすべて Fatal エラーとなります
$singleton2 = new Example;
$singleton3 = clone $singleton;
$singleton4 unserialize(serialize($singleton));
?>
警告

Singleton パターンは、よく異論が出るパターンのひとつです。よくある批判は 「Singleton はアプリケーションにグローバルな状態を導入してしまうし、 Singleton とそれを使うクラスが密結合してしまう」というものです。 その結果、目に見えない依存関係や予期せぬ副作用が発生し、 テストや保守のしにくいコードが生まれてしまいます。

さらに、こんな批判もあります。 PHP のようなシェアードナッシング型のアーキテクチャで Singleton を使うのは無意味だ。 だって、いずれにせよオブジェクトはリクエスト内でだけ一意になるのだから。 それよりは、リクエストの開始時に Builder パターンや Factory パターンを使って協調オブジェクトグラフを作ったほうがずっと簡潔ですっきりする」。

Singleton は、"ソリッド" な OOP 設計規約やデメテルの法則にも違反します。 Singleton はシリアライズできません。そのサブタイプを作ることも (PHP 5.3 より前のバージョンでは) できないし、ガベージコレクションの対象にもなりません。そのインスタンスが Singleton の静的属性として格納されるからです。


クラスとオブジェクト
PHP Manual