3

私はオブザーバーパターンについて読んでいて、古い記事を見つけました。読んだ後、私はこの段落で興味深い言及に気づきました:

ここで確認する重要なメソッドは、attach()、detach()、およびnotify()です。attach()およびdetach()は、オブザーバーの追加と削除を処理します。ここではちょっとしたトリックを使います。文字列コンテキストで引用されたオブジェクトは、一意の識別子に解決されます(__toString()が定義されている場合でも)。このファクトを使用して、連想配列のキーを作成できます。notify()メソッドは、接続されているすべてのオブザーバーを循環し、それぞれでupdate()を呼び出します。この場合、UploadManagerクラスは、アップロードとエラーについて報告することが重要な場合は常にnotify()を呼び出します。

この例を参照するもの:

function attach(UploadObserver $obs) {
    $this->observers["$obs"] = $obs;
}

さて、述べたように、この記事は日付が付けられています。もちろん、オブジェクトを文字列にキャストすることは、この方法では機能しなくなりました(devボックスで5.3.6を実行し、すべてのクライアントプロジェクトにプッシュします)が、同様の機能を実現したいと思います。私はこれ(のようなもの)についてしか考えることができません:

function attach(Observer $observer){
    $this->_observers[md5(serialize($observer))] = $observer;
}

function detach(Observer $observer){
    unset($this->_observers[md5(serialize($observer))]);
}

私は興味があります、これを達成するための他の効率的な方法はありますか?オブジェクト自体から一意のキーを作成します。

警告:定義されたキーには入りたくありません。他のリポジトリなどで十分頻繁に使用し、実装などを行います__set($key, $value)

注: MD5は理想的ではないことを理解しています。


更新:spl_object_hashが見つかりました。これがおそらく私の最良の選択だと思いますが、お気軽にご意見をお聞かせください。

4

3 に答える 3

1

SPLオブジェクトハッシュ関数を試しましたか?

于 2011-06-15T15:42:10.810 に答える
1

または、 SplObjectStorageを直接使用することもできます。

好き:

function __construct(...){
    $this->_observers = new SplObjectStorage;
}

function attach(Observer $observer) {
    $this->_observers[$observer] = $observer;
}

function detach(Observer $observer){
    unset($this->_observers[$observer]);
}
于 2011-06-15T15:51:23.227 に答える
1

その通り、もはやそのようには機能しません。代わりに他の関数を使用することもできます:spl_object_hash()

function attach(Observer $observer){
    $this->_observers[spl_object_hash($observer)] = $observer;
}

function detach(Observer $observer){
    unset($this->_observers[spl_object_hash($observer)]);
}

シリアル化ベースのアプローチには設計上の問題があります。オブジェクトの値が同一である場合、つまり、オブジェクトが同じシリアル化された値 (NULL など) を返す場合、動作を停止します。Serializableこれは、オブジェクトがインターフェイスを実装するときに、オブジェクト自体によって完全に制御可能 です。

于 2011-06-15T15:42:37.657 に答える