В методах PHP self
всегда относится к классу, в котором определен метод. Начиная с версии 5.3.0, PHP поддерживает «позднюю статическую привязку», где вы можете использовать ключевое слово static
для доступа к переопределенным статическим методам, а также функцию get_called_class()
для получения имени производного класса в статическом контексте.
Однако в вашем дизайне есть существенный недостаток: статическое свойство $factory
, определенное в Base_Factory
, является общим для всех производных классов. Поэтому при первом создании и сохранении синглтона в этом свойстве все другие вызовы getInstance()
будут возвращать один и тот же объект, независимо от того, какой производный класс используется.
Вы можете использовать статический словарь, отображающий имена классов в одноэлементные объекты:
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];
}
}
О, еще одна вещь: тот факт, что вы ищете возможность повторного использования кода для одноэлементных объектов, может свидетельствовать о том, что вы чрезмерно используете шаблон одноэлементного проектирования! Спросите себя, действительно ли классы, которые вы планируете реализовать как синглтоны, являются синглетонами, и не будет ли случая, когда вы захотите иметь несколько экземпляров определенного класса.
Часто гораздо лучше использовать только один синглтон, представляющий текущий «контекст приложения», который предоставляет средства доступа для объектов, которые являются одиночными по отношению к этому контексту.