zoukankan      html  css  js  c++  java
  • 看懂php单例模式-清晰简洁的回答

    1:

    其实单例模式,说白了就是说一个类只能实例化一次。但是我们如何在这个实例化一次上面做文章呢。其实有个突破口就是__construct()这个魔术方法。这个方法就代表着如果类实例化的时候,就会自动执行这个方法。然后如果我把这个方法变成保护或者私有的,会是什么效果呢。
    <?php
    class test{
    
    	protected function __construct(){
    
    	}
    }
    
    $test = new test();
    ?>
    

    然后执行以下,就会出现这个情况。

    这样的话,就不能实例化了。这样就保证不能随便让人给实例化了。
    但是既然这样的话,我们应该怎么实现实例化呢。就是这样:
    <?php
    class test{
    
    	protected function __construct(){
    
    	}
    
    	public static function getInstance(){
    		$_test = new test();
    		return $_test;
    	}
    }
    
    $test = test::getInstance();
    
    var_dump($test);
    ?>
    这样的话。实例的话,就能出现了。我们看一下:
    但是说了这么多,我还是没说到重点。下面重点来了,只要我们再使用一个关键字(static)就好了。铛铛铛铛:
    <?php
    class test{
    
    	protected function __construct(){
    
    	}
    
    	public static function getInstance(){
    		static $_test;
    		if (empty($_test)) {
    			$_test = new test();
    		}
    		return $_test;
    	}
    }
    
    $test1 = test::getInstance();
    $test2 = test::getInstance();
    $test3 = test::getInstance();
    
    var_dump($test1,$test2,$test3);
    echo $test1 == $test2 ? 'true' : 'false';
    echo "<br>";
    echo $test2 == $test3 ? 'true' : 'false';
    echo "<br>";
    echo $test1 == $test3 ? 'true' : 'false';
    ?>
    
    看一下结果:
    这样的话就能实现php单例的效果了。
    单例的话,最长用在需要只使用这一个类,而不是会有多个类。
    打个比方。比如现在有个config类,这个类主要是存储这个项目的配置信息。如果说这个类能实例化多次的话,那么如果在代码运行中对配置进行了修改,那么你怎么知道是在哪个配置类中进行了修改了呢。这个时候的话使用单例模式,就避免了情况的发生,所有对于配置文件的改变都是基于这个类的实例进行修改的。而不会出现因为多个类的实例化,操作对于操作的改变没有进行实时的更新。而且,实例多个类库,占用内存也会非常的厉害,这样只实例化一次。是不是好处多多呢。
    作者:鲍国枭
    链接:https://www.zhihu.com/question/35285158/answer/62151947
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    2:
    来,带你装B带你飞;
    /*
    单例设计模式 (单态)
        定义: 一个类 只能允许有 一个对象存在.
        1.不让进: 使类不能被实例化
        2.留后门: 设置静态方法
        3.给对象: 在静态方法里实例化该类
        4.判初夜: 判断是否是 第一次产生该类的对象
        5.设静态: 静态方法里 要使用静态属性
     */
    
    /*//1.不让进: 使类不能被实例化-----------------
    class Test
    {
        // 设置 一个封装的构造方法
        private function __construct()
        {
            //占位, 我就是不让你NEW我~~~
        }
    }*/
    
    /*//2.留后门: 设置静态方法--------------------
    class Test
    {
        // 设置 一个封装的构造方法
        private function __construct()
        {
            //占位, 我就是不让你NEW我~~~
        }
        //后门
        public static function getObject()
        {
            echo "啊,我是后门,进吧!<br>";
        }
    }*/
    
    /*//3.给对象: 在静态方法里实例化该类------------------
    class Test
    {
        // 设置 一个封装的构造方法
        private function __construct()
        {
            //占位, 我就是不让你NEW我~~~
        }
        //后门
        public static function getObject()
        {
            echo "啊,我是后门,进吧!<br>";
            return new self();//实例化一个对象给你
        }
    }*/
    
    /*//4.判初夜: 判断是否是 第一次产生该类的对象------------------
    class Test
    {
        private $obj = null;//属性值为对象,默认为null
        // 设置 一个封装的构造方法
        private function __construct()
        {
            //占位, 我就是不让你NEW我~~~
        }
        //后门
        public static function getObject()
        {
            echo "啊,我是后门,进吧!<br>";
            if ($this->obj === null) {
                $this->obj = new self();//实例化一个对象
            }
            //返回的属性 其实就是本对象
            return $this->obj;
        }
    }*/
    
    //5.设静态: 静态方法里 要使用静态属性------------------
    class Test
    {
        private static $obj = null;//属性值为对象,默认为null
        // 设置 一个封装的构造方法
        private function __construct()
        {
            //占位, 我就是不让你NEW我~~~
        }
        //后门
        public static function getObject()
        {
            echo "啊,我是后门,进吧!<br>";
            if (self::$obj === null) {
                self::$obj = new self();//实例化一个对象
            }
            //返回的属性 其实就是本对象
            return self::$obj;
        }
    }
    
    /*Test::getObject();//使用静态方法访问该类里的方法
    exit;*/
    
    $t1 = Test::getObject();
    $t2 = Test::getObject();
    $t3 = Test::getObject();
    $t4 = Test::getObject();
    $t5 = Test::getObject();
    $t6 = Test::getObject();
    $t7 = Test::getObject();
    $t8 = Test::getObject();
    
    //判断 两个对象 是否是同一个对象
    if ($t1 === $t6) {
        echo "哦, Yes! 是同一个实例<br>";
    } else {
        echo "哦, No! 不是同一个实例<br>";
    }
    
    第五步是成品,前面4步都是一步一步的推的!
    作者:独身待苍颜
    链接:https://www.zhihu.com/question/35285158/answer/141024074
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    既不回头,何必不忘; 既然无缘,何须誓言; 今日种种,逝水无痕; 明夕何夕,君已陌路;
  • 相关阅读:
    VS2008编写MFC程序--使用opencv2.4()
    November 02nd, 2017 Week 44th Thursday
    November 01st, 2017 Week 44th Wednesday
    October 31st, 2017 Week 44th Tuesday
    October 30th, 2017 Week 44th Monday
    October 29th, 2017 Week 44th Sunday
    October 28th, 2017 Week 43rd Saturday
    October 27th, 2017 Week 43rd Friday
    October 26th, 2017 Week 43rd Thursday
    October 25th, 2017 Week 43rd Wednesday
  • 原文地址:https://www.cnblogs.com/zyjfire/p/6760129.html
Copyright © 2011-2022 走看看