• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

看看这个类的实例化方式能否实现“单例模式”?

php 搞代码 3年前 (2022-01-25) 15次浏览 已收录 0个评论
文章目录[隐藏]

比如我有一个类,类名是A(这个类本身不是实现单例模式的,看后面实例化这个类的方式):

<code>class A(){    public $str = '这是属性';    public $str2 = '属性';    private $str3 = '私有属性';        public function __construct($a,$b,$c){        //构造方法    }        public function func1(){        //类的方法    }        public function func2(){        //类的方法    }}</code>

还有一个全局函数:

<code>function getObj(){    require PATH.'a.class.php';//引入上面定义的class A的文件    static $instance;//定义静态变量    if($instance){        return $instance;    }    $instance = new A('1','2','3');    return $instance;}</code>

然后我要在其他地方调用类A的实例,并且可能需要一次请求调用多次,通过getObj方法来得到这个类的实例,因为是返回的静态变量,其实在第一次创建这个类的实例后,后面调用都是直接用的这个静态变量的实例,并没有重新new一个新的实例,这种方式算不算单例模式??如果不算,主要是哪里不同会有什么隐患??十分感谢!

回复内容:

比如我有一个类,类名是A(这个类本身不是实现单例模式的,看后面实例化这个类的方式):

<code>class A(){    public $str = '这是属性';    public $str2 = '属性';    private $str3 = '私有属性';        public function __construct($a,$b,$c){        //构造方法    }        public function func1(){        //类的方法    }        public function func2(){        //类的方法    }}</code>

还有一个全局函数:

<code>function getObj(){    require PATH.'a.class.php';//引入上面定义的class A的文件    static $instance;//定义静态变量    if($instance){        return $instance;    }    $instance = new A('1','2','3');    return $instance;}</code>

然后我要在其他地方调用类A的实例,并且可能需要一次请求调用多次,通过getObj方法来得到这个类的实例,因为是返回的静态变量,其实在第一次创建这个类的实例后,后面调用都是直接用的这个静态变量的实例,并没有重新new一个新的实例,这种方式算不算单例模式??如果不算,主要是哪里不同会有什么隐患??十分感谢!

接下去就要是PHP7的时代了,你的代码还停留在看上去像是5.x早期时代的PHP代码,本身代码应该可以跑通,你的使用方式从宽泛的定义上来讲,勉强可以算单例,但是整体感觉非常奇怪。并且如别的回答提出的,如果别人不知道getObj函数的话,很有可能就自己new了,你的获取对象的函数无法对别人起到约束作用

既然你的构造函数依赖三个参数,这是我对于这份代码的建议实现

<code>class A(){    public $str = '这是属性';    public $str2 = '属性';    private $str3 = '私有属性';        private static $pool = [];        public static function getInstance($a, $b, $c)    {        /**         * 这里假设一种情况是需要这三个参数这个对象才唯一         * 并且这三个参数都是可以转换为字符串类型的         *(也就是说不能是stream,array,或者没有__toString()实现的object)         */        $key = impl<mark>@本文来源gaodaimacom搞#代%码@网-</mark><strong>搞代gaodaima码</strong>ode('_', func_get_args());         if (!isset(self::$pool[$key])) {            /**             * 关于这里使用static关键字详情请看后期静态绑定             * http://php.net/manual/zh/language.oop5.late-static-bindings.php             * 如果你的PHP还在用5.3以前的版本,请使用             * self::$pool[$key] = new self($a, $b, $c);             */            self::$pool[$key] = new static($a, $b, $c);         }                return self::$pool[$key];    }        protected function __construct($a, $b, $c)    {        //构造方法,没有使用private是考虑如果有子类继承的情况    }        public function func1()    {        //类的方法    }        public function func2()    {        //类的方法    }}</code>

PS 另外建议题主去了解一下PSR规范和autoload

会报错的,而且这种写法很糟糕

其实不算。原因如下:
1.假设是多线程的环境,多个线程同时进入会不会同时产生多个对象呢,所以需要你进行冗余处理。我不知道php是怎么做的,但是Java可以通过sync关键字来搞定同步。
2.你构造函数是公有的,假设别人在你的代码上二次开发,但他不知道你的这个getobj。他就会自己new一个。这样也会有问题。


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:看看这个类的实例化方式能否实现“单例模式”?

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址