Lab2 Adriano Brasileiro

aluno: Adriano Brasileiro Silva
ano/sem: 2008/2o.
data do laboratório (num. da semana) : 07/09/2008 (6)

Introdução

Nesta prática desenvolvemos o projeto anterior para permitir melhorias a ele:

- Foi criada uma classe que serve de interface com o usuário;
- A estrutura foi alterada para permitir a inclusão de novos tipos de alunos;
- Foi feita uma introdução aos conceitos de exceção;
- Foi criada uma estrutura de filas que pode ser utilizada para qualquer tipo de objeto.

Desenvolvimento

Classe Simulador

Esta classe foi feita de forma a dar uma decisão ao usuário e incluir os alunos até que o usuário decida que não, a partir do que o programa instrui os alunos a fazer os relatórios e o professor (já criado de antemão) a corrigí-los, exibindo no terminal as notas.

Vale notar alguns pontos:

- O sistema de leitura de strings da linguagem é um pouco complicada: para ler o nome dos alunos não há problemas, mas para realizar uma seleção (ler um inteiro) foi necessário fazer o programa ler uma string e convertê-la para inteiro, de modo que, caso o usuário digite um caractere neste ponto, ocorre uma exceção e o programa encerra;
- Foi criada uma array para armazenar os alunos, do tamanho da fila de relatórios, para que se pudesse percorrer esta array instruindo os alunos a realizarem os relatórios;
- O método tenta atribuir os comportamentos aos alunos e, caso não consiga, uma exceção é lançada e o aluno não é adicionado à array (o valor da variável quantidade não é incrementado).

O código da classe é o seguinte:

import java.io.*;
 
public class Simulador
{
 
    private static BufferedReader stdin = new BufferedReader( new InputStreamReader( System.in ) );
    private String aluno;
    private int selecao;
    private int quantidade = 1;
    private Aluno[] alunos = new Aluno[20];
 
    public void main() throws IOException
    {
        RelaQueue queue = new RelaQueue();
        Professor prof = new Professor(queue);
        System.out.println("Simulador de correção de relatórios");
        do{
            System.out.println("\nInserir novo aluno?: (1 - Sim, 2 - Não)");
            selecao = Integer.parseInt( stdin.readLine() );
            if(selecao == 1){
                System.out.println("\nEscreva o nome do aluno:");
                aluno = stdin.readLine();
                System.out.println("\nIndique a instituição:\n\n1 - ITA\n2 - USP\n3 - Unicamp");
                selecao = Integer.parseInt( stdin.readLine() );
                switch(selecao){
                    case 2:
                        alunos[quantidade] = new AlunoUSP(aluno, queue);
                        break;
                    case 3:
                        alunos[quantidade] = new AlunoUnicamp(aluno, queue);
                        break;
                    default:
                        alunos[quantidade] = new AlunoITA(aluno, queue);
                        break;
                }
                System.out.println("\nIndique o tipo de aluno:\n\n1 - Summa\n2 - Esforçado\n3 - Safo Preguiçoso\n4 - Imprevisível\n5 - Pemba\n6 - Burro");
                selecao = Integer.parseInt( stdin.readLine() );
                switch(selecao){
                    case 1:
                        try{
                            alunos[quantidade].setComportamento( new Summa(alunos[quantidade]) );
                        }catch (Exception e) {System.out.println( "Você tentou fazer algo impossível!"); break;}
                        quantidade++;
                        break;
                    case 3:
                        try{
                            alunos[quantidade].setComportamento( new SafoPreguicoso(alunos[quantidade]) );
                        }catch (Exception e) {System.out.println( "Você tentou fazer algo impossível!"); break;}
                        quantidade++;
                        break;
                    case 4:
                        try{
                            alunos[quantidade].setComportamento( new Imprevisivel(alunos[quantidade]) );
                        }catch (Exception e) {System.out.println( "Você tentou fazer algo impossível!"); break;}
                        quantidade++;
                        break;
                    case 5:
                        try{
                            alunos[quantidade].setComportamento( new Pemba(alunos[quantidade]) );
                        }catch (Exception e) {System.out.println( "Você tentou fazer algo impossível!"); break;}
                        quantidade++;
                        break;
                    case 6:
                        try{
                            alunos[quantidade].setComportamento( new Burro(alunos[quantidade]) );
                        }catch (Exception e) {System.out.println( "Você tentou fazer algo impossível!"); break;}
                        quantidade++;
                        break;
                    default:
                        try{
                            alunos[quantidade].setComportamento( new Esforcado(alunos[quantidade]) );
                        }catch (Exception e) {System.out.println( "Você tentou fazer algo impossível!"); break;}
                        quantidade++;
                        break;
                }
                selecao = 1;
            }
        }while(selecao != 2);
 
        for(int i = 1; i < quantidade; i++) alunos[i].fazEEntregaRelatorio();
 
        System.out.println("\nAs notas são:");
        prof.corrigirRelatorios();
 
    }
 
}

Classe Aluno

O código da classe Aluno continua o mesmo, exceto pelos métodos getInteligencia() e getDedicacao():

public double getInteligencia()
    {
        return comportamento.getInteligencia();
    }
 
    public double getDedicacao()
    {
        return comportamento.getDedicacao();
    }

