扩展单例类

发布于 2024-08-27 10:57:31 字数 377 浏览 8 评论 0原文

我曾经像这样创建单例类的实例:

$Singleton = SingletonClassName::GetInstance();

对于非单例类:

$NonSingleton = new NonSingletonClassName;

我认为我们不应该区分如何创建类的实例,无论它是否是单例。如果我看看其他班级的看法,我不在乎我们的班级是否需要单例班级。所以,我仍然对 php 如何对待单例类感到不舒服。我想并且我一直想写:

$Singleton = new SingletonClassName;

只是另一个非单例类,这个问题有解决方案吗?

i used to create an instance of a singleton class like this:

$Singleton = SingletonClassName::GetInstance();

and for non singleton class:

$NonSingleton = new NonSingletonClassName;

i think we should not differentiate how we create an instance of a class whether this is a singleton or not. if i look in perception of other class, i don't care whether the class we need a singleton class or not. so, i still not comfortable with how php treat a singleton class. i think and i always want to write:

$Singleton = new SingletonClassName;

just another non singleton class, is there a solution to this problem ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

魔法少女 2024-09-03 10:57:31

最好是相反 - 为非单例提供 工厂方法 ,并获得它们使用的实例:

$NonSingleton = NonSingletonClassName::createInstance();

这是推荐的 Java 最佳实践(位于 Effective Java),但它适用于大多数面向对象语言。

It better be the other way around - provide a factory-method for non-singletons, and get instances of them using:

$NonSingleton = NonSingletonClassName::createInstance();

This is a recommended best practice for Java (in Effective Java), but it applies to most object-oriented languages.

我不是你的备胎 2024-09-03 10:57:31

我不会推荐它,因为它会让你的代码更难理解(人们认为 new 意味着一个全新的对象)。但我不会推荐使用单例。

这段代码的基本思想是在单例周围有一个包装器。通过该包装器访问的所有函数和变量实际上都会影响单例。它并不完美,因为下面的代码没有实现很多魔术方法和 SPL 接口,但如果需要的话可以添加它们

代码

/**
 * Superclass for a wrapper around a singleton implementation
 *
 * This class provides all the required functionality and avoids having to copy and
 * paste code for multiple singletons.
 */
class SingletonWrapper{
    private $_instance;
    /**
     * Ensures only derived classes can be constructed
     *
     * @param string $c The name of the singleton implementation class
     */
    protected function __construct($c){
        $this->_instance = &call_user_func(array($c, 'getInstance'));
    }
    public function __call($name, $args){
        call_user_func_array(array($this->_instance, $name), $args);
    }
    public function __get($name){
        return $this->_instance->{$name};
    }
    public function __set($name, $value){
        $this->_instance->{$name} = $value;
    }
}

/**
 * A test singleton implementation. This shouldn't be constructed and getInstance shouldn't
 * be used except by the MySingleton wrapper class.
 */
class MySingletonImpl{
    private static $instance = null;
    public function &getInstance(){
        if ( self::$instance === null ){
            self::$instance = new self();
        }
        return self::$instance;
    }

    //test functions
    public $foo = 1;
    public function bar(){
        static $var = 1;
        echo $var++;
    }
}

/**
 * A wrapper around the MySingletonImpl class
 */
class MySingleton extends SingletonWrapper{
    public function __construct(){
        parent::__construct('MySingletonImpl');
    }
}

示例

$s1 = new MySingleton();
echo $s1->foo; //1
$s1->foo = 2;

$s2 = new MySingleton();
echo $s2->foo; //2

$s1->bar(); //1
$s2->bar(); //2

I wouldn't recommend it as it would make your code a lot harder to understand (People think new means an entirely new object). But then I wouldn't recoemmed the use of Singletons.

The basic idea of this code is that there is a wrapper around a singleton. All functions and variables accessed through that wrapper actually effect the singleton. It isn't perfect as the code below doesn't implement a lot of magic methods and SPL interfaces but they can be added in if required

Code

/**
 * Superclass for a wrapper around a singleton implementation
 *
 * This class provides all the required functionality and avoids having to copy and
 * paste code for multiple singletons.
 */
class SingletonWrapper{
    private $_instance;
    /**
     * Ensures only derived classes can be constructed
     *
     * @param string $c The name of the singleton implementation class
     */
    protected function __construct($c){
        $this->_instance = &call_user_func(array($c, 'getInstance'));
    }
    public function __call($name, $args){
        call_user_func_array(array($this->_instance, $name), $args);
    }
    public function __get($name){
        return $this->_instance->{$name};
    }
    public function __set($name, $value){
        $this->_instance->{$name} = $value;
    }
}

/**
 * A test singleton implementation. This shouldn't be constructed and getInstance shouldn't
 * be used except by the MySingleton wrapper class.
 */
class MySingletonImpl{
    private static $instance = null;
    public function &getInstance(){
        if ( self::$instance === null ){
            self::$instance = new self();
        }
        return self::$instance;
    }

    //test functions
    public $foo = 1;
    public function bar(){
        static $var = 1;
        echo $var++;
    }
}

/**
 * A wrapper around the MySingletonImpl class
 */
class MySingleton extends SingletonWrapper{
    public function __construct(){
        parent::__construct('MySingletonImpl');
    }
}

Examples

$s1 = new MySingleton();
echo $s1->foo; //1
$s1->foo = 2;

$s2 = new MySingleton();
echo $s2->foo; //2

$s1->bar(); //1
$s2->bar(); //2
孤君无依 2024-09-03 10:57:31

您不能像创建常规类实例一样创建 Singleton。 new 将始终返回一个新实例,因此您必须将构造函数设置为非公共的,因此您必须有不同的方法从类内调用它。

您可以在所有类上使用工厂方法,例如始终执行 getInstance() ,如另一个答案中所示。另一种选择是使用 服务定位器依赖注入框架知道是否返回什么。

You cannot create a Singleton the same way as a regular class instance. new will always return a new instance, thus you have to have the constructor non-public and thus you have to have a different means to call it from within the class.

You could have factory methods on all classes, e.g. always do getInstance() like shown in another answer. Another option would be to use a Service Locator and Dependency Injection Framework that knows whether to return what.

风柔一江水 2024-09-03 10:57:31

基于 new 关键字意味着您想要的一切都是无关紧要的。 new 创建类的新实例,这就是它命名为 new 的原因:-)

Based on what new keyword means all you want is irrelevant. new creates new instance of class, thats why it named new :-)

用心笑 2024-09-03 10:57:31

我知道这是一篇非常旧的文章,但在下面的链接的帮助下我更好地理解了工厂模式。

因此,如果它有助于未来的徘徊。 。 。 。这里是

http://www.devshed.com/c/a/PHP/Design-Patterns-in-PHP-Factory-Method-and-Abstract-Factory/1/

掌握和理解基本知识非常简单执行。

I know this is a really old post, but i understood Factory pattern better with the help of the below link.

So if it helps an future wandered. . . . here goes

http://www.devshed.com/c/a/PHP/Design-Patterns-in-PHP-Factory-Method-and-Abstract-Factory/1/

It was very simple to grasp and understand the basic implementation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文