Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extend abstract singleton class

Tags:

If you had a factory class that creates new objects of some kind, and that factroy class is a singleton, like this:

class Database_Factory extends Base_Factory {     private static $factory;     private $objects = array();      public function __get($profile) {         // check for object and return it if it's created before     }      public static function getInstance(){         if (!self::$factory)             self::$factory = new self();         return self::$factory;     } } 

The same code repeats anytime where some object needs it's own factory. So i decided to make this factory class abstract and implement only specific routines for each factory. But PHP does not allow to instantiate abstract class.

abstract class Base_Factory {     public static function getInstance(){         if (!self::$factory)             self::$factory = new self();         return self::$factory;     } } 

Fatal error: Cannot instantiate abstract class Base_Factory

What would you do?

like image 569
Deniss Kozlovs Avatar asked Nov 30 '09 09:11

Deniss Kozlovs


People also ask

Can a singleton class be abstract?

The Singleton pattern requires a private constructor and this already makes subclassing impossible. You'll need to rethink your design. The Abstract Factory pattern may be more suitable for the particular purpose. The purpose of the private constructor in the Singleton is to prevent anyone else instantiating it.

Can we extend singleton class in C#?

Yes you can. Keep base class constructor protected (and not private). Then derived class can be instantiated but base class cannot be (even inside function definitions of derived class).

Can singleton object be modified?

One of the strengths of the Singleton design pattern, as opposed to static methods, is that if you change your mind and want more than one, the Singleton class can be easily altered. For example, most servlets run as Singletons in their servlet engines.

How do I override singleton class?

The only way to override a singleton is to have a singleton that expects to be overridden. The simplest way to do this is to provide Singleton that implements an interface (or is otherwise fully abstract itself) that internally instantiates an injected singleton upon the first use of getInstance() .


1 Answers

In PHP methods, self always refers to the class where the method is defined. Since version 5.3.0, PHP supports “late static binding”, where you can use the static keyword to access overridden static methods, as well as the function get_called_class() to get the name of the derived class in static context.

However, your design has a major flaw: The static property $factory defined in Base_Factory is shared across all derived classes. Therefore, the first time a singleton is created and stored in this property, all other calls to getInstance() will return the same object, no matter what derived class is used.

You could use a static dictionary mapping class names to singleton objects:

abstract class Base_Factory {     private static $_instances = array();     public static function getInstance() {         $class = get_called_class();         if (!isset(self::$_instances[$class])) {             self::$_instances[$class] = new $class();         }         return self::$_instances[$class];     } } 

Oh, one more thing: The fact that you are looking for a possibility to re-use code for singleton objects could be a cue to the fact that you are over-using the singleton design pattern! Ask yourself if the classes you are planning to implement as singletons really are singletons and if there will be no use case where you might want to have multiple instances of the particular class.

Often it is much better to use just one singleton representing the current “application context” that provides accessors for objects that are singletons with respect to this context.

like image 161
Ferdinand Beyer Avatar answered Sep 28 '22 03:09

Ferdinand Beyer