Objectivos
Aplicação dos conhecimentos adquiridos sobre a Fénix Framework para a especificação do modelo de domínio do projecto utilizando a DML.
Descrição
Este aula serve como apoio à 1ª entrega do projecto de Engenharia de Software. Os alunos já devem estar familiarizados com a especificação do modelo de domínio utilizando a DML providenciada pela Fénix Framework.
Nota:
cada grupo deverá reunir-se antes da aula de laboratório para desenvolver o máximo possível da implementação da 1ª entrega do projecto para que o docente das práticas possa esclarecer eventuais dúvidas. O apoio dado a cada grupo será com base naquilo que for apresentado durante a aula. Esta aula funciona como uma pré-avaliação do código já realizado.
Herança na DML da Fénix Framework
Se quisermos modelar duas classes Fruta e Abacaxi, que representam entidades que devem pertencer ao estado persistente de uma dada aplicação e que estão relacionadas por uma relação de herança, a forma de o fazer usando a DML da Fénix Framework é a seguinte:
// ficheiro frutaria.dml class Fruta { String cor; float peso; }
class Abacaxi extends Fruta { String origem; }
Note-se que existe uma classe intermédia na relação de herança entre Fruta e Abacaxi.
Na Fénix Framework, cada entidade declarada na DML herda de uma class _Base.
Ou seja, neste caso, a classe Fruta herda de Fruta_Base:
// Ficheiro Fruta.java public abstract class Fruta extends Fruta_Base {
protected Fruta() {
super();
}
// restantes métodos de Fruta
}
E a classe Abacaxi de Abacaxi_Base:
// Ficheiro Abacaxi.java public class Abacaxi extends Abacaxi_Base {
public Abacaxi() {
super();
}
// restantes métodos de Abacaxi
}
A relação de herança entre Abacaxi e Fruta expressa no ficheiro 'frutaria.dml', é obtida através da herança de Abacaxi_Base de Fruta:
// Ficheiro Abacaxi_Base.java gerado automaticamente para build/src public abstract class Abacaxi_Base extends Fruta {
protected Abacaxi_Base() { super(); }
// restante código gerado automaticamente pela Fénix Framework
}
O problema é que no construtor de Abacaxi, as referências a possíveis construtores da super classe (via super) referem-se à classe Abacaxi_Base e não a Fruta, como seria desejável. As classes _Base apenas disponibilizam um construtor, o construtor sem argumentos. Dado que estas classes são geradas automaticamente pela Fénix Framework, durante o processamento do ficheiro dml que contém a especificação do modelo do domínio da aplicação. não se deve alterar o código destas classes dado que os ficheiros que contém as classes _Base são destruídos durante o processamento do ficheiro dml.
Uma forma de ter um mecanismo semelhante ao da herança para os construtores, é definir o código de inicialização não no construtor mas num método auxiliar (por exemplo init).
Nesse caso, a classe Fruta passa a ter esse método:
// Ficheiro Fruta.java public abstract class Fruta extends Fruta_Base { protected Fruta() {} protected void init(String cor, float peso) { setCor(cor); setPeso(peso); } // restantes métodos de Fruta }
E as classes derivadas como Abacaxi passam a:
// Ficheiro Abacaxi.java class Abacaxi extends Abacaxi_Base {
public Abacaxi() { super(); }
public Abacaxi(String origem, float peso) { super(); init(origem, peso); }
// permite que a hierarquia de classes possa continuar a crescer
protected void init(String origem, float peso) { super.init("Yellow", peso); setOrigem(origem); }
// restantes métodos de Abacaxi. }
Desta forma, para se criar uma instância da classe Abacaxi faz-se:
Abacaxi a = new Abacaxi("Azores", 10.0f);
Code highlight generated with tohtml.com/java