Reescrevendo Magento 2 classes vs Plugins

17

O Magento 2 tem o conceito de Plugins / Interceptação / Interceptores opostos ao Magento 1.
Eles agem como um | antes do evento para todos os métodos públicos. Que é bom.
Você também pode usar o aroundplug-in para substituir a funcionalidade de um método.
Mas o Magento 2 ainda oferece a possibilidade de reescrever classes mais ou menos da maneira M1.
Gostaria de ver alguns exemplos em que reescrever classes é o caminho a seguir, em vez de usar plug-ins.
Sei que isso é útil quando você deseja alterar o comportamento de um método protegido por núcleo, mas há outros casos em que uma reescrita é recomendada ou necessária?

Marius
fonte
1
Relacionados: magento.stackexchange.com/questions/93932/...
Robbie Averill

Respostas:

19

O motivo óbvio para usar uma reescrita em vez de um plug-in é quando você precisa substituir um método privado, protegido ou final .

Mas também considere os seguintes cenários.

1º cenário (ordem de classificação absoluta):

As regravações podem ser úteis quando você precisar que seu código seja executado antes dos plug-ins . Eu sei que você pode fazer isso configurando o plug-in sortOrder, mas não pode ter certeza de que seu código será sempre o primeiro quando alguém (não você) instalará componentes de terceiros.

Segundo cenário (excluir código):

Se você precisar excluir ou reescrever apenas um pedaço de código em um método, um plug-in pode ser uma maneira abaixo do ideal. Eu sei que você pode usar um aroundplug - in e evitar chamar o proceed, mas isso pode quebrar outros plug-ins na pilha.

Terceiro cenário (estilo de código):

Você deve reescrever quando precisar reescrever um comportamento; os plug-ins devem ser usados ​​para modificar a saída ou executar o código antes / depois.

Um plug-in deve sempre executar o código original para evitar a quebra de outros módulos.

Minha conclusão:

Se você pode considerar um método principal como uma caixa preta com uma entrada e uma saída e não souber sobre seus mecanismos internos, um plug-in pode ser a melhor opção.

Se você precisar alterar um comportamento interno , uma reescrita pode ser a melhor opção.

Phoenix128_RiccardoT
fonte
O primeiro cenário é um pouco impreciso (acho que é apenas a redação), pois um plug-in anterior ou ao redor é executado (ou pode ser executado) antes do código do método real.
David Verholen
Sim, minha redação não estava correta. Meu argumento era sobre a ordem de classificação relativa com o método real.
Phoenix128_RiccardoT
7

Ótima pergunta, eu me fiz a mesma coisa no outro dia e aqui está o que eu vim com:

  • Primeiro, plugins não podem ser usados ​​para métodos finais, classes finais e classes criadas sem injeção de dependência. Acho que é um caso muito específico, mas é um caso em que você não pode usar plugins
  • Segundo, você precisa ter em mente a definição de um plugin. É usado para trabalhar em um nível de método, enquanto as preferências são usadas para trabalhar em todo o nível da classe. Não é óbvio para todos, por isso é bom ter isso em mente.
  • Finalmente, e eu acho que é o mais importante, parece que os plugins só podem ser usados ​​para estender o comportamento de qualquer método público dentro de uma classe Magento . Portanto, parece que você não pode usar plug-ins com métodos protegidos / privados .

Fonte: Curso Fundamental Magento U

Raphael na Digital Pianism
fonte
2
Está bem. Boas razões. Não sei o que dizer sobre o segundo ponto. Se você deseja plug-in de vários métodos públicos da mesma classe, acho que a maneira mais segura é criar uma única classe que atue como um plug-in para todos eles. (minha opinião). Deixarei isso em aberto de 2 a 3 dias para ver se alguém apresenta outros motivos. Caso contrário, a marca de seleção é sua.
Marius
@ Marius você está absolutamente certo re: segundo ponto. Por algumas razões, pensei que você tinha que criar vários arquivos de plugins para todos os métodos que desejava, mas acho que é isso que os observadores fazem, não os plugins. Seria legal se mais pessoas responderem para ver se há mais razões (não óbvias).
Raphael no Digital Pianism
1
@ marius como uma adição: como os plug-ins devem ser específicos do domínio, acho que deve ser pelo menos uma prática recomendada definir apenas vários plug-ins em uma classe, se eles forem uma implementação do mesmo recurso. Com uma reescrita, você não tem essa opção, pois sempre altera uma classe inteira. Então eu acho que seria um motivo para pelo menos tentar reescrever a evitar
David Verholen
@DavidVerholen. Eu concordo totalmente. Mas eu estava pedindo motivos para usar reescritas em vez de plugins.
Marius
sim, eu acho que isso poderia ser uma razão para usar plugins desde que você pode definir característica específica do plugin aulas, enquanto uma reescrita só pode ser feito uma vez
David Verholen