Vantagens do padrão de fábrica Magento2 sobre o Magento 1

15

Magento 2 está usando classes de fábrica para não injetáveis.

Por exemplo classe de produto: ProductFactory
Por exemplo classe de cliente:CustomerFactory

Não entendo qual é o tipo de padrão de fábrica aqui?

Porque para cada classe associada a 1 classe de fábrica. Estou pensando que é algo duplicado. Por que não deveríamos criar fábrica abstrata para CustomerFactory, ProductFactoryetc?

e também por exemplo:

Podemos passar AbstractFactorypela verificação de tipo em vez de ProductFactoryno ProductRepositoryconstrutor de classe.

Para evitar o acoplamento apertado entre ProductRepositoryeProductFactory


Classe de fábrica abstrata:

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);
    }
}

Resumo Implementação de fábrica:

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;
    }

}

Qual é a relação entre o gerenciador de objetos e a fábrica?

Há muitos objetos encadeados:

  • Por exemplo ProductRepository(aqui podemos chamá-lo como cliente) requer Productobjeto.

  • Para isso, depende de ProductFactoryobjeto específico .

  • ProductFactoryobjeto depende do ObjectManagerobjeto.

  • ObjectManagerobjeto depende do objeto de fábrica (aqui Developer Object).

É claro que eles estão usando interfaces para acoplamentos soltos. Fluxo ainda muito confuso.

Você pode dar vantagens detalhadas com o padrão de fábrica do Magento 2 e também como ele difere do Magento 1?

sivakumar
fonte

Respostas:

8

Uma coisa a lembrar é que geramos automaticamente classes de fábrica SOMENTE SE VOCÊ NÃO SE DEFINIR. Isso significa que, se você precisar fazer alguma mágica especial na fábrica, poderá fazê-lo. (Por exemplo, se você quiser registrar todas as criações de uma instância por algum motivo, escreva a fábrica você mesmo e não a geraremos automaticamente.) Se usássemos uma única classe abstrata de fábrica para tudo, isso não funcionaria.

Também pode ajudar um pouco na depuração - você pode ver a classe real, definir pontos de interrupção, ver rastreamentos de pilha mais significativos etc.

Alan Kent
fonte
pode haver uma pequena lacuna ... apenas para verificação de tipo, eu quero usar a classe abstrata ... mas sempre que passar, quero passar apenas a classe de fábrica de concreto.
Sivakumar
Interessante - eu teria considerado o contrário. Eu gostaria que o CustomerFactory fosse passado, então eu tenho uma dica de tipo que create () retornará Customer. Com o AbstractFactory, não posso usar a dica do tipo php Storm para descobrir o tipo do objeto retornado da fábrica. (Ou estou faltando alguma coisa?)
Alan Kent
8

Posso estar errado aqui, mas essa é uma vantagem que encontrei.
As fábricas geradas automaticamente são parecidas com os getters ou setters mágicos.
Digamos que você queira que algo aconteça quando uma instância de uma entidade específica (vamos chamá-la de BlogPost) é criada. Digamos que você queira definir um valor padrão para um campo.
O exemplo pode não ser o melhor, mas ouça-me.
Se você usar um factory abstrato, precisará modificá-lo para que, ao receber o instanceName como parâmetro 'BlogPost', chame setDateapós instanciar.

Se você usar uma fábrica settergerada automaticamente, mais tarde poderá criar essa fábrica, chamar o código, remover a fábrica gerada e ela funcionará.
Semelhante ao que você faz com o setter mágico. Você implementa o método e ele é chamado em qualquer lugar.

Marius
fonte
Oi Marius. Obrigado pela sua resposta. Concordo com você. Ainda precisa de mais informações.
Sivakumar
@sivakumar. Eu adoraria uma resposta de um membro da equipe principal também.
Marius