1

私が達成しようとしていること (PHP 5.3) は、たとえば、ページの HTML 本文の私の表現へのアクセサーを持つことです。すべてを直接エコーする代わりに、そのシングルトンのエントリの配列に追加する必要があります。例:myBodyClass::add('<h1>Title</h1>');

add()として宣言されていますpublic static function add($strEntry) {}

self::$entries[] = $strEntry;( class VersionB )のような静的配列 $entries にそれらを追加するだけですか、それとものようなインスタンスを使用する必要がありますself::getInstance()->entries[] = $strEntry;か? ( class VersionA ) (もちろん getInstance() は必要に応じて '...new self;' をインスタンス化します)

違いはまだよくわかりませんが、残念です。

私の質問の 2 番目の部分は、オブジェクトを印刷する方法です。PHP のマニュアルでは、__toString() を static にできない理由について少し説明がありませんが、パーサーがecho myBodyClass定数との区別に問題があることは理解できます (それが理由ですか?)。

理想的には、体のすべての部分を追加するために必要なだけ呼び出し、スクリプトの最後でクラス内のメソッドを呼び出すadd()ようなものを使用したいと考えています。echo myHeaderClass, myBodyClass, myFooterClass;__toString()

私を正しい方向に向けてくれてありがとう。

コード例

class VersionA
{
    private static $instance = null;
    private $entries = array();
    private final function __construct(){}
    private final function __clone(){}

    private static final function getInstance()
    {
        if (self::$instance === null) :
            self::$instance = new self;
        endif;
        return self::$instance;
    }
    public static function add($sString)
    {
        self::getInstance()->entries[] = $sString;
    }
    public static function getHtml()
    {
        return implode("\r\n", self::getInstance()->entries);
    }
}

class VersionB
{
    private static $entries = array();
    private final function __construct(){}
    private final function __clone(){}

    public static function add($sString)
    {
        self::$entries[] = $sString;
    }
    public static function getHtml()
    {
        return implode("\r\n", self::$entries);
    }
}
4

3 に答える 3

1

おそらく、静的 add メソッドを使用しないでください。

シングルトンの考え方は、クラスのインスタンスを 1 つ作成して、外部オブジェクトがそのインスタンスと対話できるようにすることです。つまり、add メソッドは静的であってはなりません。

次のようなことができます:

class MyBodyClass
{
    protected $entries = array();

    protected $instance;

    public static function getInstance()
    {
        if (is_null($this->instance)) {
            $this->instance = new self();
        }
        return $this->instance;
    }

    private function __construct() {}

    public function add($strEntry)
    {
        $this->entires[] = $strEntry;
    }
}

そして、次のように呼び出します。

MyBodyClass::getInstance()->add('<h1>blah</h1>');
于 2013-01-11T12:52:57.040 に答える
1

(OPの要求に応じて、コメントからコピーされました...)

シングルトンのポイントがありません。シングルトン オブジェクトと静的クラスには違いがあります。オブジェクトに作用するメソッド (__toString() など) を使用する場合は、それがオブジェクトである必要があります。静的クラスでは十分ではありません。常に呼び出すことを避けたい場合はgetInstance、変数をオブジェクトに設定し、依存性注入パターンに従って、他のオブジェクトの場合と同様に、どこにでも渡します。とにかく、それはおそらくベストプラクティスのアドバイスでしょう。

静的クラスの問題は、実際には OOP ではないということです。これは、共有クラス名を持つ一連のグローバル関数にすぎません。名前空間宣言で単純な関数を使用することもできます。

しかし、本物のシングルトンを使用する主な理由は、スワップ可能性です。上記の私のアドバイスに従って、コードを渡すオブジェクトへの単一の参照を作成すると仮定すると、ハードコーディングされたクラス名があちこちで参照されていないため、代替オブジェクトを交換するのがはるかに簡単になります。 . これにより、クラスを使用するコードの適切な単体テストを簡単に作成できます。

それが役立つことを願っています。

于 2013-01-15T13:52:10.743 に答える
0

このようなものが動作するはずです:

class MySingleton
{

    public static function getInstance()
    {
        static $inst = null;
        if ($inst === null) {
            $inst = new MySingleton();
        }
    return $inst;
    }

    private function __construct() { }

    public static function add() {}

    public function __toString() {
        echo 'Something';
    }

}

$body = MySingleton::getInstance();
$body::add('Something');
echo $body;
于 2013-01-11T12:51:55.093 に答える