麻烦朋友们帮我解答一个 PHP 实现单例模式,实例销毁的困惑。

2018-04-20 18:20:38 +08:00
 leven87
场景是:Jack 和 Mary 都想骑一个共享单车,但是单车只有一辆。一人能骑上单车的条件是现在单车没人使用。参考代码( php 版本):

<?php
/*
* 单例模式示例
*/
error_reporting(E_ALL);
ini_set('display_errors','on');


//
class SingletonBike{
private static $instance = null; //创建静态私有的变量保存该类对象
private $ownerUser = "";//使用者姓名

//构造函数私有化,防止直接创建对象
private function __construct($ownerUser) {
$this ->ownerUser = $ownerUser;
}
//构造函数私有化,防止直接创建对象

//防止克隆对象
private function __clone() {
}
//静态方法,创建实例
public static function getInstance($ownerUser){
if(!self::$instance instanceof self){//self 指类,this 代表实例,这里指代静态属性,使用 self
self::$instance = new self($ownerUser);
return self::$instance;
}else{
return null;
}
}
public function getOwnerUser(){
return $this->ownerUser;
}
//静态方法,销毁实例
public static function destroyInstance(){
self::$instance = null;
}
}


$singletonBike = SingletonBike::getInstance("Mary");
echo $singletonBike->getOwnerUser()."<br/>";//Mary
$singletonBike2 = SingletonBike::getInstance("Jack");
var_dump($singletonBike2);//null
echo "<br/>";
SingletonBike::destroyInstance();
$singletonBike2 = SingletonBike::getInstance("Jack");
var_dump($singletonBike2);//object(SingletonBike)#1 (1) { ["ownerUser":"SingletonBike":private]=> string(4) "Jack" }
echo "<br/>";
echo $singletonBike->getOwnerUser()."<br/>";//理想是为 Jack,结果为 Mary

?>
理论上希望最后的$singletonBike 不存在了,或者$singletonBike->getOwnerUser()的结果为 Jack。这样就证明 SingletonBike 的实例已经被销毁了。但是结果并没有。想请朋友帮忙想一个单例生成实例后销毁该实例的办法。谢谢。
3014 次点击
所在节点    PHP
3 条回复
zhongkouwei
2018-04-20 19:54:51 +08:00
代码中有错误:应该这样获取吧
//静态方法,创建实例
public static function getInstance($ownerUser){
if(!self::$instance instanceof self){//self 指类,this 代表实例,这里指代静态属性,使用 self
self::$instance = new self($ownerUser);
}
return self::$instance;
}
zhongkouwei
2018-04-20 19:57:56 +08:00
2、你在销毁实例里面销毁的是 instance,单例对象 mary 本身并没有被销毁。instance 是用来判断对象是否已被创建,你把它销毁后只会让下一个 jack 请求再创建一个 jack 对象,然后实际上就存在了两个对象。
leven87
2018-04-20 21:02:49 +08:00
@zhongkouwei 感谢回复。我们明白你的意思。其实我的代码是对单例模式做了点改进,想让 Jack 来请求的时候,如果单车已经有人了,就直接返回空。不过我有新思路了,改写下 destroyInstance()方法。如下:
//静态方法,销毁实例
public static function destroyInstance(&$instance){
self::$instance = null;
$instance = null;
}


SingletonBike::destroyInstance($singletonBike);

将$singletonBike 当作参数给 destroyInstance 销毁。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/448529

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX