Lab2 Rafael Siqueira

aluno: Rafael Siqueira
ano/sem: 2008/2o.
data do laboratório (num. da semana) : 21/08/2008 (4)

Introdução

Nesse segundo laboratório, o objetivo era dar um upgrade no laboratório passado através da inclusão de uma classe Simulador que possibilita maior interação com o usuário uma vez que não exige conhecimentos de programação para que o programa seja rodado. A classe recebe inputs do usuário via linhas de comando e assim coordena-se a interação entre os objetos. Em seguida, mais alterações foram feitas no programa para deixá-lo mais completo e mais 'real'. As mudanças nas classes e na relação entre elas foi repassada para o Simulador para que o propósito do mesmo pudesse ser alcançado com as atualizações feitas.

Desenvolvimento

A estrutura do programa é muito similar à do laboratório anterior, tendo como principais alterações as seguintes:
1) Classe Aluno deixa de ser abstrata, tendo como subclasses alunos de universidades diferentes
2) Criação da classe abstrata Comportamento
3) Utilização de exceções para limitar o comportamento dos alunos dependendo de sua universidade
4) Criação de uma fila de genéricos, da qual RelaQueue é subclasse
5) Classe Simulador

As únicas classes inalteradas foram as Professor e Relatório, cujos códigos já seguem abaixo.

Professor

import java.util.*; //Importa biblioteca de Java para que se utilize alguma de suas classes pré-definidas
 
public class Professor
{
    //Variáveis internas
    RelaQueue queue;
 
    //Contrutor
    public Professor(RelaQueue queue) {
        this.queue=queue;
    }
 
    //Corrige um relatorio e retorna a nota do aluno no mesmo
    private double corrigirRelatorio(Relatorio rela) 
    {
        double nota =(rela.getOriginalidade()+rela.getQualidade()+fatorAleatorioDe0a1())/3*10;
        return nota;
    }
 
    //Retorna um número aleatório de 0 a 1
    public double fatorAleatorioDe0a1()
    {
        Random generator = new Random();
        double r = generator.nextDouble();
        return r * 1;
    }
 
    //Método que faz com que todos os relatórios sejam tirados da fila, sejam corrigidos e tenham suas notas impressas na tela
    public void corrigirRelatorios() 
    {
        Relatorio rela = queue.dequeue();
        while (rela!=null) 
        {
            System.out.println(rela.getAluno().getNome()+": "+corrigirRelatorio(rela));   
            rela=queue.dequeue();
        }
    }   
}

Relatório

public class Relatorio
{
    //Variáveis internas
    private double qualidade;
    private double originalidade;
    private Aluno aluno;
 
    //Construtor
    public Relatorio(double qualidade,double originalidade,Aluno aluno) {
        this.qualidade = qualidade;
        this.originalidade = originalidade;
        this.aluno = aluno;
    }
 
    //Getter de qualidade
    public double getQualidade() {
        return this.qualidade;
    }
 
    //Getter de originalidade
    public double getOriginalidade() {
        return this.originalidade;
    }
 
    //Getter de aluno
    public Aluno getAluno() {
        return this.aluno;
    }
}

Classe Aluno

A classe aluno foi alterada de forma a não ter como subclasses classes determinadas pelo comportamento do aluno. Agora, a classe aluno possui uma variável comportamento que é definida pela criação de uma classe Comportamento que será explicada a seguir. As subclasses de aluno agora são referentes às diferentes universidades que cada aluno pode estudar: ITA, USP e Unicamp. Cada uma possui restrições quanto ao comportamento que o aluno pode ter. Segue abaixo o código da classe Aluno e de suas subclasses: AlunoITA, AlunoUSP e AlunoUnicamp.

Aluno

public class Aluno
{
    //Variáveis internas
    private int conhecimento = 0;
    private String nome = new String();
    private RelaQueue queue;
    Comportamento comportamento;
 
    //Construtor
    public Aluno(String nome,RelaQueue queue)
    {
        this.nome=nome;
        this.queue=queue;
        this.comportamento = new Esforcado(this);
    }
 
    //Método que faz o relatório do aluno dependendo das características do seu comportamento e o coloca na pilha de relatórios
    public void fazEEntregaRelatorio() 
    {
        double qualidade = (2 * this.comportamento.getDedicacao() + 1 * this.comportamento.getInteligencia() ) / 3 ;
        double originalidade = (1 * this.comportamento.getDedicacao() + 2 * this.comportamento.getInteligencia() ) / 3 ;
        Relatorio rela = new Relatorio (qualidade,originalidade,this);
        queue.queue(rela);
        conhecimento++;
    }
 
