|
|
Line 8: |
Line 8: |
| | | |
| Este exemplo utiliza [[Informação de Tipos em Tempo de Execução (Java)|informação de tipos em tempo de execução]], mas qualquer outro que realizasse a mesma função por outras vias seria admissível. | | Este exemplo utiliza [[Informação de Tipos em Tempo de Execução (Java)|informação de tipos em tempo de execução]], mas qualquer outro que realizasse a mesma função por outras vias seria admissível. |
− |
| |
− | === Introdução ===
| |
− | Considere-se o ficheiro <tt>obras.txt</tt>, contendo descrições de DVDs (título e realizador) e de Livros (título, autor e [[wikipedia:ISBN|ISBN]]):
| |
− | DVD:Era uma vez na amadora:Fernando Fonseca
| |
− | DVD:Lumiar selvagem:Pedro Fonseca
| |
− | Livro:A arte de sobreviver no 36:Joao Fonseca:1234567890
| |
− | Livro:Bairro alto e o budismo zen:Zun Tse Fonseca:1234567891
| |
− | DVD:48 horas para o exame:Orlando Fonseca
| |
− | Livro:Lux e o insucesso escolar - Uma visao matematica:Carlos Alberto Fonseca:1234567892
| |
− |
| |
− | A ideia da aplicação que se descreve de seguida é a leitura de cada linha como se da criação de um objecto se tratasse. Assim, o primeiro campo (os campos são separados por "<tt>:</tt>") define a classe do objecto e os restantes campos são passados como argumentos ao constructor da classe. Pretende-se ainda que a implementação seja suficientemente flexível para que resista à utilização de descrições erradas ou de descrições de objectos desconhecidos.
| |
− |
| |
− | === Interfaces ===
| |
− |
| |
− | Além dos aspectos acima, cada obra é classificada com uma ou mais interfaces, sendo o seu comportamento definido por elas.
| |
− |
| |
− | <java5>
| |
− | interface Folheável {
| |
− | void folhear();
| |
− | }
| |
− | </java5>
| |
− |
| |
− | <java5>
| |
− | interface Legível {
| |
− | void ler();
| |
− | }
| |
− | </java5>
| |
− |
| |
− | <java5>
| |
− | interface Rodopiável {
| |
− | void rodopiar();
| |
− | }
| |
− | </java5>
| |
− |
| |
− | Estas interfaces não são realmente utilizadas para os aspectos de criação dos objectos, mas permitem ilustrar a utilização de código específico em conjunto com código genérico.
| |
− |
| |
− | === A classe de base ===
| |
− |
| |
− | A classe de base de todas as entidades a criar é <tt>Obra</tt>. Esta classe, por um lado, impõe às suas subclasses a definição do método <tt>processa</tt> e, por outro, recorrendo a uma fábrica simples que, fazendo uso de informação de tipos em tempo de execução, permite criar instâncias das suas subclasses, de acordo com uma descrição passada como argumento (<tt>cria</tt>).
| |
− |
| |
− | <java5>
| |
− | import java.util.ArrayList;
| |
− | import java.lang.reflect.Constructor;
| |
− | import java.lang.reflect.InvocationTargetException;
| |
− |
| |
− | public abstract class Obra {
| |
− | static { System.out.println("Carregamento da classe Obra"); }
| |
− |
| |
− | public abstract void processa();
| |
− |
| |
− | static Obra cria(String dsc) {
| |
− | String dados[] = dsc.split(":");
| |
− | try {
| |
− | ArrayList<String> ctorargs = new ArrayList<String>(dados.length-1);
| |
− | Class tipo = Class.forName(dados[0]);
| |
− | for (int ix = 1; ix < dados.length; ix++)
| |
− | ctorargs.add(ix-1, dados[ix]);
| |
− | Constructor ctor = tipo.getConstructors()[0]; // hack? só existe um...
| |
− | return (Obra)ctor.newInstance(ctorargs.toArray());
| |
− | }
| |
− | catch (ClassNotFoundException e) { // forName
| |
− | System.err.println("!! TIPO DE OBRA DESCONHECIDO !!");
| |
− | System.err.println(e);
| |
− | return null;
| |
− | }
| |
− | catch (InstantiationException e) { // newInstance
| |
− | System.err.println("!! TIPO DE OBRA ABSTRACTO !!");
| |
− | System.err.println(e);
| |
− | return null;
| |
− | }
| |
− | catch (IllegalAccessException e) { // newInstance
| |
− | System.err.println("!! TIPO DE OBRA SEM CONSTRUCTOR ACESSÍVEL!!");
| |
− | System.err.println(e);
| |
− | return null;
| |
− | }
| |
− | catch (IllegalArgumentException e) { // newInstance
| |
− | System.err.println("!! TIPO DE OBRA MAL DESCRITO !!");
| |
− | System.err.println(e);
| |
− | return null;
| |
− | }
| |
− | catch (InvocationTargetException e) { // newInstance
| |
− | System.err.println("!! TIPO DE OBRA COM CONSTRUCTOR EM APUROS !!");
| |
− | System.err.println(e);
| |
− | return null;
| |
− | }
| |
− | }
| |
− |
| |
− | }
| |
− | </java5>
| |
− |
| |
− | Note-se o tratamento de várias excepções, em particular, o tratamento da excepção <tt>ClassNotFoundException</tt>, que tem, neste contexto especial, um significado para a aplicação algo distinto do habitual.
| |
− |
| |
− | Note-se ainda o tratamento de <tt>InvocationTargetException</tt>, que permite lidar com as excepções específicas do constructor da obra em causa (''exception chaining'').
| |
− |
| |
− | === As classes das obras ===
| |
− |
| |
− | Para DVDs:
| |
− | <java5>
| |
− | public class DVD extends Obra implements Rodopiável, Legível {
| |
− | static { System.out.println("Carregamento da classe DVD"); }
| |
− |
| |
− | String _título;
| |
− | String _realizador;
| |
− |
| |
− | public DVD(String título, String realizador) {
| |
− | _título = título;
| |
− | _realizador = realizador;
| |
− | }
| |
− |
| |
− | public String toString() { return "DVD:" + _título + ":" + _realizador; }
| |
− | public void ler() { System.out.println("LER " + this); }
| |
− | public void rodopiar() { System.out.println("RODOPIAR " + this); }
| |
− |
| |
− | public void processa() { rodopiar(); ler(); }
| |
− | }
| |
− | </java5>
| |
− |
| |
− | Para livros:
| |
− | <java5>
| |
− | public class Livro extends Obra implements Folheável, Legível {
| |
− | static { System.out.println("Carregamento da classe Livro"); }
| |
− |
| |
− | String _título;
| |
− | String _autor;
| |
− | String _isbn;
| |
− |
| |
− | public Livro(String título, String autor, String isbn) {
| |
− | _título = título;
| |
− | _autor = autor;
| |
− | _isbn = isbn;
| |
− | }
| |
− |
| |
− | public String toString() { return "Livro:" + _título + ":" + _autor + ":" + _isbn; }
| |
− | public void ler() { System.out.println("LER " + this); }
| |
− | public void folhear() { System.out.println("FOLHEAR " + this); }
| |
− |
| |
− | public void processa() { folhear(); ler(); }
| |
− | }
| |
− | </java5>
| |
− |
| |
− | === Aplicação exemplo ===
| |
− |
| |
− | Esta aplicação lê o ficheiro de obras (propriedade <tt>obras</tt>) e processa cada linha, criando os objectos correspondentes. Depois de lidas, as obras são processadas (uniformemente).
| |
− | <java5>
| |
− | import java.util.ArrayList;
| |
− | import java.io.BufferedReader;
| |
− | import java.io.FileReader;
| |
− | import java.io.IOException;
| |
− |
| |
− | public class Teste {
| |
− | public static void main(String[] args) throws IOException {
| |
− | String entrada = System.getProperty("obras", "obras.txt");
| |
− | BufferedReader r = new BufferedReader(new FileReader(entrada));
| |
− | String linha;
| |
− | ArrayList<Obra> obras = new ArrayList<Obra>();
| |
− | while ((linha = r.readLine()) != null) {
| |
− | Obra o = Obra.cria(linha);
| |
− | obras.add(o);
| |
− | System.out.println(o);
| |
− | }
| |
− | r.close();
| |
− | System.out.println("****************");
| |
− | for (Obra o: obras) o.processa();
| |
− | }
| |
− | }
| |
− | </java5>
| |
− |
| |
− | A saída da aplicação de teste é a que se apresenta. Note-se a ordem de carregamento das classes.
| |
− |
| |
− | '''% java -Dobras=obras.txt Teste'''
| |
− | <font color="green">Carregamento da classe Obra</font>
| |
− | <font color="green">Carregamento da classe DVD</font>
| |
− | DVD:Era uma vez na amadora:Fernando Fonseca
| |
− | DVD:Lumiar selvagem:Pedro Fonseca
| |
− | <font color="green">Carregamento da classe Livro</font>
| |
− | Livro:A arte de sobreviver no 36:Joao Fonseca:1234567890
| |
− | Livro:Bairro alto e o budismo zen:Zun Tse Fonseca:1234567891
| |
− | DVD:48 horas para o exame:Orlando Fonseca
| |
− | Livro:Lux e o insucesso escolar - Uma visao matematica:Carlos Alberto Fonseca:1234567892
| |
− | ****************
| |
− | RODOPIAR DVD:Era uma vez na amadora:Fernando Fonseca
| |
− | LER DVD:Era uma vez na amadora:Fernando Fonseca
| |
− | RODOPIAR DVD:Lumiar selvagem:Pedro Fonseca
| |
− | LER DVD:Lumiar selvagem:Pedro Fonseca
| |
− | FOLHEAR Livro:A arte de sobreviver no 36:Joao Fonseca:1234567890
| |
− | LER Livro:A arte de sobreviver no 36:Joao Fonseca:1234567890
| |
− | FOLHEAR Livro:Bairro alto e o budismo zen:Zun Tse Fonseca:1234567891
| |
− | LER Livro:Bairro alto e o budismo zen:Zun Tse Fonseca:1234567891
| |
− | RODOPIAR DVD:48 horas para o exame:Orlando Fonseca
| |
− | LER DVD:48 horas para o exame:Orlando Fonseca
| |
− | FOLHEAR Livro:Lux e o insucesso escolar - Uma visao matematica:Carlos Alberto Fonseca:1234567892
| |
− | LER Livro:Lux e o insucesso escolar - Uma visao matematica:Carlos Alberto Fonseca:1234567892
| |
| | | |
| [[category:Ensino]] | | [[category:Ensino]] |
| [[category:PO]] | | [[category:PO]] |
| [[category:PO Exemplos|S]] | | [[category:PO Exemplos|S]] |