Класс фабрики с инициализацией объекта - попытка избежать статики

Я пытаюсь разработать набор фабричных классов для нашей системы, где некоторые объекты, созданные фабрикой, также должны быть инициализированы, прежде чем их можно будет использовать должным образом.

Пример:

$foobar = new Foobar();
$foobar->init( $qux, ... );
// $foobar ready for usage

Для В том же примере, допустим, что объект $ qux - единственная зависимость, которая нужна Foobar . Я бы хотел получить следующее:

$foobar = Foo_Factory( 'bar' );

Чтобы избежать необходимости передавать объект $ qux по всей системе и передавать его классу фабрики в качестве другого параметра, я бы хотелось бы выполнить инициализацию Foobar непосредственно в фабричном классе:

class Foo_Factory {

    public static function getFoo( $type ) {

        // some processing here
        $foo_name = 'Foo' . $type;
        $foo = new $foo_name();
        $foo->init( $qux );

        return $foo;
    }

}

На ум приходит несколько решений, но ни одно из них не является идеальным:

  1. Добавьте статический метод установки для $ qux в фабричный класс, и пусть он хранит ссылку на $ qux в частной статической переменной. Система может установить $ qux в начале, и фабричный класс может предотвратить любые будущие изменения (по соображениям безопасности).
    Хотя этот подход работает, используя статический параметр для хранения ссылки на $ qux проблематичен во время модульного тестирования (например, он счастливо выживает, выживает между отдельными тестами из-за своего статического состояния).
  2. Создайте новый класс контекста, используя шаблон Singleton, и позвольте классу фабрики использовать его для получения ссылки на $ qux . Это может быть немного более чистый способ сделать это, чем вариант №1 (хотя мы перемещаем статическую проблему из класса фабрики в класс контекста).
  3. Используйте внедрение зависимостей полностью, т.е. pass $ qux к любому объекту, который использует фабричный класс, и пусть этот объект передает его классу-фабрике в качестве другого параметра: Foo_Factory :: getFoo ($ type, $ qux); .
  4. То же, что и выше (# 3), но вместо передачи $ qux по всей системе, вместо этого передайте экземпляр фабричного класса (т.е. в этом случае он будет не статическим, а создаваемым).

Что вы порекомендуете, пожалуйста? Любая из четырех альтернатив, упомянутых выше, или есть лучший способ сделать это, пожалуйста?

Примечание: я не хочу впадать в статику зла флеймвара здесь, просто пытаюсь подойти с лучшим решением.

7
задан ROMANIA_engineer 12 April 2017 в 16:03
поделиться