    //Getter de nome
    public String getNome() 
    {
        return this.nome;
    }
 
    //Getter de conhecimento
    public double getConhecimento() 
    {
        return this.conhecimento; 
    }
 
    //Getter de dedicacao
    public double getDedicacao() 
    {
        return this.comportamento.getDedicacao();
    }
 
    //Getter de inteligencia
    public double getInteligencia() 
    {
        return this.comportamento.getInteligencia();
    }
 
    //Setter de comportamento
    public void setComportamento(Comportamento comportamento) throws Exception 
    {
        this.comportamento=comportamento;
    }
}

AlunoITA

public class AlunoITA extends Aluno
{
    //Construtor
    public AlunoITA(String nome,RelaQueue queue)
    {
        super(nome,queue);
    }
 
    //Tratamento das restrições de comportamento que o aluno do ITA deve ter, ele não pode ser burro, através do uso de exceções
    public void setComportamento(Comportamento comportamento) throws Exception 
    {
    if(comportamento instanceof Burro) throw new Exception(); 
    super.setComportamento(comportamento);
    }
}

AlunoUSP

public class AlunoUSP extends Aluno
{
    //Construtor
    public AlunoUSP(String nome,RelaQueue queue)
    {
        super(nome,queue);
    }
 
    //Tratamento das restrições de comportamento que o aluno da USP deve ter, ele não pode ser summa nem safo&preguicoso, através do uso de exceções
    public void setComportamento(Comportamento comportamento) throws Exception 
    {
        if(comportamento instanceof SafoPreguicoso || comportamento instanceof Summa) throw new Exception(); 
        super.setComportamento(comportamento);
    }    
}

AlunoUnicamp

public class AlunoUnicamp extends Aluno
{
    //Construtor
    public AlunoUnicamp(String nome,RelaQueue queue)
    {
        super(nome,queue);
    }
 
    //Tratamento das restrições de comportamento que o aluno da Unicamp deve ter, ele não pode ser summa nem safo&preguicoso, através do uso de exceções
    public void setComportamento(Comportamento comportamento) throws Exception 
    {
    if(comportamento instanceof SafoPreguicoso || comportamento instanceof Summa) throw new Exception(); 
    super.setComportamento(comportamento);
    }    
}

Criação da classe Comportamento

A classe Comportamento é uma classe abstrata que possui 6 subclasses: Summa, SafoPreguicoso, Esforcado, Imprevisivel, Pemba e Burro. Essas subclasses possuem diferentes maneiras de determinar a inteligência e a dedicação do Aluno que possui tal comportamento. E ainda, há na classe Aluno um método setter de comportamento para que possa haver mudança do comportamento do aluno. Segue abaixo o código da classe Comportamento e de cada uma das suas subclasses.

Comportamento

public abstract class Comportamento
{
    //Variáveis internas
    public Aluno aluno;
 
    //Construtor
    public Comportamento(Aluno aluno) {
       this.aluno = aluno;
    }
 
    //Métodos abstratos subscritos nas suas subclasses
    abstract double getDedicacao();
    abstract double getInteligencia();
}

Summa

public class Summa extends Comportamento
{
    //Variáveis internas
    private double inteligencia = 1;
    private double dedicacao = 1;
 
    //Construtor
    public Summa(Aluno aluno)
    {
        super(aluno);
    }
 
    //Getter de inteligencia
    public double getInteligencia()
    {
        return this.inteligencia;
    }
 
    //Getter de dedicacao
    public double getDedicacao() 
    {
        return this.dedicacao;  
    }
}

SafoPreguicoso

import java.util.*; //Importa biblioteca de Java para utilização de alguma de suas classes pré-definidas
 
public class SafoPreguicoso extends Comportamento
{
    //Variáveis internas
    private double inteligencia = 1;
    private double dedicacao;
 
    //Construtor
    public SafoPreguicoso(Aluno aluno)
    {
        super(aluno);
    }
 
    //Getter de inteligencia
    public double getInteligencia()
    {
        return this.inteligencia;
    }
 
    //Getter de dedicacao
    public double getDedicacao() 
    {
        Random generator = new Random();
        double r = generator.nextDouble();
        return r * 0.5;   
    }
}

Esforcado

public class Esforcado extends Comportamento
{
     //Variáveis internas
    private double inteligencia = 0.5;
    private double dedicacao = 1;
 
    //Construtor
    public Esforcado(Aluno aluno) 
    {
        super(aluno);
    }
 
    //Getter de inteligencia
    public double getInteligencia() 
    {
        return this.inteligencia;
    }
 
