I\'m working in a web app framework, and part of it consists of a number of services, all implemented as singletons. They all extend a Service class, where the singleton behavio
Use trait instead of a abstract class allows to extend a singleton class.
Use the trait SingletonBase for a parent singleton class.
Use the trait SingletonChild for its singleton childs.
interface Singleton
{
public static function getInstance(): Singleton;
}
trait SingletonBase
{
private static $instance=null;
abstract protected function __construct();
public static function getInstance(): Singleton {
if (is_null(self::$instance)) {
self::$instance=new static();
}
return self::$instance;
}
protected function clearInstance(): void {
self::$instance=null;
}
public function __clone()/*: void*/ {
trigger_error('Class singleton '.get_class($this).' cant be cloned.');
}
public function __wakeup(): void {
trigger_error('Classe singleton '.get_class($this).' cant be serialized.');
}
}
trait SingletonChild
{
use SingletonBase;
}
class Bar
{
protected function __construct(){
}
}
class Foo extends Bar implements Singleton
{
use SingletonBase;
}
class FooChild extends Foo implements Singleton
{
use SingletonChild; // necessary! If not, the unique instance of FooChild will be the same as the unique instance of its parent Foo
}