在PHP中可以定义Singleton接口吗?

ojsjcaue  于 2023-10-15  发布在  PHP
关注(0)|答案(5)|浏览(95)

我想定义一个Singleton基类型,用户将从中派生他的类,所以这是我的想法:

interface SingletonInterface {
    public static function getInstance();
}

abstract class SingletonAbstract implements SingletonInterface {
    abstract protected function __construct();
    final private function __clone() {}
}

但是使用这种方法,用户可以实现这个单例。

class BadImpl implements SingletonInterface {
    public static function getInstance() {
        return new self;
    }
}

你的计划是什么?

z0qdvdin

z0qdvdin1#

记住PHP不允许多重继承,所以你必须仔细选择你的类所基于的对象。Singleton很容易实现,最好让每个类定义它。还要注意的是,私有字段不会被移植到子类中,因此你可以有两个同名的不同字段。

wmvff8tz

wmvff8tz2#

我使用以下代码创建一个Singleton:

abstract class Singleton {

    private static $_aInstance = array();

    private function __construct() {}

    public static function getInstance() {

       $sClassName = get_called_class(); 

       if( !isset( self::$_aInstance[ $sClassName ] ) ) {

          self::$_aInstance[ $sClassName ] = new $sClassName();
       }
       $oInstance = self::$_aInstance[ $sClassName ];

       return $oInstance;
    }

    final private function __clone() {}
}

这是使用这种模式:

class Example extends Singleton {
   ...
}

$oExample1 = Example::getInstance();
$oExample2 = Example::getInstance();

if(is_a( $oExample1, 'Example' ) && $oExample1 === $oExample2){

    echo 'Same';

} else {

    echo 'Different';
}
h22fl7wq

h22fl7wq3#

首先:如果你在项目中有这么多的Singleton,那么你可能会在投影层面上搞砸一些事情。
其次:Singleton应该在这里使用,而且只在这里使用,在这里,一个类的多个示例完全没有意义,或者可能会导致一些错误
最后:继承不是为了减少代码量而设计的

apeeds0o

apeeds0o4#

你现在可以使用traits,但是你需要这么多的单例吗?

siv3szwd

siv3szwd5#

另一种选择是使用依赖注入容器,它们通常提供一种配置“单例”的方法。例如
关于Symfony DependencyInjection

services:
    app.my_singleton_service:
        class: App\Service\MyService
        shared: true

关于Pimple

$container['my_singleton_service'] = $container->share(function ($container) {
    return new MyService();
});

关于Level-2Dice

$dice->addRules[App\Service\MyService::class => ['shared' => true]]);


此外,你可以创建一个简单的接口,不需要方法Singleton,然后为你的依赖注入容器自动生成配置。

相关问题