    //Getter de dedicacao
    public double getDedicacao() 
    {
        return this.dedicacao;
    }  
}

Imprevisivel

import java.util.*; //Importa biblioteca de Java para utilização de alguma de suas classes pré-definidas
 
public class Imprevisivel extends Comportamento
{
    //Variáveis internas
    private double inteligencia;
    private double dedicacao;
 
    //Construtor
    public Imprevisivel(Aluno aluno)
    {
        super(aluno);
    }
 
    //Getter de inteligencia
    public double getInteligencia()
    {
        Random generator = new Random();
        double r = generator.nextDouble();
        return r * 1; 
    }
 
    //Getter de dedicacao
    public double getDedicacao() 
    {
        Random generator = new Random();
        double r = generator.nextDouble();
        return r * 1;   
    }
}

Pemba

import java.util.*; //Importa biblioteca de Java para utilização de alguma de suas classes pré-definidas
 
public class Pemba extends Comportamento
{
    //Variáveis internas
    private double inteligencia;
    private double dedicacao;
 
    //Construtor
    public Pemba(Aluno aluno)
    {
        super(aluno);
    }
 
    //Getter de inteligencia
    public double getInteligencia()
    {
        Random generator = new Random();
        double r = generator.nextDouble();
        return r * 0.5; 
    }
 
    //Getter de dedicacao
    public double getDedicacao() 
    {
        Random generator = new Random();
        double r = generator.nextDouble();
        return r * 0.5;   
    }
}

Burro

public class Burro extends Comportamento
{
    //Variáveis internas
    private double inteligencia = 0;
    private double dedicacao = 0;
 
    //Construtor
    public Burro(Aluno aluno)
    {
        super(aluno);
    }
 
    //Getter de inteligencia
    public double getInteligencia() {
        return this.inteligencia;
    }
 
    //Getter de dedicacao
    public double getDedicacao() {
        return this.dedicacao;
    }
}

Implementando restrições utilizando exceções

Cada subclasse de aluno representa um estudante que estuda em uma das três universidades: ITA, Unicamp e USP. No programa, dependendo de onde o aluno estuda, ele tem restrições no tipo de comportamento que pode possuir:
- Alunos do ITA não podem ter o comportamento Burro
- Alunos da USP e da Unicamp não podem ter o comportamento Summa nem SafoPreguicoso

Diante disso, fizemos um tratamento dessas restrições através do uso de exceções do Java. Ele funciona basicamente da seguinte forma: quando um método de uma classe lança uma exceção, essa deve ser tratada toda vez que o método for chamado; e assim nós podemos, quando alguém tentar fazer algo que não é possível ser feito, 'capturar' essa exceção e fazermos de outra forma, exibindo mensagens de erro e afins. Assim, o método setComportamento() dos alunos lança uma exceção que é tratada no método main() da classe Simulador, quando o usuário escolhe o comportamento do aluno depois de ter escolhido sua universidade. Segue abaixo um excerto do código da classe Simulador na qual mostramos o tratamento de uma exceção, quando o usuário tenta setar o comportamento de burro à um AlunoITA.

try {
   aluno[i].setComportamento(new Burro(aluno[i]));
} catch(Exception e) {
   c.printf("Alunos do ITA nao podem ser burros!\n");
   c.printf("Digite um comportamento válido");
   exc=1;
}

Criação de uma fila de genéricos

Tal criação se deu de maneiro complicada devido à disperidade de opiniões e maneiras propostas para sua implementação, nem todas que funcionaram. De qualquer forma, a idéia foi não restringir a fila a apenas os relátorios dos alunos, qualquer coisa pode ser armazenada nela. O formato e as funcionalidades são os mesmos do laboratório passado. A classe RelaQueue, portanto, nesse laboratório, é uma subclasse dessa fila de genéricos e herda todos os métodos da superclasse, não tendo nenhum método próprio. Seguem abaixo os códigos das duas classes, nos quais evidencia-se como foi feita essa transição (uso do tipo Object[]) da generalidade para a particularidade do problema (Relatórios na fila).

Queue<T>

import java.util.Vector; //Importa uma biblioteca de Java da qual faz parte o tipo Object[] usado no código
 
public class Queue<T>
{
    //Estado inicial - fila vazia
    private Object[] array = new Object[10];
    private int inicio = 0;
    private int fim = 0;
 
    //Comportamento
    //Método que coloca algo na fila
    public void queue (T obj) 
    {
        array[fim]=obj;
        fim = (fim+1) % 10;
    }
 
