
Olá pessoal. Quero confessar diante de você e contar um pouco sobre como me sinto quando desenvolvo no Laravel. Não, não pense, eu amo esse framework e sou extremamente grato à equipe que o criou e o apoia, eles fazem um trabalho extremamente legal e, na minha opinião, o Laravel é a melhor continuação do Symfony, não menos amada por mim.
Eu amo código idiota. É mudo no sentido de que, mesmo depois de dez anos, se o cliente solicitar que você faça alterações, você poderá fazer isso sem se aprofundar na lógica, mesmo depois de participar de uma festa corporativa na sexta-feira, sem quebrar nada no código antigo. E burro no sentido de que você não precisa fazer nenhum esforço cognitivo para entendê-lo. Mas há uma solução arquitetônica no Laravel Eloquent ORM que me faz chorar. Interessante? Venha sob o gato.
As pessoas inteligentes criaram tudo para nós há muito tempo: OOP, Design Patterns, SOLID, DDD e outras palavras assustadoras que o assustam tanto no começo e depois são aplicadas com pressa.
Eu gosto do Laravel e do Symfony. Eles permitem que você escreva o código mais idiota e seguro imediatamente. Sim Cada um deles tem suas desvantagens ... Mas no Laravel há um que me incomoda mais. Isso está usando o Active Record Pattern (AR) para trabalhar com modelos.
Para começar, um pouco sobre esse padrão. O que é isso tudo? Para entender, você deve ir para o pai desse trabalho de design de aplicativo - o padrão do Repositório. Esse padrão é uma coleção. Uma coleção de entidades (Entidade) que podem recuperar, modificar, salvar, excluir, em geral, gerenciá-las em um local de armazenamento abstrato. Em 90% dos 100% dos casos, esse local de armazenamento é uma variedade de bancos de dados. Mas pode haver um sistema de arquivos, algum tipo de cache e até uma API externa.
Essa abordagem é totalmente consistente com o princípio da responsabilidade compartilhada e a abordagem DDD. Além disso, graças a essa abordagem, a conectividade fraca é implementada - não nos importamos como exatamente o aplicativo é armazenado, trabalhamos com a Entity quando queremos trabalhar diretamente com a representação de dados dos objetos e trabalhamos com o Repository quando precisamos interagir com o repositório.
Mas o Laravel decidiu seguir o caminho do uso de AR, que é inegavelmente legal e incrivelmente conveniente quando você precisa criar um protótipo rápido, mas torna-se uma dor de cabeça incrível quando você precisa interagir com várias fontes de dados e operar com elas no sistema.
AR é um padrão que mapeia Entidade e Repositório em um Modelo. Ou seja, um objeto se torna uma representação de um registro específico no banco de dados. E ... o que? O que isso leva e por que é tão irritante?
Primeiro, violamos o mesmo princípio de responsabilidade compartilhada - a lógica de trabalhar com o repositório em um lugar e a lógica de trabalhar com uma entidade em outro. Isso é importante porque, na estrutura do meu sistema, não desejo transferir uma linha do banco de dados na representação do objeto através da cadeia de chamadas. Eu quero passar o modelo. Eu não deveria dar a mínima para como isso acontece, muda e persiste. Preciso ter os métodos que permitem interagir apenas com o modelo, e não com as linhas no banco de dados.
Em segundo lugar, não podemos (como conseqüência do fato de a camada Persistente - a camada de armazenamento - estar conectada à camada de entidade) simplesmente alterar o local de armazenamento do modelo. Sim, podemos fazer isso na configuração, alterando-a imediatamente para todos, nos bancos de dados suportados. Ou altere apenas para um modelo específico (com tudo isso, não removemos nenhum método do construtor de consultas, porque você não pode se livrar dos métodos da classe base) e deparamos com vários erros prováveis no código ou, Deus o livre, se alguém o tiver suportará (e isso acontece o tempo todo).
Terceiro. Eu quero testar minhas entidades. Quero condenar a certeza de que as alterações que eu fizer não quebrarão minha lógica de negócios. E, como mostra a prática, no caso da AR, você não pode fazer isso, porque o princípio diabólico da responsabilidade única é violado! Embora aqui eu esteja um pouco falso. Testar modelos é possível, apenas ... Um pouco complicado.
No entanto, é impossível não dizer sobre as vantagens desse padrão. Embora toda a sua vantagem seja "rápida, simples, sem hesitação". Ao mesclar dois padrões que são próximos da lógica de suas ações e são constantemente usados juntos, obtemos uma ferramenta conveniente que reduz um pouco a quantidade de código (na direção da complexidade, lembramos do "código burro"?). Ele também permite que você se livre de problemas desnecessários no estágio de formação do MVP, o que é obrigatório (a prática mostra que isso raramente acontece, mas ainda assim) que está planejado reescrever. Isso permite que você mude os pensamentos da pergunta "como fazemos" para a pergunta "o que fazemos", ou seja, elimine questões desnecessárias sobre tecnologias e passe para a lógica de negócios.
A que conclusão cheguei ao longo dos anos usando o ORM do Laravel Eloquent? Registro ativo mal na carne? Não, essa é a ferramenta mais legal para algumas situações, especialmente para o estágio em que você está escrevendo um aplicativo simples ou um protótipo desse aplicativo. Mas isso é algo impossível de funcionar quando seu aplicativo cresce e você precisa trabalhar com um grande número de fontes de dados, escrever código com 100% de cobertura de teste e iniciar grandes problemas.
Sim, novos chips estão sendo inventados ( Trucker ?), Mas vamos fazer truques. Mas ainda quero um pouco mais de liberdade da estrutura, especialmente porque é tão bom para muitos!