A Op

  • May 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View A Op as PDF for free.

More details

  • Words: 2,551
  • Pages: 43
Ricardo Terra [email protected]

Ricardo Terra Bacharel em Ciência da Computação – FUMEC Pós-graduado em Análise de Sistemas – UFMG Mestre em Informática – PUC Minas Doutorando em Ciência da Computação – UFMG Especializado em Java SCJP SCWCD Professor FUMEC FAMINAS-BH UNIPAC-CONTAGEM Aspect-Oriented Programming

2

Nomenclaturas Quaisquer das nomenclaturas abaixo é valida: AOP Aspect-Oriented Programming POA Programação Orientada a Aspectos (tradução) AOSD Aspect-Oriented Software Development Já familiarizados com a variedade de termos para AOP, vamos simplesmente falar AOP

Aspect-Oriented Programming

3

Introdução Paradigmas de Programação: Programação Estruturada Programação Orientada a Objetos (OOP) Programação Orientada a Aspectos (AOP)

Boas perguntas a serem realizadas: A OOP substitui a programação estruturada? Então a AOP veio para substituir a OOP?

Aspect-Oriented Programming

4

OOP vs AOP? OOP Paradigma dominante de programação Unidade básica de modularização: classes Desenvolvimento orientado a objetos: Decomposição dos sistemas em classes Classes implementam interesses (concerns) do sistema

Aspect-Oriented Programming

5

OOP vs AOP? Na ECOOP 1997, Gregor Kiczaler, propôs a AOP no artigo Aspect-Oriented Programming "We have found many programming problems for which neither procedural nor object-oriented programming techniques are sufficient to clearly capture some of the important design decisions the program must implement. This forces the implementation of those design decisions to be scattered throughout the code, resulting in tangled code that is excessively difficult to develop and maintain." Principal objetivo da AOP: Separation of Concerns (separação de interesses, requisitos, funcionalidades…) ECOOP - European Conference on Object-Oriented Programming

Aspect-Oriented Programming

6

OOP vs AOP? “O paradigma de orientação a objetos tem se consolidado como o principal paradigma para o desenvolvimento de sistemas de software. Entretanto, as abstrações e os mecanismos de composição desse paradigma possuem limitações para separar e compor alguns interesses relevantes em um sistema de software.” “Assim, muitas propriedades importantes espalham-se por vários módulos e misturam-se com outras propriedades de um sistema de maneira intrusiva, dificultando a reutilização e manutenção de seus componentes.” “A POA propõe um novo tipo de abstração - denominado aspecto e novos mecanismos de composição que permitem a descrição modular e a composição de interesses que geralmente se encontram espalhados e misturados (crosscutting concerns) em vários pontos de um sistema de software tradicional.” Aspect-Oriented Programming

7

OOP e AOP! Respondendo a pergunta: AOP não veio para substituir OOP AOP trabalha em conjunto com a OOP Uma linguagem orientada por aspectos permite confinar interesses transversais (crosscutting concerns) em módulos Em AOP, tais módulos são chamados de aspectos

Boa pergunta a ser realizada: O que são interesses transversais (crosscutting concerns)?

Aspect-Oriented Programming

8

Interesses transversais São requisitos que não são facilmente implementados em uma ou em poucas classes do sistema Pode-se dizer que estes requisitos "pertencem" a todo o sistema Exemplos: Logging Autenticação Controle de acesso Controle de transações Persistência Não é comum, mas requisitos funcionais também podem apresentar um comportamento transversal

Aspect-Oriented Programming

9

Interesses transversais Principais problemas com requisitos transversais: Código espalhado (code spreading/scattered) Interesse transversal espalhado em diversas classes Código entrelaçado (code tangling) Interesse transversal entrelaçado com código de negócio

Aspect-Oriented Programming

10

Código do Apache Tomcat Para explicar na prática o que vem a ser um requisito transversal ou não-transversal, vamos fazer análise sobre o código fonte do Apache Tomcat

Aspect-Oriented Programming

11

Código do Apache Tomcat Requisito não-transversal Parsing de documento HTML

Aspect-Oriented Programming

12

Código do Apache Tomcat Requisito transversal (exemplo tradicional) Logging