    //Método que retorna algo tirando-o da fila, retornando nulo caso a mesma esteja vazia
    public T dequeue()
    {
        if (inicio==fim)
        {
            return null;
        }
        else 
        {
            T objsaida = (T) array[inicio];
            inicio = (inicio+1) % 10;
            return objsaida;
        }
    }
}

RelaQueue

public class RelaQueue extends Queue<Relatorio>
{
}

Classe Simulador

Como já explicado, a classe simulador garante uma interação muito facilitada entre o programa e o usuário, de forma que esse último não preciso ter conhecimento de programação para poder usar o programa. Abaixo, seguem as duas classes Simulador, a primeira se refere ao primeiro laboratório e a segunda ao segundo, depois que foram feitas todas as alterações aqui descritas.

Simulador 1

import java.io.Console; //Biblioteca de java que foi usada nesse laboratório para receber entradas do usuário via teclado e escrever na tela, através dos métodos readLine() e printf() respectivamente
 
public class Simulador {
    public static void main(String[] args) {
        //Definição de um console para que se possa usar os métodos readLine() e printf()
        Console c = System.console();
        int num, i, comp;
        //Criação dos alunos
        do {
            c.printf("\n");
            String num2 = c.readLine("Quantos alunos deseja criar? ");
            num = Integer.parseInt(num2);
            if (num<=0) c.printf("Digite um número válido");
        } while (num<=0);
        Aluno[] aluno = new Aluno[num];
        //Criação da fila de relatórios
        RelaQueue queue = new RelaQueue();
        //Definição do nome e do comportamento dos mesmos
        for (i=0;i<num;i++) {
            String nome = c.readLine("Digite o nome do aluno "+(i+1));
            c.printf("Qual o comportamento do aluno "+nome); 
            c.printf("?\n");
            c.printf("1 - Safo & Preguicoso\n");
            c.printf("2 - Esforcado\n");
            do {
                c.printf("\n");
                String comp2 = c.readLine("Digite o comportamento ");
                comp = Integer.parseInt(comp2);
                if(comp>2 || comp<1) c.printf("Digite um comportamento válido");
            } while (comp>2 || comp<1);
            if(comp==1) aluno[i] = new AlunoSafoPreguicoso(nome,queue);
            else aluno[i] = new AlunoEsforcado(nome,queue);   
        }
        //Criação do professor
        Professor professor = new Professor(queue);
        //Alunos fazem e entregam seus relatórios
        for (i=0;i<num;i++) {
            aluno[i].fazEEntregaRelatorio();
        }
        c.printf("\nOs alunos fizeram e entregaram seus relatórios");
        c.printf("\nO professor corrigiu os relatórios, as notas seguem abaixo:\n\n");
        //Professor corrige os relatórios e imprime suas notas
        professor.corrigirRelatorios();   
    }       
}

Simulador 2

import java.io.Console; //Biblioteca de java que foi usada nesse laboratório para receber entradas do usuário via teclado e escrever na tela, através dos métodos readLine() e printf() respectivamente
 
