Taverna /dev/All

AOP - aquele poderoso desconhecido?

image

AOP (Aspect Oriented Programming) quando se popularizou com o AspectJ, e depois com o Spring era visto como o próximo paradigma de programação, a cura pra todos os males, a coisa mais bonita do universo.

Pra quem não conhece, AOP consiste em uma técnica (alguns dizem que é até um paradigma de programação) no qual essencialmente você trabalha com a interceptação de eventos em seu código fonte.

Por exemplo, você quer colocar um log em todos os controladores do seu sistema para saber quanto tempo levam para executar. Uma alternativa, a mais ingênua, seria fazer algo como isto:

def controlador {
   def tempoInicial = getTempoInicial()
   // faz todo o trabalho duro
  def tempoFinal = getTempoInicial() - tempoInicial
  logaTempoTotal(tempoFinal)
}

E aí repetiria este código em todos os seus controladores, todas as suas actions, todos os pontos do universo que quisesse medir o tempo de execução. Com a AOP você implementa o que chamamos de aspecto, isto é, a lógica que você quer compartilhar (a medição do tempo, que mencionei agora, por exemplo) e simplesmente configura os pontos nos quais este código será executado.

Este código é literalmente um interceptador: você diz quando começa a sua execução, o que ele irá envolver, e quando irá terminar. Frameworks de segurança, como o Spring Security, por exemplo, fazem essencialmente isto.

Minha experiência é mais com Java, mas em outras plataformas o mesmo conceito se aplicou. Em nosso caso ele apareceu com maior evidência em dois momentos: AspectJ (https://www.eclipse.org/aspectj/), que a partir do momento de compilação você define aonde os aspectos vão ser inseridos no seu sistema e o Spring (https://spring.io), que tinha uma abordagem na minha opinião bem mais interessante por ser bem menos evasiva.

E, claro, tem também o Groovy, que na própria linguagem, por ser dinâmica, já te permite fazer isto usando os recursos que lhe são naturais (e o que mostra o próprio poder da linguagem). Se não me engano, neste vídeo eu mostro isto: https://www.youtube.com/watch?v=AQBxfYBifAk

Mas apesar de algo tão poderoso, AOP acabou meio que caindo no esquecimento. Não houve uma adoção em massa da técnica. Eu consigo ver duas razões:

  • Descrevê-lo é muito difícil - quando fui escrever meu livro sobre Spring, por exemplo (Vire o Jogo com Spring Framework) o capítulo mais difícil foi justamente sobre AOP.
  • É um perigo para a manutenção: como o código não está visível, se você se esquecer que o aspecto existe, pesadelos de manutenção irão ocorrer.

Então trago a discussão aqui: qual a sua experiência com a AOP? Por que você acha que não foi adotado em massa?

No início da década 2010 participei de um projeto Java grande que usava AOP amplamente para promover aspectos de segurança, logging, monitoração, profiling, e vários outros controles transversais. Além dos “riscos” que você mencionou, lembro de uma grande fragilidade: dependiamos de um Eclipse bem configurado com o plugin do AspectJ para conseguir trabalhar no projeto levando em conta os aspectos, principalmente o hot deploy. Tinha ainda a necessidade do plugin do Maven. Isso tudo vivia falhando. Creio deva ter evoluído. Mas um tempo valioso foi perdido em torno dessa putaria.

Daí eu me lembro bem de quando saímos do Java EE 5 para o 6 e daí podíamos usar os próprios interceptadores nativos do CDI para resolver praticamente as mesmas questões, e de uma forma mais natural e simples de escrever, criando e usando anotações para qualificar classes e métodos.

De uma certa forma as bibliotecas e frameworks foram evoluindo para cuidar da maioria desses aspectos recorrentes e oferecer uma forma amigável de uso. Talvez por isso o assunto tenha morrido.

Acho que para a maioria dos usos da AOP os filtros/middlewares/whatever que tratam requisições nos frameworks web cumprem a tarefa… Aí acaba que as pessoas não vão atrás de aprender (me incluo :joy:).

1 Curtida

Acredito que AOP virou uma técnica “escondida” pelos frameworks e especificações. Já utilizei em projetos antigos para fazer log de operações de usuário, veio o Java EE 6 com interceptadores e matou mais da metade do que escrevi.

Acredito que se tornou uma tecnologia que usamos sem saber, por justamente consumirmos muitos frameworks, e é subutilizada.

Citando algumas experiências: já tive a ideia de utilizar para checar em tempo de compilação métricas do código, mas ai veio os plugins como sonarlint e perdeu o sentido. Outra vez foi o de nomear as regras de negócio e controlar a execução por uma linguagem ubíqua, mas ficou muito grande e pra cada domínio tinha que reclassificar os termos e por isso foi esquecido. Parei de explorar justamente por esquecimento também.

1 Curtida

O que não me agrada em AOP é que fica tudo muito implícito. Isso algum momento acaba mal, seja impactando a performance, complexidade de código, efeitos indesejados, etc.

Prefiro a regra do “explícito é melhor do que implícito”, mesmo que sacrifique a “beleza” do código. Podemos pegar exemplos de outras coisas relacionado a isso também, vejam sobre implicits em Scala, é uma situação similar. Eu costumo correr desse tipo de coisa como o diabo corre da cruz.

1 Curtida

itexto