Código espalhado (scattered) e entrelaçado (tangled) Aspect-Oriented Programming

13

OOP vs AOP?

Implementação OOP de logging

Implementação AOP de logging

Boa pergunta a ser realizada: Qual das implementações acima está mais fácil de ser desenvolvida e de ser mantida? Aspect-Oriented Programming

14

Utilizando AOP Identificar e caracterizar os requisitos Implementar requisitos não-transversais utilizando CLASSES Implementar requisitos transversais utilizando ASPECTOS Aspecto é uma unidade de modularização Aspectos são desenvolvidos de forma isolada Os módulos influenciados não necessitam de modificações São combinados com os outros módulos usando mecanismos declarativos ou programáticos Boa pergunta a ser realizada: Vamos supor que eu implemente alguns aspectos. Como é feita a sua combinação com os outros módulos de minha aplicação?

Aspect-Oriented Programming

15

Interseção Processo de interseção, conhecido como WEAVING Ele é o responsável por “injetar” os aspectos, ou melhor, é a ferramenta que combina código OO e código OA para a geração do sistema final É um processo relativamente lento

Aspect-Oriented Programming

16

Conceitos básicos Joinpoints (pontos de junção) São pontos da execução do programa: chamadas e execuções de métodos ou construtores retorno de métodos ou construtores lançamento ou tratamento de exceções alteração de campos de classe Pointcuts (coleção de pontos de junção) Exemplos: Todas as execuções de métodos públicos Toda criação de objetos da classe Point Toda chamada do método Point.setX ou Point.setY Toda alteração do campo x da classe Point Aspect-Oriented Programming

17

Conceitos básicos Advices Código que deve executar no momento de qualquer joinpoint de um pointcut Exemplos: chamar um método de log antes de toda chamada a método público do programa abrir conexão antes de executar métodos de persistência fechar conexão depois de executar métodos de persistência chamar um método de atualização depois que qualquer atributo de uma figura geométrica for alterado executar um outro método ao invés de executar o método Aspectos Coleção de pointcuts e advices Aspect-Oriented Programming

18

Prática Linguagens que permitem implementação AOP: Java AspectJ (a que será abordada) HyperJ Spring AOP C e C++ AspectC e AspectC++, respectivamente Aplicações de destaque que utiliza AOP: FreeBSD (reestruturação do kernel) JBoss AOP Implementação de sistemas distribuídos

Aspect-Oriented Programming

19

Prática AspectJ Extensão orientada a aspectos para Java Declarações de aspectos são similares a declarações de classes (como veremos nos exemplos a frente) Em um aspecto podem ser declarados: Pointcuts (conjuntos de junção) Advices

Aspect-Oriented Programming

20

Prática Com a teoria já absorvida podemos ir um pouco além e mostrar alguns exemplos Os exemplos a seguir foram feitos utilizando: Eclipse IDE for Java Developers (Ganymede) http://www.eclipse.org AJDT: AspectJ Development Tools 1.6.4 http://www.eclipse.org/ajdt

Aspect-Oriented Programming

21

Prática 01 Observe as classes abaixo: public class Point { private int x, y; public public public public

public class Line { private Point p1, p2;

int getX() {..} void setX(int x) {..} int getY() {..} void setY(int y) {..}

public public public public

public void draw(Graphics g){..} public void refresh(){ this.draw(Canvas.getGraphics(this)); } }

Point getP1() {..} void setP1(Point p1) {..} Point getP2() {..} void setP2(Point p2) {..}

public void draw(Graphics g){..} public void refresh(){ this.draw(Canvas.getGraphics(this)); } }

Boa pergunta a ser realizada: O que há de errado com o código acima? Aspect-Oriented Programming

22

Prática 01 Métodos comuns public class Point { private int x, y; public public public public

public class Line { private Point p1, p2;

int getX() {..} void setX(int x) {..} int getY() {..} void setY(int y) {..}

public public public public

public void draw(Graphics g){..} public void refresh(){ this.draw(Canvas.getGraphics(this)); } }

Point getP1() {..} void setP1(Point p1) {..} Point getP2() {..} void setP2(Point p2) {..}

public void draw(Graphics g){..} public void refresh(){ this.draw(Canvas.getGraphics(this)); } }