public class Simulador {
    public static void main(String[] args) {
        //Definição de um console para que se possa usar os métodos readLine() e printf()
        Console c = System.console();
        int num, i, comp, uni, exc;
        //Criação dos alunos
        do {
            c.printf("\n");
            String num2 = c.readLine("Quantos alunos deseja criar? ");
            num = Integer.parseInt(num2);
            if (num<=0) c.printf("Digite um número válido");
        } while (num<=0);
        Aluno[] aluno = new Aluno[num];
        //Criação da fila de relatórios
        RelaQueue queue = new RelaQueue();
        //Definição do nome, da universidade e do comportamento dos alunos
        for (i=0;i<num;i++) {
            String nome = c.readLine("Digite o nome do aluno "+(i+1));
            c.printf("Qual a universidade do aluno "+nome); 
            c.printf("?\n");
            c.printf("1 - ITA\n");
            c.printf("2 - USP\n");
            c.printf("3 - Unicamp\n");
            do {
                c.printf("\n");
                String uni2 = c.readLine("Digite a universidade ");
                uni = Integer.parseInt(uni2);
                if(uni>3 || uni<1) c.printf("Digite uma universidade válida");
            } while (uni>3 || uni<1);
            if(uni==1) aluno[i] = new AlunoITA(nome,queue); 
            else if (uni==2) aluno[i] = new AlunoUSP(nome,queue);
            else aluno[i] = new AlunoUnicamp(nome,queue);
            c.printf("Qual o comportamento do aluno "+nome); 
            c.printf("?\n");
            c.printf("1 - Safo & Preguicoso\n");
            c.printf("2 - Esforcado\n");
            c.printf("3 - Summa\n");
            c.printf("4 - Imprevisivel\n");
            c.printf("5 - Pemba\n");
            c.printf("6 - Burro\n");
            //Tratamento das exceções para os comportamentos dos alunos dependendo de sua universidade
            do {
                exc=0;
                c.printf("\n");
                String comp2 = c.readLine("Digite o comportamento ");
                comp = Integer.parseInt(comp2);
                if(comp==1) {
                    if (uni!=1) {
                        //Alunos da USP ou da Unicamp não podem ser safos e preguiçosos
                        try {
                            aluno[i].setComportamento(new SafoPreguicoso(aluno[i]));
                        } catch(Exception e) {
                            c.printf("Alunos que nao sao do ITA nao podem ser safos e preguicosos!\n");
                            c.printf("Digite um comportamento válido");
                            exc=1;
                        }
                    }
                }
                else if(comp==2) {
                    try {   
                        aluno[i].setComportamento(new Esforcado(aluno[i]));
                    } catch(Exception e) {
                    }
                }
                else if(comp==3) {
                    if (uni!=1) {
                        //Alunos da USP ou da Unicamp não podem ser summa
                        try {
                            aluno[i].setComportamento(new SafoPreguicoso(aluno[i]));
                        } catch(Exception e) {
                            c.printf("Alunos que nao sao do ITA nao podem ser summa!\n");
                            c.printf("Digite um comportamento válido");
                            exc=1;
                        }
                    }
                }               
                else if(comp==4) {
                    try {
                        aluno[i].setComportamento(new Imprevisivel(aluno[i]));
                    } catch(Exception e) {
                    }
                }
                else if(comp==5) {
                    try {
                        aluno[i].setComportamento(new Pemba(aluno[i]));
                    } catch(Exception e) {
                    }
                }
                else if (comp==6) {
                    if(uni==1) {
                        //Alunos do ITA não podem ser burros
                        try {
                            aluno[i].setComportamento(new Burro(aluno[i]));
                        } catch(Exception e) {
                            c.printf("Alunos do ITA nao podem ser burros!\n");
                            c.printf("Digite um comportamento válido");
                            exc=1;
                        }
                    }
                }
                if(comp>6 || comp<1) c.printf("Digite um comportamento válido");
            } while ((comp>6 || comp<1) || exc==1);
        }
        //Criação do professor
        Professor professor = new Professor(queue);
        //Alunos fazem e entregam seus relatórios
        for (i=0;i<num;i++) {
            aluno[i].fazEEntregaRelatorio();
        }
        c.printf("\nOs alunos fizeram e entregaram seus relatórios");
        c.printf("\nO professor corrigiu os relatórios, as notas seguem abaixo:\n\n");
        //Professor corrige os relatórios e imprime suas notas
        professor.corrigirRelatorios();   
    }       
}

Seguem abaixo imagens que comprovam o bom funcionamento do programa.

imagem1.JPG

Imagem 1 - Novo diagrama de classes do Laboratório 1

imagem2.JPG

Imagem 2 - Diagrama de classes do Laboratório 2

imagem3.JPG

Imagem 3 - Resultado dos testes realizados pela classes Teste fornecida para os alunos

O programa foi rodado no 'cmd' do Windows (DOS) através do comando 'java Simulador' dentro da pasta de cada laboratório

imagem4.JPG

Imagem 4 - Resultado da execução do programa do Laboratório 1

imagem5.JPG

Imagem 5 - Resultado da execução do programa do Laboratório 2

Conclusão

O laboratório foi muito interessante pois foi feita uma ligação com o primeiro laboratório através da melhoria de várias de suas funcionalidadess, bem como com diversas maneiras de torná-lo mais complexo. Achei importante a implementação de uma fila genérica que comporta o enfileiramente de qualquer coisa. Tal tipo de implementação é essencial para códigos complexos bem como para a manipulação de mudanças de código, evitando que muito do código tenha que ser alterado em decorrência de uma ligeira mudança nas exigências da aplicação que se cria. O tratamento de exceções foi outra coisa que não tinha idéia da existência e que ampliou os horizontes da minha programação em Java. Em suma, o laboratório foi bem proposto e estruturado apenas senti que mais suporte podia ter sido dado no tocante à execução do programa, execução da classe Simulador. Não ficou claro o que se queria exatamente. A utilização do 'cmd' aprendi com um colega e vi que outros partiram para um lado ainda inexplorado na matéria, a criação de uma interface gráfica mais complexa para o programa, não sei como eles fizeram isso.

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