Ventajas del patrón de fábrica Magento2 sobre Magento 1

15

Magento 2 está utilizando clases de fábrica para no inyectables.

Por ejemplo, clase de producto: ProductFactory
Por ejemplo, clase de cliente:CustomerFactory

No entiendo cuál es el tipo de patrón de fábrica aquí.

Porque para cada clase asociada con 1 clase de fábrica. Estoy pensando que es algo duplicado. ¿Por qué no deberíamos crear una fábrica abstracta para CustomerFactory, ProductFactoryetc.?

y también por ejemplo:

Podemos pasar AbstractFactorypara la verificación de tipo en lugar de ProductFactoryen el ProductRepositoryconstructor de clase.

Así podemos evitar un acoplamiento estrecho entre ProductRepositoryyProductFactory


Clase abstracta de fábrica:

namespace Magento\Framework\ObjectManager\Code\Generator;

/**
 * Abstract Factory class 
 */
abstract class AbstractFactory 
{
    /**
     * Object Manager instance
     *
     * @var \Magento\Framework\ObjectManagerInterface
     */
    protected $_objectManager = null;

    /**
     * Instance name to create
     *
     * @var string
     */
    protected $_instanceName = null;


    /**
     * Create class instance with specified parameters
     *
     * @param array $data
     * @return \Magento\Catalog\Model\Product
     */
    public function create(array $data = array())
    {
        return $this->_objectManager->create($this->_instanceName, $data);
    }
}

Implementación de Abstract Factory:

namespace Magento\Catalog\Model;
use Magento\Framework\ObjectManager\Code\Generator\AbstractFactory;
/**
 * Factory class for @see \Magento\Catalog\Model\Product
 */
class ProductFactory extends AbstractFactory
{

    public function __construct(\Magento\Framework\ObjectManagerInterface $objectManager, $instanceName = '\\Magento\\Catalog\\Model\\Product')
    {

        $this->_objectManager = $objectManager;
        $this->_instanceName = $instanceName;
    }

}

¿Cuál es la relación entre el administrador de objetos y la fábrica?

Hay mucho de encadenar objetos:

  • Por ejemplo ProductRepository(aquí podemos llamarlo como cliente) requiere Productobjeto.

  • Para esto depende de un ProductFactoryobjeto específico .

  • ProductFactoryEl objeto depende del ObjectManagerobjeto.

  • ObjectManagerEl objeto depende del objeto de fábrica (aquí Developer Object).

Por supuesto, están utilizando interfaces para acoplamiento flojo. Sigue siendo un flujo realmente confuso.

¿Alguien puede dar ventajas en profundidad con el patrón de fábrica Magento 2 y también en qué se diferencia de Magento 1?

sivakumar
fuente

Respuestas:

8

Una cosa para recordar es que autogeneramos clases de fábrica SÓLO SI NO SE DEFINE UNO MISMO. Eso significa que si necesita hacer algo de magia especial en la fábrica, puede hacerlo. (Por ejemplo, si desea registrar cada creación de una instancia por alguna razón, escriba la fábrica usted mismo y no la generaremos automáticamente). Si usáramos una sola clase de fábrica abstracta para todo, esto no funcionaría.

También puede ayudar un poco con la depuración: puede ver la clase real, puede establecer puntos de interrupción, ver trazas de pila más significativas, etc.

Alan Kent
fuente
puede ser una pequeña brecha ... para la verificación de tipos solo quiero usar la clase abstracta ... pero cada vez que pase quiero pasar solo la clase de fábrica de concreto.
sivakumar
Interesante: lo habría considerado al revés. Me gustaría que se pasara CustomerFactory, por lo que tengo sugerencias de tipo que create () devolverá Customer. Con AbstractFactory, no puedo usar las sugerencias de tipo php Storm para calcular el tipo del objeto devuelto de fábrica. (¿O me estoy perdiendo algo?)
Alan Kent
8

Puedo estar equivocado aquí, pero esta es una ventaja que encontré.
Las fábricas autogeneradas son algo similares con los captadores o setters mágicos.
Supongamos que desea que suceda algo cuando se crea una instancia de una entidad específica (llamémosla BlogPost). Supongamos que desea establecer un valor predeterminado en un campo.
El ejemplo puede no ser el mejor, pero escúchame.
Si usa una fábrica abstracta, tendrá que modificarla para que cuando reciba el nombre de instancia como parámetro 'BlogPost' llamesetDate después de crear una instancia.

Si usa la fábrica autogenerada, más tarde puede crear esa fábrica, llamar settera su código, eliminar la fábrica generada y funcionará.
Similar a lo que haces con el setter mágico. Implementa el método y se llama en todas partes.

Marius
fuente
Hola Marius. Gracias por tu respuesta. Estoy de acuerdo contigo. Todavía necesito más información.
sivakumar
@sivakumar. Me encantaría una respuesta de un miembro del equipo central también.
Marius