Aspect-Oriented Programming

23

Prática 01 Solução: uso de herança como mecanismo de reuso

public abstract class Figure { public abstract void draw(Graphics g); public void refresh(){ this.draw(Canvas.getGraphics(this)); } }

public class Point extends Figure { private int x,y; public public public public

public class Line extends Figure { private Point p1,p2;

int getX() {..} void setX(int x) {..} int getY() {..} void setY(int y) {..}

public public public public

public void draw(Graphics g){..} }

Point getP1() {..} void setP1(Point p1) {..} Point getP2() {..} void setP2(Point p2) {..}

public void draw(Graphics g){..} }

Aspect-Oriented Programming

24

Prática 01 Observe as classes abaixo: public class Point extends Figure { ... public void setX(int x) { this.x = x; this.refresh(); } public void setY(int y) { this.y = y; this.refresh(); } ... }

public class Line extends Figure { ... public void setP1(Point p1) { this.p1=p1; this.refresh(); } public void setP2(Point p2) { this.p2=p2; this.refresh(); } ... }

Boa pergunta a ser realizada: O que há de errado com o código acima? Aspect-Oriented Programming

25

Prática 01 Chamada a um mesmo método no final de todos setters public class Point extends Figure { ... public void setX(int x) { this.x = x; this.refresh(); } public void setY(int y) { this.y = y; this.refresh(); } ... }

public class Line extends Figure { ... public void setP1(Point p1) { this.p1=p1; this.refresh(); } public void setP2(Point p2) { this.p2=p2; this.refresh(); } ... }

Aspect-Oriented Programming

26

Prática 01 Solução: uso de aspecto public aspect RefreshingAspect { pointcut setterMethods(): execution(public void Figure+.set*(..)); after(Figure f): setterMethods() && this(f) { f.refresh(); } } public class Point extends Figure { ... public void setX(int x) { this.x = x; } public void setY(int y) { this.y = y; } ... }

public class Line extends Figure { ... public void setP1(Point p1) { this.p1=p1; } public void setP2(Point p2) { this.p2=p2; } ... }

Aspect-Oriented Programming

27

Prática 02 Observe a classe abaixo: public class Concerns { public void doSomething(int value){ Logger.logEntry("doSomething(" + value + ")"); ... Logger.logExit("doSomething"); } public void doAnotherThing(char a, double b){ Logger.logEntry("doAnotherThing(" + a + "," + b + ")"); ... Logger.logExit("doAnotherThing"); } }

Boa pergunta a ser realizada: O que há de errado com o código acima? Aspect-Oriented Programming

28

Prática 02 Implementação OOP de um requisito transversal public class Concerns { public void doSomething(int value){ Logger.logEntry("doSomething(" + value + ")"); ... Logger.logExit("doSomething"); } public void doAnotherThing(char a, double b){ Logger.logEntry("doAnotherThing(" + a + "," + b + ")"); ... Logger.logExit("doAnotherThing"); } }

Aspect-Oriented Programming

29

Prática 02 Solução: uso de aspecto public aspect LoggingAspect { pointcut publicMethods() : execution(public * *(..)); pointcut logObjectMethods() : execution(* Logger.*(..)); pointcut loggableCalls(): publicMethods() && !logObjectMethods(); before() : loggableCalls() { Logger.logEntry(thisJoinPoint.getSignature().toString()); } after() : loggableCalls() { Logger.logExit(thisJoinPoint.getSignature().toString()); } }

Aspect-Oriented Programming

30

Prática 02 Assim, o desenvolvedor não precisa dar atenção a requisito de logging public class Concerns { public void doSomething(int value){ ... } public void doAnotherThing(char a, double b){ ... } }

Aspect-Oriented Programming

31

Prática 02 Demostração da criação de todo um projeto orientado a aspectos

Aspect-Oriented Programming

32

