3

私はこのレベルのPHPプログラミングに不慣れで、シングルトンクラスと静的クラスに関する投稿を読んでいます。DB接続を容易にするクラスを作成中です。

Jon Raphaelson(ここ)による次のコードに出くわしました:

class ConnectionFactory
{
    private static $factory;
    public static function getFactory()
    {
        if (!self::$factory)
            self::$factory = new ConnectionFactory(...);
        return self::$factory;
    }

    private $db;

    public function getConnection() {
        if (!$this->db)                 // this line was modified due to comment
            $this->db = new PDO(...);       // this line was modified due to comment
        return $db;
    }
}

function getSomething()
{
    $conn = ConnectionFactory::getFactory()->getConnection();
    .
    .
    .
}

探していたものが見つかったようですが、いくつか質問があります。

  1. self::$factory = new ConnectionFactory(...);-このクラスにコンストラクターがありません。このコンストラクターを作成して、dbの詳細('dbname'、'user'、'pass'など)を渡すだけですか?
  2. このgetSomething()関数は、データを取得するすべての実際の関数をConnectionFactoryクラス内に配置することを目的としていると想定しています。これが、この関数がこのクラスに含まれる理由です。そうでなければ、この関数が別のクラス内にあることを期待していました。[編集]この質問をスキップしてください。角かっこが1つ表示されませんでした。
  3. 2人のユーザーがサイトにログインしてDB接続を要求している場合(両方が更新などを行っている場合)はどうなりますか?これがシングルトンであることが問題になりますか?

ありがとう!

4

3 に答える 3

2

これは主に、質問の下での私のコメントを拡張するためのものです...

より良い「シングルトン」パターンは次のようになります。

class ConnectionFactory {

    protected static $connection;

    public function getConnection() {
        if (!self::$connection) {
            self::$connection = new PDO(...);
        }
        return self::$connection;
    }

}

このファクトリのユーザーは、自分で呼び出すのではなく、そのインスタンスを期待する必要があります。

class Foo {

    protected $connectionFactory;

    public function __construct(ConnectionFactory $factory) {
        $this->connectionFactory = $factory;
    }

    public function somethingThatNeedsAConnection() {
        $connection = $this->connectionFactory->getConnection();
        ...
    }

}

$foo = new Foo(new ConnectionFactory);

これにより、必要に応じて接続自体を取得できますが、たとえばテスト目的で、Foo代替接続をに挿入することもできます。Foo

便利な手段として、またインスタンス化の複雑さを減らすために、このパターンも適しています。

class Foo {

    protected $connectionFactory;

    public function __construct(ConnectionFactory $factory = null) {
        if (!$factory) {
            $factory = new ConnectionFactory;
        }
        $this->connectionFactory = $factory;
    }

    ...

}

これにより、依存関係を注入してオーバーライドすることができますが、インスタンス化するたびにファクトリを注入する必要はありませんFoo

于 2012-11-14T16:05:47.177 に答える
0

複数のファクトリが必要ないため、ファクトリはシングルトンです。

  1. コンストラクターは必要ありません。ファクトリに必要な状態をgetFactory()メソッドでセットアップできます。getFactory()関数は接続を取得しないため、ここでは接続関連の設定を行わないでください。ただし、接続オブジェクト自体は行わないでください。ファクトリは、使用するクラスの「インスタンスを構築」するため、getConnection()メソッドを使用して状態を設定し、ファクトリが生成することになっている接続オブジェクトを構築します。
  2. getSomething()はConnectionFactoryクラスのメソッドではありません。これは、ファクトリクラスを使用してファクトリを取得してから接続を取得する例にすぎません。

私は個人的にPHPでのメソッドチェーンが嫌いです。getSomething()で実際に起こっていることは次のとおりです。

function getSomething()
{
   $factory = ConnectionFactory::getFactory();
   $conn = $factory->getConnection();
   .
   .
   . 
}
于 2012-11-14T15:20:21.550 に答える
0
  1. クラスは、でインスタンス化するために明示的なコンストラクターを必要としませんnew ClassName()。ただし、クラスがシングルトンであると想定されている場合(この場合はそのように見えます)、パターンの全体的なポイントにより、クラスの外部からそのようなインスタンス化が不可能になります。そのため、次のように宣言されたコンストラクターが必要であると考えています。privateキーワード。

  2. getgetSomething()は、クラスの使用例を含む「スタンドアロン」関数です。

  3. いいえ。複数のユーザーがスクリプトを処理するPHPの複数のインスタンスを使用し、それらの間で何も共有されません。

于 2012-11-14T15:27:28.313 に答える