3

我正在阅读有关观察者模式的信息,并找到了一篇过时的文章。通读后,我注意到本段中有一个有趣的提及:

此处查看的关键方法是 attach()、detach() 和 notify()。attach() 和 detach() 处理添加和删除观察者。我们在这里使用一个小技巧。字符串上下文中引用的对象解析为唯一标识符(即使定义了 __toString() )。您可以使用此事实为关联数组构建键。notify() 方法循环遍历所有附加的观察者,对每个观察者调用 update()。在这种情况下,只要有重要的上传和错误报告,UploadManager 类就会调用 notify()。

其中引用了这个例子:

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

现在如前所述,这篇文章已经过时了。将对象转换为字符串当然不再以这种方式工作(我在我的开发盒上运行 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

你是对的,不再那样工作了。您可能想改用其他一些功能: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 回答
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 回答