Prática 03 Observe uma das classes de persistência do sistema: public class UsuarioDAO implements IDataAccessObject{ ... public void add(Usuario usuario) throws SQLException{ Connection conn = null; try { conn = ConnectionLocator.getConnection(); //Abre a conexão PreparedStatement st = conn.prepareStatement("insert into USUARIO values (?,?,?)"); st.setString(1, usuario.getLogin()); st.setString(2, usuario.getSenha()); st.setString(3, usuario.getNome()); st.execute(); st.close(); conn.commit(); //Realiza commit } catch (SQLException e) { if (conn!=null){ conn.rollback(); //Realiza rollback } throw e; }finally{ if (conn!=null){ conn.close(); //Fecha a conexão } } } ... }//Fim da Classe

Boa pergunta a ser realizada: O que há de errado com o código acima? Aspect-Oriented Programming

33

public class UsuarioDAO implements IDataAccessObject{ ... public void add(Usuario usuario) throws SQLException{ Connection conn = null; try { conn = ConnectionLocator.getConnection(); //Abre a conexão Observe uma das classes de persistência do sistema: PreparedStatement = public class UsuarioDAOstimplements IDataAccessObject{ ... conn.prepareStatement("insert into USUARIO values (?,?,?)"); public void add(Usuario usuario) throws SQLException{ Connection conn = null; st.setString(1, usuario.getLogin()); try { st.setString(2, usuario.getSenha()); conn = ConnectionLocator.getConnection(); //Abre a conexão PreparedStatement st = st.setString(3,conn.prepareStatement("insert usuario.getNome()); into USUARIO values (?,?,?)"); st.setString(1, usuario.getLogin()); st.execute(); st.setString(2, usuario.getSenha()); st.setString(3, usuario.getNome()); st.close(); st.execute(); conn.commit(); //Realiza commit st.close(); conn.commit(); //Realiza commit } catch }(SQLException e) { catch (SQLException e) { if (conn!=null){ if (conn!=null){ conn.rollback(); //Realiza rollback conn.rollback(); //Realiza rollback } throw e; } }finally{ throw e;if (conn!=null){ conn.close(); //Fecha a conexão }finally{ } } if }(conn!=null){ ... conn.close(); //Fecha a conexão }//Fim da Classe } Boa pergunta a ser realizada: } O que há de errado com o código acima? } ... Aspect-Oriented Programming 34 }//Fim da Classe

Prática 03

public class UsuarioDAO implements IDataAccessObject{ ... public void add(Usuario usuario) throws SQLException{ Connection conn = null; try { conn = ConnectionLocator.getConnection(); //Abre a conexão Observe uma das classes de persistência do sistema: PreparedStatement = public class UsuarioDAOstimplements IDataAccessObject{ ... conn.prepareStatement("insert into USUARIO values (?,?,?)"); public void add(Usuario usuario) throws SQLException{ Connection conn = null; st.setString(1, usuario.getLogin()); try { st.setString(2, usuario.getSenha()); conn = ConnectionLocator.getConnection(); //Abre a conexão PreparedStatement st = st.setString(3,conn.prepareStatement("insert usuario.getNome()); into USUARIO values (?,?,?)"); st.setString(1, usuario.getLogin()); st.execute(); st.setString(2, usuario.getSenha()); st.setString(3, usuario.getNome()); st.close(); st.execute(); conn.commit(); //Realiza commit st.close(); conn.commit(); //Realiza commit } catch }(SQLException e) { catch (SQLException e) { if (conn!=null){ if (conn!=null){ conn.rollback(); //Realiza rollback conn.rollback(); //Realiza rollback } throw e; } }finally{ throw e;if (conn!=null){ conn.close(); //Fecha a conexão }finally{ } } if }(conn!=null){ ... conn.close(); //Fecha a conexão }//Fim da Classe } Boa pergunta a ser realizada: } O que há de errado com o código acima? } ... Aspect-Oriented Programming 35 }//Fim da Classe

Prática 03

Prática 03 Implementação OOP de controle transacional public class UsuarioDAO implements IDataAccessObject{ ... public void add(Usuario usuario) throws SQLException{ Connection conn = null; try { conn = ConnectionLocator.getConnection(); //Abre a conexão PreparedStatement st = conn.prepareStatement("insert into USUARIO values (?,?,?)"); st.setString(1, usuario.getLogin()); st.setString(2, usuario.getSenha()); st.setString(3, usuario.getNome()); st.execute(); st.close(); conn.commit(); //Realiza commit } catch (SQLException e) { if (conn!=null){ conn.rollback(); //Realiza rollback } throw e; }finally{ if (conn!=null){ conn.close(); //Fecha a conexão } } } ... }//Fim da Classe

Aspect-Oriented Programming

36

Prática 03 Esta implementação faz com o código do controle transacional esteja espalhado e entrelaçado em todos os métodos dos DAOs O ideal seria que, na chamada de qualquer método transacional, fosse automaticamente feito: Abertura de conexão Realização do commit da transação Encerramento da conexão Tratamento de eventuais exceções que possam vir a ocorrer

Aspect-Oriented Programming

37

Prática 03 Solução: uso de aspecto public aspect PersistenceAspect percflow(topLevelTransactedMethods()) { public Connection com.terra.dao.IDataAccessObject._connection; pointcut transactedMethods() : execution(* com.terra.dao.IDataAccessObject+.*(..)); pointcut topLevelTransactedMethods(): transactedMethods() && !cflowbelow(transactedMethods()); Object around(IDataAccessObject dao) throws SQLException : topLevelTransactedMethods() && target(dao){ Object operationResult = null; try{ dao._connection = ConnectionLocator.getConnection(); operationResult = proceed(dao); if (dao._connection!=null){ dao._connection.commit(); } }catch(SQLException e){ if (dao._connection!=null){ dao._connection.rollback(); } throw e; }finally{ if (dao._connection!=null){ dao._connection.close(); } } return operationResult; } } // Fim do Aspecto Aspect-Oriented Programming

38

public aspect PersistenceAspect percflow(topLevelTransactedMethods()) {

Prática 03

public Connection com.terra.dao.IDataAccessObject._connection; pointcut transactedMethods() : execution(* com.terra.dao.IDataAccessObject+.*(..)); pointcut topLevelTransactedMethods(): transactedMethods() && !cflowbelow(transactedMethods()); Object around(IDataAccessObject dao) throws SQLException : topLevelTransactedMethods() && target(dao){ Object operationResult = null; try{ dao._connection = ConnectionLocator.getConnection(); operationResult = proceed(dao); if (dao._connection!=null){ dao._connection.commit(); } }catch(SQLException e){ if (dao._connection!=null){ dao._connection.rollback(); } throw e; }finally{ if (dao._connection!=null){ dao._connection.close(); } } return operationResult; } Aspect-Oriented Programming

} // Fim do Aspecto

39

Prática 03 Assim, o desenvolvedor não precisa dar atenção ao controle transacional nos métodos de persistência public class UsuarioDAO implements IDataAccessObject{ public void add(Usuario usuario) throws SQLException{ PreparedStatement st = _connection.prepareStatement("insert into USUARIO values (?,?,?)"); st.setString(1, usuario.getLogin()); st.setString(2, usuario.getSenha()); st.setString(3, usuario.getNome()); st.execute(); st.close(); } }//Fim da Classe

Aspect-Oriented Programming

40

Considerações finais Desenvolver uma solução utilizando aspecto é um pouco trabalhoso, mas é realizada apenas uma única vez AOP é poderoso, entretanto pode ser perigoso AOP quebra o raciocínio modular Nada impede, mas o AOP não deve ser usado para qualquer interesse, mas sim, para os interesses transversais Melhora o nível de modularização do sistema, com baixo acoplamento e alta coesão O processo de weaver demora A sintaxe do AspectJ não é das melhores Desenvolver utilizando AOP é incrível! Aspect-Oriented Programming

41

Dúvidas?

Aspect-Oriented Programming

42

Obrigado! Ricardo Terra [email protected] Apresentação e vídeo disponíveis em: www.ricardoterra.com.br/pucsg Principais referências bibliográficas: KICZALES, Gregor et al. Aspect-Oriented Programming. ECOOP, 1997. TIRELO, Fábio et al. Desenvolvimento de Software Orientado por Aspectos. XXIII JAI, 2004. VALENTE, M. T. Programação Orientada por Aspectos. Programa de Pós-graduação em Informática PUC Minas, 2006.

Aspect-Oriented Programming

43

Related Documents

A Op
May 2020 7
Home Op A Ti A
May 2020 13
Est Op A
April 2020 8
Spring A Op
November 2019 7
Op Am A
May 2020 27
Op A 2227
November 2019 12