que retornam os valores de inteligência e dedicação que a classe comportamento retornar:

public abstract class Comportamento
{
 
    private Aluno aluno;
 
    public Comportamento(Aluno x){
        aluno = x;
    }
 
    public abstract double getInteligencia();
    public abstract double getDedicacao();
 
}

que, por sua vez, são classes abstratas e são substituídos pelas classes herdeiras.
Essas classes têm todas estrutura parecida, que segue a seguinte conformação:

import java.util.*;
 
public class SafoPreguicoso extends Comportamento
{
 
    public SafoPreguicoso(Aluno x){
        super(x);
    }
 
    public double getInteligencia()
    {
        return 1;                         //Métodos que retornam valores definidos têm essa forma
    }
 
    public double getDedicacao()
    {
        Random generator = new Random();
        return generator.nextDouble() * 0.5;      //Métodos que retornam valores aleatórios têm essa forma
    }
 
}

Então, ao se criar um aluno, deve-se definir seu comportamento utilizando:

aluno.setComportamento( new Comportamento(aluno) );

A única maneira de se alterar o comportamento do aluno é realmente criando-se a variável comportamento. Então, uma outra maneira de se solucionar este problema é fazer este comportamento ser uma seleção (pode ser um inteiro) e, dependendo se seu valor, as funções getInteligencia() e getDedicação retornariam valores diferentes. Assim, caso se mude o valor do comportamento, tais métodos retornariam valores diferentes. No entanto isso deixaria o código pouco enxuto.

Alunos de instituições diferentes

Para este caso, simplesmente explodi a classe aluno, gerando as classes AlunoITA, AlunoUSP e AlunoUnicamp. O único objetivo dessas classes foi o de verificar se o seu aluno poderia ou não ter o comportamento especificado.

As classes ficarm com a seguinte forma:

public class AlunoUSP extends Aluno
{
 
    public AlunoUSP(String x, RelaQueue y)
    {
        super(x, y);
    }
 
    public void setComportamento(Comportamento c) throws Exception
    {
        if(c instanceof Summa || c instanceof SafoPreguicoso) throw new Exception();
        super.setComportamento(c);
    }
 
}

A classe AlunoUnicamp tem a mesma configuração desta classe. Ja a condição na classe AlunoITA é:

if(c instanceof Burro) throw new Exception();

Classe Queue

Esta classe foi feita utilizando a classe Vector do java, como sugerido. No entanto, ao se tentar definir um valor em uma vector utilizando o método "set", caso este valor não tenha sido criado ainda, o programa lança uma exceção. Assim, foi necessário utilizar o método "add" para criar estes objetos no vector. O método "get" funciona normalmente.

Assim, a classe queue é a seguinte:

import java.util.Vector;
 
public class Queue<T> {
 
    private Vector<T> array = new Vector<T>();
    private int inicio = 0;
    private int fim = 0;
    private T obj;
 
    public void queue(T obj){
        array.add(fim, obj);
        fim = (fim + 1)%10;
    }
 
    public T dequeue(){        
        if(inicio != fim)
        {
            obj = array.get(inicio);
            inicio = (inicio + 1) % 10;
            return obj;
        }
        else return null;
    }
 
}

A antiga classe RelaQueue simplesmente herda dessa classe, tendo o corpo do código vazio, a fim de não precisarmos alterar todo o código da aplicação para se adaptar ao novo Queue.

Resultados

O diagrama da aplicação é o seguinte:

imagem1.JPG

Vamos testar a classe Simulador. Primeiro criamos uma instância dela e executamos o método main():

imagem2.jpg

A seguinte janela de terminal se abre:

imagem3.JPG

Vamos inserir um hipotético aluno Adriano Brasileiro, Aluno do ITA, Burro:

imagem4.JPG

Bom, se no ITA não há alunos burros, vamos tentar um pemba (desta vez vamos chamá-lo de Adriano Brasileiro Silva, para diferenciá-lo do anterior):

imagem5.JPG

Desta vez não ocorreram problemas. Vamos agora inserir um novo aluno Mark Smith, Aluno da USP, Esforçado:

imagem6.JPG

Isto deve ser o bastante. Não queremos mais inserir alunos:

imagem7.JPG

Temos então as notas dos alunos. Note que o aluno Adriano Brasileiro não apareceu pois era um aluno inválido.

Vamos executar a classe de testes:

imagem8.JPG
imagem9.JPG

Vemos que não ocorreram erros. O terminal também se abre revelando suas notas:

imagem10.JPG

Conclusão

Houveram alguns problemas para a leitura de string, já que a linguagem java não tem uma função simples como o scanf() de C, tendo que realizar várias operações para tanto. Aparentemente java também não suporta uma array de genéricos, o que me fez utilizar a classe Vector, como foi descrito. Acredito que strategy realmente seja uma boa implementação que pode ser utilizado para simplificar bastante o código, mas ainda não sei como isso se reflete na velocidade da aplicação (se é mais rápido realizar as operações em uma única classe ou se uma "chamada de classe" leva mais tempo). Talvez fosse bom explorarmos esse assunto.

Add a New Comment
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License