Programação Orientada a
Objetos
Desenvolvimento de Software
Orientado a Aspectos
Lida com conceitos mais intuitivos
Permite ganhos
„
„
• Reuso
• Manutenção
• Adaptação
Sérgio Soares
[email protected]
Padrões de projetos
„
• Auxiliam a POO
Sérgio Castelo Branco Soares
ESCOLA POLITÉCNICA
1
DE PERNAMBUCO
Exemplo:
Sistema Disque Saúde
„
Exemplo:
Sistema Disque Saúde
Um sistema de informação
Implementado em Java
„
• Registra e encaminha queixas para o sistema de
saúde
• Exibe informações sobre unidades de saúde e
suas especialidades
„
• Servlets implementam a GUI
• Utiliza vários padrões de projetos para
contemplar requisitos não-funcionais
Requisitos não-funcionais
• Distribuído
• Acesso concorrente
• Extensível
Como implementar a distribuição no
sistema?
„
—Armazenamento de dados
—Tecnologia de distribuição
Sérgio Castelo Branco Soares
2
Sérgio Castelo Branco Soares
3
4
Sérgio Castelo Branco Soares
Disque Saúde distribuído com
RMI
Disque Saúde local
public class Complaint implements java.io.Serializable {
public class HealthWatcherFacade implements IFacade {
private String description;
public class ServletUpdateComplaintData extends HttpServlet {
public void update(Complaint complaint)
private Person complainer; ...
private IFacade facade;
throws TransactionException, RepositoryException,
public Complaint(String description, Person complainer,
...) {
public void init(ServletConfig config) throws ServletException {
ObjectNotFoundException, ObjectNotValidException {
try {
...
...
facade = (IFacade) java.rmi.Naming.lookup("//HealthWatcher");
}
}
}
public static void main(String[] args) {
public String getDescription() {
catch (java.rmi.RemoteException rmiEx) {...}
try {
return this.description;
catch (java.rmi.NotBoundException rmiEx) {...}
HealthWatcherFacade facade = HealthWatcherFacade.getInstance();
}
catch (java.net.MalformedURLException rmiEx) {...}
System.out.println("Creating RMI server...");
public Person getComplainer() {
}
UnicastRemoteObject.exportObject(facade);
return this.complainer;
java.rmi.Naming.rebind("/HealthWatcher");
}
System.out.println("Server created and ready.");
public void setDescription(String desc) {
public void doPost(HttpServletRequest request, HttpServletResponse response)
}
this.description = desc;
throws ServletException, IOException {
catch (RemoteException rmiEx) {... }
}
...
catch (MalformedURLException rmiEx) { ...}
public void setComplainer(Person complainer) {
} ...
facade.update(complaint);
catch(Exception ex) {... }
this.complainer = complainer;
...
}
} ...
}
}
}
public class Person implements java.io.Serializable {
public interface IFacade extends java.rmi.Remote {
private String nome; ...
public Person(String nome, …) {
public void updateComplaint complaint)
this.nome = nome; …
throws TransactionException, RepositoryException,
}
ObjectNotFoundException, ObjectNotValidException,
public String getNome() {
RemoteException;
return nome;
}…
...
}
}
Código RMI é vermelho…
Sérgio Castelo Branco Soares
5
Sérgio Castelo Branco Soares
6
1
AOP — Aspect-oriented
programming
Implementação OO: problemas!
„
Tangled code (código entrelaçado)
„
• código de distribuição misturado com
código de negócio e de GUI
„
• distribuição, gerenciamento de dados,
controle de concorrência, tratamento de
exceções, logging, debugging, …
Spread code (código espalhado)
• código de distribuição em várias classes
„
„
Distribuição é um crosscutting
concern (interesse transversal)
Difícil de manter e reusar
• mudanças no protocolo de distribuirão
(RMI, CORBA, EJB ) são invasivas
Sérgio Castelo Branco Soares
Melhora a modularidade de interesses
transversais
„
Auxilia separação de interesses
(separation of concerns)
• aumenta extensibilidade e reuso
7
Disque Saúde distribuído com
AOP (usando Java RMI)
8
Sérgio Castelo Branco Soares
Disque Saúde distribuído com
AOP
public class Complaint {
private String description;
private Person complainer; ...
public class ServletUpdateComplaintData extends HttpServlet {
public Complaint(String description, Person complainer,
...) {
aspect DistributionAspect {
private HealthWatcherFacade facade;
declare parents: HealthWatcherFacade implements IFacade;
public void init(ServletConfig config) throws ServletException {
declare parents: Complaint || Person implements java.io.Serializable;
...
try {
}
public static void HealthWatcherFacade.main(String[] args) {
facade = HealthWatcherFacade.getInstance();
public String getDescription() {
try {
}
return this.description;
HealthWatcherFacade facade = HealthWatcherFacade.getInstance();
catch (Exception ex) {...}
}
System.out.println("Creating RMI server...");
}
public Person getComplainer() {
return this.complainer;
UnicastRemoteObject.exportObject(facade);
public void doPost(HttpServletRequest request, HttpServletResponse
response)
}
java.rmi.Naming.rebind("/HealthWatcher");
System.out.println("Server created and ready.");
throws ServletException, IOException {
public void setDescription(String desc) {
this.description = desc;
}
} catch (RemoteException rmiEx) {...}
...
catch (MalformedURLException rmiEx) {...}
} ...
catch(Exception ex) {...}
}
}
public void setComplainer(Person complainer) {
this.complainer = complainer;
}
}
public class Person {
private String nome; ...
public Person(String nome, ...) {
this.matricula = matricula; ...
}
public String getNome() {
return nome;
private IFacade remoteFacade;
Sistema local
pointcut facadeMethodsExecution():
within(HttpServlet+) && execution(* HealthWatcherFacade.*(..)) &&
this(HealthWatcherFacade);
before(): facadeMethodsExecution() { prepareFacade();}
Aspectos de
distribuição com RMI
private synchronized void prepareFacade() {
if (healthWatcher == null) {
try { remoteFacade = (IFacade) java.rmi.Naming.lookup("//HealthWatcher");
} catch (java.rmi.RemoteException rmiEx) {...}
catch (java.rmi.NotBoundException rmiEx) {...}
catch (java.net.MalformedURLException rmiEx) {...}
}
} ...
void around(Complaint complaint) throws TransactionException, RepositoryException
}
ObjectNotFoundException,ObjectNotValidException:
public interface IFacade extends java.rmi.Remote {
facadeRemoteExecutions() && args(complaint) &&
public class HealthWatcherFacade {
try { remoteFacade.update(complaint);
throws TransactionException, RepositoryException,
throws TransactionException, RepositoryException,
} catch (RemoteException rmiEx) {...}
ObjectNotFoundException, ObjectNotValidException,
ObjectNotFoundException,
ObjectNotValidException {
}
RemoteException;
...
...
}
call(void update(Complaint)) {
public void updateComplaint complaint)
public void update(Complaint complaint)
}
}
}
Sérgio Castelo Branco Soares
9
10
Sérgio Castelo Branco Soares
Implementação com AOP
„
Aumento em modularidade, reuso e
extensibidade
Em direção ao
Desenvolvimento de
Software
• Mais unidades de código
• Mudanças no sistema local podem causar
impacto nos aspectos de distribuição
„
Separation of concerns (separação de
Orientado a Aspectos (DSOA)
interesses)
• Relação entre os aspectos e o resto do
sistema nem sempre é clara
„
Normalmente menos linhas de código
Sérgio Castelo Branco Soares
11
Sérgio Castelo Branco Soares
12
2
Passo 1: Identificando
interesses (decomposição)
Identificador
de interesses
Interesses do Disque Saúde
Interface com o usuário
Interesses
Gerenciamento de dados
Distribuição
Requisitos
Regras de negócio
Controle de concorrência
Engenharia de requisitos
13
Sérgio Castelo Branco Soares
Passo 2: Implementar o sistema,
separando os interesses
„
Alguns concerns são bem modelados
como objetos (núcleo do sistema)
Passo 3: Recompor o sistema
classes e
interfaces
• interface com o usuário
• regras de negócio
„
14
Sérgio Castelo Branco Soares
Outros (crosscutting concerns) como
aspectos
aspects and
tipos auxiliares
W
E
A
V
E
R
Sistema
executável
• distribuição, controle de concorrência,
armazenamento de dados
15
Sérgio Castelo Branco Soares
Desenvolvimento de Software
Orientado a Aspectos
Identificador
de concerns Interesses
OOP
Requisitos
AOP
Classes
Interfaces
Aspects
W
E
A
V
E
R
16
Sérgio Castelo Branco Soares
OOP vs AOP
Sistema
executável
Requisitos funcionais
Controle de concorrência
Requisitos funcionais
Controle de concorrência
Gerenciamento de dados
Distribuição
Interface com o usuário
Gerenciamento de dados
Distribuição
Interface com o usuário
Sérgio Castelo Branco Soares
17
Sérgio Castelo Branco Soares
18
3
Composição nos pontos
junção (join points)
Combinação (weaving) é
usada para …
„
Compor o “núcleo” do sistema com os
aspectos
Sistema original
chamadas locais entre A e B
A
B
Processo de
combinação
Sistema distribuído
chamadas remotas entre A e B
Sérgio Castelo Branco Soares
um método é
chamado
e
retorna ou lança
uma exceção
object B
dispatch
um método executa
e
retorna ou lança
uma exceção
A
B
Protocolo de distribução
19
Comportamento pode
ser alterado nos pontos
de junção…
um método executa
e
retorna ou lança
uma exceção
Fonte: AspectJ Tutorial
20
aspectj.org
Sérgio Castelo Branco Soares
AspectJ: identificando
chamadas de métodos da
fachada (servidor)
Identifica pontos de junção de um sistema
identifica código
dentro da classe ...
• chamadas e execuções de métodos (e
construtores)
• acessos a atributos
• tratamento de exceções
• inicialização estática e dinâmica
„
dispatch
Weaver
Conjunto de pontos de
junção (pointcut)
„
Um método é
chamado
e
retorna ou lança
uma exceção
object A
Aspectos de
distribuição
de
nome do conjunto
de pontos de junção
pointcut facadeMethodsCall():
within(HttpServlet+) &&
Expõe o contexto nos join points
call(* IFacade+.*(..));
—argumentos de métodos, objetos alvo, atributos
„
Composição de pontos de junção
• &&, || e !
Sérgio Castelo Branco Soares
21
Comportamento
transversal (advice)
„
qualquer
método
com quaisquer
argumentos
Sérgio Castelo Branco Soares
22
AspectJ: antes (before) de
chamar métodos da fachada
private IFacade remoteFacade;
Define código adicional que deve ser
executado…
before(): facadeMethodsCall() {
getRemoteInstance();
• before
• after
}
synchronized void getRemoteInstance() {...
—after returning
—after throwing
remoteFacade =
• ou around
(IFacade) java.rmi.Naming.lookup(...);
pontos de junção
Sérgio Castelo Branco Soares
identifica
chamadas de …
...}
23
Sérgio Castelo Branco Soares
24
4
Além de mudanças (dinâmicas)
com comportamento
transversal…
AspectJ: transformando
chamadas locais em remotas
void around(Complaint c) throws Ex1,…:
facadeMethodsCall() && args(c) &&
„
call(void update(Complaint))
{
try { remoteFacade.update(c);
AspectJ suporta mudanças estáticas
• alterar relação de subtipo
• adicionar membros a classes
obtendo e utilizando
argumento de método
em um ponto de junção
} catch (RemoteException rmiEx) {...}
Declarações
intertipos
}
25
Sérgio Castelo Branco Soares
Sérgio Castelo Branco Soares
AspectJ: mudanças estáticas
Mais construtores de AspectJ
declare parents:
HealthWatcherFacade implements IFacade;
„
„
} catch
...
Adicionando o
método main
na classe
fachada
„
27
Sérgio Castelo Branco Soares
cflow(<conjunto de junção>)
• Identifica pontos de junção que estejam no fluxo
de execução identificado por <conjunto de junção>
„
public aspect DistributionAspect {
declare parents: ...
get(<assinatura>) / set(<assinatura>)
private IFacade remoteFacade;
public static void
HealthWatcherFacade.main(String[] as)...
pointcut facadeMethodsCall(): ...
before(): facadeMethodsCall() ...
private synchronized void
getRemoteInstance() ...
void around(Complaint complaint) ...
• Leitura/atribuição a atributos
„
declare soft: <nome do tipo> :
<conjunto de junção>;
• A exceção <nome do tipo> será encapsulada em
uma exceção não checada em tempo de
compilação (runtime) em qualquer ponto de
junção definido por <conjunto de junção>
Sérgio Castelo Branco Soares
28
Aspecto de distribuição em
AspectJ
Mais construtores de AspectJ
„
withincode(<assinatura de método>)
• Identifica pontos de junção cujo código em
execução pertence ao corpo do método ou
construtor especificado por <assinatura de
método>
Alterando a hierarquia de tipos
}
Sérgio Castelo Branco Soares
this(<nome do tipo>)
• Identifica pontos de junção cujo objeto em
execução é uma instância de <nome do tipo>
public static void
HealthWatcherFacade.main(String[] args){
java.rmi.Naming.rebind("/HW");
target(<nome do tipo>)
• Identifica pontos de junção onde o objeto alvo
é uma instância de <nome do tipo>
declare parents: Complaint || Person
implements java.io.Serializable;
try {...
26
}
29
Sérgio Castelo Branco Soares
30
5
Aspectos de desenvolvimento:
debugging simples com AspectJ
AspectJ: pontos positivos
„
public aspect DatabaseDebugging {
pointcut queryExecution(String sql):
call(* Statement.*(String)) &&
„
args(sql);
„
• debugging
before(String sql): queryExecution(sql) {
System.out.println(sql);
„
}
„
}
Sérgio Castelo Branco Soares
31
„
Novo paradigma
Projeto da linguagem
„
• tratamento de exceções
• conflitos entre aspectos
„
„
„
„
Requer suporte de ferramentas
Combinação (apenas) estática
Sérgio Castelo Branco Soares
32
Referências
• relação entre classes e aspectos deve
ser minimizada
• inconsciência (obliviousness)
„
Produtividade
Permite implementação e testes
progressivos
Sérgio Castelo Branco Soares
AspectJ: pontos negativos
„
Modularidade, reuso, e
extensibilidade de software
Inconsciência (obliviousness)
Suporte a desenvolvimento com IDEs
33
Gregor Kiczales et. al. Aspect-Oriented
Programming. European Conference on
Object-Oriented Programming,
ECOOP'97
http://groups.yahoo.com/group/asoc-br/
http://www.aosd.net/
http://www.eclipse.org/aspectj
Sérgio Castelo Branco Soares
34
Cross References view
„
„
Mostra relacionamentos de e para o membro selecionado
Um clique duplo do mouse sobre uma das extremidades
abre e mostra o arquivo fonte no editor
Classe
Aspecto
Sérgio Castelo Branco Soares
35
Sérgio Castelo Branco Soares
36
6
Impacto de Crosscutting
„
Ex: Logging no Apache Tomcat
Visualizador de aspectos: mostra o impacto de
crosscutting dos aspectos de um projeto,
pacote ou classe
„
37
Sérgio Castelo Branco Soares
Linhas vermelhas: logging
• não estão no mesmo lugar
• nem mesmo em poucos lugares
Sérgio Castelo Branco Soares
38
Software Productivity Group
http://spg.dsc.upe.br/
UPE e UFPE
Sérgio Castelo Branco Soares
Sérgio Soares
[email protected]
39
7
Download

Desenvovimento de Sodtware Orientado a Aspectos