Tags:
create new tag
, view all tags

AspectJ

Tecnologia orientada a aspectos desenvolvida como uma extensão da linguagem de programação Java.

Implementação de Variações em AspectJ

Esse exemplo consiste em adaptar o avaliador de expressões de acordo com:

  • 1 - o tipo da expressão (int ou double).
  • 2 - suporte opcional a geração de uma representação String das expressões.
  • 3 - suporte alternativo a expressões básicas (soma e subtração) ou avançadas (que inclui divisão e multiplicação)

Em linhas gerais, o que será feito é a implentação destas variações a partir de um código base. Os arquivos deste exemplo estão disponíveis para download aqui: epl_base.rar e epl_aspectJ.rar

Variação 1

-> Estratégia utilizada: deixar o código da base apenas com o tipo Inteiro e implementar o tipo Double em aspectos (construtores de AspectJ utilizados: pointcuts e advices)

Passo 1 - efetuar refactoring no código das expressões para deixá-lo somente com o tipo inteito

Exemplo: AddExp.java

public class AddExp extends BinaryExp {
...
   public Value evaluate() {
      Value leftValue = getLeft().evaluate();
      Value rightValue = getRight().evaluate();
      
      if (leftValue instanceof DoubleValue)
         return new DoubleValue(((DoubleValue) leftValue).value()
               + ((DoubleValue) rightValue).value());
      else
         return new IntegerValue(((IntegerValue) leftValue).value()
               + ((IntegerValue) rightValue).value());
   }
}

AddExp.java depois do refactoring

public class AddExp extends BinaryExp {
...
   public Value evaluate() {
      
         return new IntegerValue(((IntegerValue) getLeft().evaluate()).value()
               + ((IntegerValue) getRight().evaluate()).value());
   }   
}

Passo 2 -> Criar aspectos para implentação do tipo Double:

 public abstract aspect DoubleTypeAspect {
   pointcut callEval() : call (public Value Expression.evaluate(..));

   pointcut addValue(Parser p, String value): call (public void Parser.addValue(..))
   && args(value) && target(p);
   
   void around(Parser p, String value): addValue(p,value) {
      
      p.getExp().add(new DoubleValue(Double.parseDouble(value)));
   }
}

public aspect AddSubDoubleTypeAspect extends DoubleTypeAspect{
   
    pointcut add(Expression e) :  if(e instanceof AddExp) && target(e);
   ...
      
   Value around(Expression e) : callEval()&& add(e){
      AddExp ae = (AddExp)e;
      return new DoubleValue(
            ((DoubleValue)ae.getLeft().evaluate()).value()     + (DoubleValue)ae.getRight().evaluate()).value() );
   }
   ...
}

-> Para gerar produtos da linha com o tipo Double, basta incluir na build do sistema os aspectos DoubleTypeAspect.aj e AddSubDoubleTypeAspect.aj. Caso a opção de multiplicação e divisão também fizer parte de um determinado produto, incluir também o aspecto MulDivDoubleTypeAspect.aj.

Variação 2

Estratégia utilizada: introduzir a operação Print nas classes necessárias através de aspectos. (construtores de AspectJ utilizados: inter-types, pointcuts e advices)

public privileged aspect PrintAspect {   
1   public void Expression.print(){}     
   
2   public void Value.print(){
      System.out.print(value);
   }
      
3   public void BinaryExp.print(){
      left.print();
      System.out.print(" "+operator+" ");
      right.print();      
   }
   
4   pointcut programExecution(Program p) : call(public Value Program.execute(..)) && target(p);
   
5   before(Program p) : programExecution(p) {
      p.getExpression().print();
      System.out.print(" = ");
   }

1,2,3 - Introduz o método print() na interface Expression.java e classes Value.java e BinaryExpression.java através de inter-type declaration.

4 – Captura chamadas da execução do método execute da classe Program

5 – Antes da execução de joinpoints capturados pelo pointcut definido em 4, inclui-se a chamada ao método print() da expressão que está sendo avaliada.

-> Para gerar produtos da linha com a operação Print presente, basta incluir o aspecto PrintAspect.aj na build do sistema.

Variação 3

A inclusão das operações de multiplicação e divisão em um produto não foram implentadas com aspectos. A técnica de OO, polimorfismo de subtipos (herança simples), resolve melhor este tipo de variação. Para gerar um produto da linha com suporte a estas operações, inclui-se na build do sistema as classes correspondentes.

-- FernandaDamorim - 28 Aug 2008

Topic revision: r5 - 2008-08-30 - FernandaDamorim
 
This site is powered by the TWiki collaboration platformCopyright © 2008-2020 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback

mersin escort bayan adana escort bayan izmit escort ankara escort bursa escort