V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
leven87
V2EX  ›  PHP

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

  •  
  •   leven87 · 2018-04-20 18:20:38 +08:00 · 3022 次点击
    这是一个创建于 2416 天前的主题,其中的信息可能已经有所发展或是发生改变。
    场景是: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 的实例已经被销毁了。但是结果并没有。想请朋友帮忙想一个单例生成实例后销毁该实例的办法。谢谢。
    zhongkouwei
        1
    zhongkouwei  
       2018-04-20 19:54:51 +08:00   ❤️ 1
    代码中有错误:应该这样获取吧
    //静态方法,创建实例
    public static function getInstance($ownerUser){
    if(!self::$instance instanceof self){//self 指类,this 代表实例,这里指代静态属性,使用 self
    self::$instance = new self($ownerUser);
    }
    return self::$instance;
    }
    zhongkouwei
        2
    zhongkouwei  
       2018-04-20 19:57:56 +08:00
    2、你在销毁实例里面销毁的是 instance,单例对象 mary 本身并没有被销毁。instance 是用来判断对象是否已被创建,你把它销毁后只会让下一个 jack 请求再创建一个 jack 对象,然后实际上就存在了两个对象。
    leven87
        3
    leven87  
    OP
       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 销毁。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2512 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 04:55 · PVG 12:55 · LAX 20:55 · JFK 23:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.