2013-07-25 60 views
1

У меня есть класс Foo и класс Bar и я хочу использовать Bar «s статические методы, чтобы получить одноэлементный экземпляр Foo, (по аналогии с тем, как BitmapFactory.create() возвращает Bitmap экземпляр), НО Foo не следует вводить с помощью new Foo(), как я могу это получить?Factory статические методы и частные конструкторы

class Foo { 
    $private Foo() {} // ?? 
} 

class Bar { 
    private static $foo = null; 
    static function getFooInstance() { 
     if(Bar::$foo == null) $foo = new Foo();    
     return Bar::$foo; 
    } 
} 



$foo = Bar::getFooInstance(); 

ответ

0

, что вы хотите сделать, это Foo одноэлементно и сделать Bar правопреемником преградить по Foo::getInstance(); Например:

class Foo { 
    private static $instance; 
    private function __construct(){} 
    public static function getInstance(){ 
     if (!isset(self::$instance)){ 
      self::$instance = new Foo(); 
     } 
     return self::$instance; 
    } 
    public function __clone(){ 
     throw new Exception("Cannot Clone Singletons... bad programmer"); 
    } 
} 

class Bar { 
    static function getFooInstance() { 
     return Foo::getInstance(); 
    } 
} 

Там нет необходимости переигрывать шаблон одноэлементный в баре, как Foo уже Политики - это собственный экземпляр.

+0

1) Вместо 'self :: $ instace = new Foo()' вы могли бы определить его как: 'self :: $ instance = new self()' 2) Вы можете придерживаться принципа DRY здесь, просто например: '$ i = & self :: $ instance; if (is_null ($ i)) {$ i = new self();} return $ i; ' – Yang

+0

@DaveJust, вы ничего не получаете, делая это, хотя .... Он всегда будет возвращать' Foo' .. вам придется использовать 'static' вместо' self', потому что это означает что-то другое (как подкласс foo). – Orangepill

0

Здесь нет необходимости использовать одноэлементный шаблон. Синглтон - плохая модель, и ее следует избегать.

Лучшее решение: Сделать статический заводский метод в Bar, который гарантирует, что будет создан только один Foo. Вы уже это сделали.

И для Foo: Просто не создавайте экземпляр на своем собственном в своем продуктивном коде. Но вы действительно хотите создать несколько копий Foo в своих тестах! Из-за этого вы не можете сделать конструктор Foo непубличным.

Объекты, которые обычно создаются только один раз, должны играть важную роль в вашем приложении. Скорее всего, они будут созданы один раз в начале, а затем использованы для нескольких вещей. Создайте выделенный заводский класс для этого (или, возможно, по одному для темы: для моделей, для базы данных и для шаблонов). Сделайте это привычкой использовать эти фабрики только для создания объектов.

Или, что еще лучше, добавьте это в свою инфраструктуру впрыска Dependency как конфигурацию. Использование при получении объектов в основном одинаково.

Смежные вопросы