zoukankan      html  css  js  c++  java
  • 单例模式

    //注:单例模式常用也常考,请认真练习

    单例模式:

    主要思路

    1.保护或私有构造函数,防止外部实例化
    2.内部开放一个公共的静态方法,负责实例化
    3.类有一个静态属性存放对象

    当静态属性已经存放对象,直接return 该对象。

    第一步:一个普通的类
    这个普通类,可以new来实例化
    这显然不是单例

    class single{


    }

    $s1=new single();
    $s2=new single();
    $s3=new single();


     

    第二步:看来new是罪恶之源,干脆不让new了

    我们把构造方法 保护/私有
    外部不能new了            new了报错了
    ----但引入一个问题,不能new,那得不到对象,这不是单例,这是0例模式。

    class single{
       protected function __construct(){
      
       }
    }

    $s1=new single();

    第三步,通过内部的static方法,来调用


    class single{

     public $hash;   //证明

      protected function __construct(){
            $this->hash=mt_rand(1,99999);  //随机码   证明
      }

      static public function getInstance(){
            return new self();        //self 代表本类  也可以直接写上类名
      }


    }


    $s1=single::getInstance();
    $s2=single::getInstance();

    两个对象什么时间相等?

    答:只有指向一个对象地址的时候,才相等。


    证明给你看!

     打了证明的都是可以证明不是一个对象的

    print_r($s1);  //证明
    print_r($s2);  //证明

    if($s1==$s2){             //证明
        echo '是一个对象';      //证明
    }else{
       echo '不是一个对象';       //证明 
    }

    //输出    不是一个对象


     

    第四步,通过内部的static方法实例化,
    并且,把实例保存在内部的静态属性上


    简单的单例模式完成

    class single{

     public $hash;  

     static protected $ins=NULL;

      protected function __construct(){
            $this->hash=mt_rand(1,99999);
      }

      static public function getInstance(){
         
            if(self::$ins instanceof self){  //instanceof 专门判断某个对象是不是某个类的实例用的

           return self::$ins;
      }

      self::$ins=new self();
      return self::$ins;

      }


    }


    $s1=single::getInstance();
    $s2=single::getInstance();

    print_r($s1); 
    print_r($s2); 


    if($s1==$s2){            
        echo '是一个对象';    
    }else{
       echo '不是一个对象';      
    }


    //输出    是一个对象

    //-----------------看问题------------------------//


    class test extends single{
      
        public function __construct(){
          parent::__construct();
     }
     
    }


    $t1=new test();               //假如 你改成    $t1=test::getInstance();  那就没问题了
    $t2=new test();

    print_r($t1); 
    print_r($t2); 


    if($t1==$t2){            
        echo '是一个对象';    
    }else{
       echo '不是一个对象';      
    }


    //输出    不是一个对象


    //问题1:我们辛苦写的单例,继承一下就不灵了

    //解决  final    可以解决


    class s{

     public $hash;  

      static protected $ins=NULL;

       final protected function __construct(){
            $this->hash=mt_rand(1,99999);
      }

      static public function getInstance(){
         
            if(self::$ins instanceof self){  //instanceof 专门判断某个对象是不是某个类的实例用的

           return self::$ins;
      }

      self::$ins=new self();
      return self::$ins;

      }


    }


    class t extends s{
       
    }

    $t1=t::getInstance();
    $t2=t::getInstance();

    print_r($t1);
    print_r($t2);


    $t3=clone $t2;        //这里是克隆一份给$t3

    if($t1===$t2){            
        echo '是一个对象';         // 输出 是一个对象
    }else{
       echo '不是一个对象';      
    }


    echo "
    ";


    if($t3===$t2){       //用全等于  暴露出不是一个对象      
        echo '是一个对象';     
    }else{
       echo '不是一个对象';     //  输出 不是一个对象 
    }


    t1 t2显然是一个对象
    而clone出来的t3显然是另一个对象



    //clone又多出一个对象,试问,如何解决?

    //提示:请看魔术方法  clone


    //魔术方法很多

      __construct

      __destruct

      __clone

      __callstatic

        等等

  • 相关阅读:
    eclipse插件开发:创建向导和导航器配置
    eclipse插件开发:属性视图
    标识出下列SQL语句的执行先后顺序
    webapi和webservice的本质区别
    某仪表上市公司.net-————Sql面试题
    Asp.net MVC 用EF来保存高精度小数时会碰到保留4位小数时,后两位默认为0的解决方法
    Asp.net MVC 集成AD域认证
    jquery zTree插件 json 数据详解
    模板列传值到子窗体中,子窗体中多选gridview中checkbox保存数据多项到数据库中
    asp.net comp雷达图
  • 原文地址:https://www.cnblogs.com/suiyuewuxin/p/5608485.html
Copyright © 2011-2022 走看看