Estoy tratando de diseñar un conjunto de clases de fábrica para nuestro sistema, donde algunos objetos creados por la fábrica también deben inicializarse antes de que puedan ser utilizados correctamente.Clase de fábrica con inicialización de objetos - tratando de evitar estática
Ejemplo:
$foobar = new Foobar();
$foobar->init($qux, ...);
// $foobar ready for usage
Por la misma de ejemplo, digamos que el objeto $qux
es la única dependencia que Foobar
necesidades. Lo que me gustaría llegar a es:
$foobar = Foo_Factory('bar');
Con el fin de evitar la necesidad de pasar a lo largo del objeto $qux
en todo el sistema y pasarlo a la clase de fábrica como un parámetro más, me gustaría llevar a cabo inicialización de Foobar
directamente en la clase de fábrica:
class Foo_Factory {
public static function getFoo($type) {
// some processing here
$foo_name = 'Foo' . $type;
$foo = new $foo_name();
$foo->init($qux);
return $foo;
}
}
Hay pocas soluciones que vienen a la mente, pero ninguno de ellos es ideal:
- Añadir un colocador estática metanfetamina od para
$qux
a la clase de fábrica, y que almacene una referencia a$qux
en una variable privada estática. El sistema puede establecer$qux
al inicio, y la clase de fábrica puede evitar cualquier cambio futuro (por razones de seguridad).
Aunque este enfoque funciona, el uso de un parámetro estático para almacenar la referencia a$qux
es problemático durante las pruebas unitarias (por ejemplo, afortunadamente la vida sobrevive entre las pruebas individuales debido a su estado estático). - Crea una nueva clase de contexto usando el patrón Singleton y deja que la clase de fábrica lo use para obtener una referencia a
$qux
. Esta podría ser una forma un poco más limpia de hacer esto que la opción n. ° 1 (aunque movemos el problema estático de la clase de fábrica a la clase de contexto). - Use la inyección de dependencia por completo, es decir, pase
$qux
a cualquier objeto que use la clase de fábrica, y deje que ese objeto lo transmita a la clase de fábrica como otro parámetro:Foo_Factory::getFoo($type, $qux);
. - Igual que el anterior (n. ° 3), pero en lugar de pasar
$qux
a lo largo del sistema, pase una instancia de la clase de fábrica (es decir, en este caso no sería estático, pero sería instantilable).
¿Qué recomendarías por favor? ¿Alguna de las cuatro alternativas mencionadas anteriormente, o hay una mejor manera de hacerlo, por favor?
Nota: No quiero entrar en un llamarada static is evil
aquí, solo tratando de encontrar la mejor solución.
Ah, eso es muy bueno en realidad - veo que voy a tener que mirar en sinfonía con más detalle (prácticamente) cuando tengo la oportunidad. Creé una solución de contenedor simple, y mientras sigo usando las fábricas internamente, funciona como un encanto :-) ¡Gracias por los comentarios y el ejemplo! – MicE