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

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

  •  
  •   leven87 · 2018-04-20 18:20:38 +08:00 · 1621 次点击
    这是一个创建于 604 天前的主题,其中的信息可能已经有所发展或是发生改变。
    场景是: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 的实例已经被销毁了。但是结果并没有。想请朋友帮忙想一个单例生成实例后销毁该实例的办法。谢谢。
        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;
    }
        2
    zhongkouwei   2018-04-20 19:57:56 +08:00
    2、你在销毁实例里面销毁的是 instance,单例对象 mary 本身并没有被销毁。instance 是用来判断对象是否已被创建,你把它销毁后只会让下一个 jack 请求再创建一个 jack 对象,然后实际上就存在了两个对象。
        3
    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 销毁。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1008 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 28ms · UTC 18:15 · PVG 02:15 · LAX 10:15 · JFK 13:15
    ♥ Do have faith in what you're doing.