Mixins
Em linguagens orientadas a objetos, Mixin é uma classe que provê uma certa funcionalidade para ser herdada por uma subclasse. Herdar de um Mixin não é uma forma de especialização e sim um meio de coletar funcionalidades. Uma classe pode ter a maioria ou todas as suas funcionalidades herdadas de um ou mais Mixins através de herança múltipla.
CeasarJ é uma linguagem orientada a aspectos que dá suporte a implementação de Mixins.
Implementação de Variações usando Mixins - CaesarJ
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_1.zi e
epl_caesarj.zip
*obs: CaesarJ não dá suporte as features de Java 5 (generics, etc.), por isso, o código base foi alterado para satisfazer esta limitação.
Variação 1
Estratégia utilizada: deixar o código da base apenas com o tipo Inteiro e implementar o tipo Double em classes (mixins).
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 cclass AddExp extends BinaryExp {
...
public Value evaluate() {
return new IntegerValue(((IntegerValue) getLeft().evaluate()).value()
+ ((IntegerValue) getRight().evaluate()).value());
}
}
Passo 2 - Criar Mixins que implementem o tipo Double
public cclass DoubleAddExp extends AddExp{
public Value evaluate() {
return new DoubleValue(((DoubleValue) getLeft().evaluate()).value()
+ ((DoubleValue) getRight().evaluate()).value());
}
}
-> Para criar produtos da linha onde a feature Double foi selecionada, a classe DoubleAddExp deve ser instanciada no lugar da classe AddExp.
obs: Neste exemplo, por simplicidade, as classes instanciadas foram selecionadas através de compilação condicional. (isto está refletido na classe Parser.java que contém a lógica de criação da árvore de expressões)
Variação 2
Estratégia utilizada: Criar Mixins para dar suporte a operação Print
1 public interface PrintExpression extends Expression{
public void print();
}
2 public abstract cclass PrintBinaryExp extends BinaryExp implements PrintExpression{
public void print() {
PrintExpression lPe = (PrintExpression)getLeft();
lPe.print();
System.out.print(" "+getOperator()+" ");
PrintExpression rPe = (PrintExpression)getRight();
rPe.print();
}
}
*3* public cclass PrintAddExp extends PrintBinaryExp & AddExp{}
No exemplo acima, mostramos a hierarquia criada para se definir a operação Print para expressões do tipo AddExp. Para cada expressão (sub, mult, div...) cria-se um novo Mixin (como definido em
3).
-> Para criar produtos da linha onde a feature Print foi selecionada, a classe PrintAddExp deve ser instanciada no lugar da classe AddExp.
-> É necessário a criação de um novo Mixin para dar suporte ao produtos que tiverem as features Double e Print selecionadas ao mesmo tempo.
public cclass PrintDoubleAddExp extends DoubleAddExp & PrintBinaryExp {}
-> Para geração destes produtos, a classe PrintDoubleAddExp deve ser instanciada no lugar da classe AddExp.
Variação 3
A inclusão das operações de multiplicação e divisão em um produto não foram implentadas com Mixins. 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 - 29 Aug 2008