Programação Orientada a Aspectos
Carolina Dias Fonseca
Posted on October 7, 2021
Dando sequência aos meus estudos sobre Micronaut, dei de cara com mais um conceito que não conhecia muito e resolvi pesquisar mais sobre.
Dessa vez, me refiro à Programação Orientada a Aspectos que, para a surpresa de ninguém, o Spring também trabalha com ela (se você quiser).
A Programação Orientada a Aspectos (ou Aspects Oriented Programming - AOP) foi um estudo desenvolvido por: Gregor Kiczales, John Lamping, Anurag Mendhekar, Chris Maeda, Cristina Videira Lopes,Jean-Marc Loingtier, John Irwin em 1997.
Esse estudo teve por objetivo melhorar alguns pontos complexos no desenvolvimento de código que nem o paradigma procedural e nem a orientação a objetos conseguiam resolver. Os autores apontam que exatamente esses pontos complexos são os aspectos do design de código que, novamente, a OOP não consegue resolver por mais que ela busque representar o mundo real.
Por conta disso, os autores apresentam uma nova técnica de programação chamada orientada a aspectos, onde é possível usar isolamento de forma apropriada, reutilizar código e composição tudo baseado no aspecto do código. O que eu acredito ser bem relevante sobre o artigo dessa galera é que, em momento algum, eles não falam que OOP, Programação Procedural ou até mesmo a Programação Funcional são ruins, mas sim que a AOP é uma forma de complementar essas programações em pontos que geralmente deixam o desenvolvimento com um código complexo de ser desenvolvido e, posteriormente, dar manutenção.
Ok, mas o que exatamente é um aspecto na programação?
Enquanto um componente tende a ser uma unidade do sistema como, por exemplo, uma imagem, conta bancária, etc. Aspectos são propriedades que afetam a performance e a semântica dos componentes de forma sistemática, por exemplo, padrão de acesso e sincronização de objetos concorrentes, conforme imagem abaixo:
Fonte: Aspect-Oriented Programming traduzido por: Carolina Fonseca
Para facilitar mais na explicação, os autores usam erros e falhas como base, pois sabemos que são os pontos mais comuns no dia a dia como desenvolvedores, afinal, sempre teremos que customizar/adicionar algum handle quer seja para captar qualquer tipo de erro que dê na aplicação ou lidar com erros/falhas específicas.
"Many performance-related issues are aspects, because performance optimizations often exploit information about the execution context that spans components."
Muitos problemas relacionados a performance, são aspectos. Porque a otimização de performance sempre explora a informação sobre o contexto de execução onde os componentes estão.
Mão no código
Vamos ver um exemplo prático usando Java como base, no caso, vamos utilizar a Biblioteca Digital sugerida na imagem anterior:
public class Livro {
String título, autor;
int isbn;
public String getTitulo(){
return título;
}
public String getAutor(){
return autor;
}
public int getIsbn() {
return isbn;
}
}
public class Repository {
private Livro livros[];
private int nlivros = 0;
public Repository (int dbsize) {
livros = new Livro[dbsize];
}
public void registrar (Livro liv) {
livros [nlivros++] = liv;
}
public void retirar (Livro liv) {
...
}
}
Os autores destacam que programas como o acima, onde precisam gerenciar todas as instâncias criadas de suas classes e as chamadas de métodos, não são capazes de fazer esse gerenciamento todo sozinho, afinal, estamos falando de uma estrutura cujo foco é a abstração que queremos fazer do sistema real e não como ele vai gerenciar todas as sua chamadas.
O mais indicado seria o uso de reflection para acessar essa comunicação de forma distribuída, porém, criar reflection no nível de detalhe que a OOP precisa, acaba se tornando algo muito complexo.
É aqui onde temos uma oportunidade real de se utilizar a AOP:
remote Repository {
void registrar (Livro);
void retirar (Livro: copy isbn);
Livro: copy isbn busca(String);}
Acima temos um trecho de código com foco no aspecto da comunicação. Basicamente, ele comunica ao Repository que quando novos livros são registrados, ele deve criar uma cópia daquele objeto e quando o livro é retirado ele deve copiar somente o número de isbn, o restante do livro não é copiado a menos que seja preciso mais tarde.
O Join e as reflections
Em AOP, temos um conceito chamado Join que nada mais é do que o momento em que unimos o nosso componente ao seu aspecto, uma vez que, em inglês, join significar unir, esse conceito faz total sentido.
E ela faz mais sentido ainda quando falamos de reflection e metaobjetos, porque um sistema reflexivo disponibiliza a base da semântica e implementação da linguagem que estamos utilizando. Falando da metalinguagem, temos acesso à todas as chamadas de funções e stack de execução que, a nível humano, nunca conseguimos ver. Vendo por esse ângulo, é no baixo nível onde é possível aplicarmos os joins da AOP de forma que a reflection faça todo o restante do trabalho, dessa forma, temos os nossos aspectos criados para fins de controle das instâncias e vinculados ao reflection que nem precisamos criar já que utilizamos da própria linguagem para tal.
Conclusão
Admito que enquanto lia o artigo que "criou" o AOP, não esperava encontrar o uso de reflections nele, mas passou a se fazer muito sentido de quando comparamos o uso delas no Spring e no Micronaut.
O Spring já faz as reflections todas de uma vez, ou seja, já vamos fazendo o mapeamento de aspectos no tempo de compilação, ao passo que o Micronaut também faz esse gerenciamento de aspectos, porém somente do que realmente está sendo utilizado na aplicação mas em tempo de pré-compilação, mas falarei mais sobre isso nos próximos artigos ;)
Espero que tenha gostado e se acha que faltou algo ou escrevi algo sem sentido, me chama para conversamos!
Fonte: https://www.cs.ubc.ca/~gregor/papers/kiczales-ECOOP1997-AOP.pdf
Posted on October 7, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.