Lab2 Maykon Bergamaschi

aluno: Maykon Lorencini Bergamaschi
ano/sem: 2008/2o.
data do laboratório (num. da semana) : 20/08/2008 (4)

Introdução

Este laboratório corresponde a uma extensão do laboratório anterior. As atividades foram divididas em duas partes: a primeira corresponde à criação de um novo simulador, com leitura das informações a partir do teclado; a segunda, mais extensa, consiste em tornar a aplicação mais robusta, definindo de uma nova forma o comportamento dos alunos e permitindo a inclusão de alunos de diferentes instituições.

Desenvolvimento

Primeira parte

Na primeira parte, foi criada uma nova classe Simulador, para receber inputs com informações sobre os alunos por meio do teclado. Trata-se somente de uma nova interface, pois a estrutura interna do código ainda é a mesma do laboratório anterior, pouco flexível.

Na segunda parte das atividades, a classe Simulador mostrada abaixo será bastante modificada. É importante não confundir as duas versões.

Classe Simulador (primeira parte)

import java.io.*;
import java.util.*;
 
public class Simulador
{
    public static void main(String[] args)
    {
        RelaQueue fila = new RelaQueue();
        Professor prof = new Professor(fila);
        Vector vetorAluno = new Vector();
        Aluno aluno;
 
        Console console = System.console();
        if(console != null)
        {
            //Criacao de quantos alunos o usuario desejar
 
            System.out.print("\nDeseja incluir quantos alunos? ");      
            Scanner scanner = new Scanner(console.reader());
            int nalunos = scanner.nextInt();
            for (int i=0; i<nalunos; i++) 
            {
                 System.out.print("\nDigite o nome do aluno #"+ (i+1) +": ");
                 String nome = scanner.next();
                 System.out.print("Selecione o tipo (1- esforcado / 2- safo preguicoso): ");
                 int tipo = scanner.nextInt();
                 while (!(tipo == 1 || tipo == 2)) {
                     System.out.print("Opcao invalida. Tente novamente: ");
                     tipo = scanner.nextInt();
                    }
                 if (tipo == 1) aluno = new AlunoEsforcado (nome, fila);
                 else aluno = new AlunoSafoPreguicoso (nome, fila);
                 vetorAluno.addElement(aluno);
            }      
 
            //Alunos fazem e entregam o relatorio
 
            for (int i=0; i<nalunos; i++) {
             aluno = (Aluno) vetorAluno.elementAt(i);
             aluno.fazEEntregaRelatorio();                     
            }
 
            //Professor corrige os relatorios entregues
            System.out.println("\nResultado da correcao do professor: \n");     
            prof.corrigirRelatorios();
        }
        else
        {
            throw new RuntimeException("Can't run w/out a console!");
        }
    }
}

A seguir, os resultados de um teste realizado com a classe criada.
lab2-resultados-parte1.JPG

O número de alunos está limitado a 10, devido às restrições que foram impostas na execução do laboratório anterior.

Segunda parte

A segunda parte consiste em flexibilizar a aplicação gerada, permitindo ao usuário classificar os alunos com uma maior variedade de comportamentos, além de incluir alunos de diferentes instituições.

Utilizando o padrão Strategy, foi criada uma classe abstrata Comportamento, responsável por atribuir as características dedicação e inteligência aos alunos, em lugar da classe Aluno, que deixou de ser abstrata.

Foram criadas também seis subclasses de Comportamento, com características de dedicação e inteligência pré-determinadas. O usuário, no momento da inserção dos dados no programa, deve selecionar entre as seis opções a mais adequada a cada aluno.

A seguir, os códigos relativos às classes Aluno e Comportamento.

Classe Comportamento

public abstract class Comportamento
{ 
    Aluno aluno;
    double dedicacao;
    double inteligencia;
 
    public Comportamento (Aluno aluno) {
            this.aluno = aluno;
        }
 
    public abstract double getDedicacao();
    public abstract double getInteligencia();
}

Classe Aluno

public class Aluno
{
    int conhecimento = 0;
    String nome = new String();
    Queue<Relatorio> queue;
    Comportamento comportamento;
 
    /**
     * Constructor for objects of class Aluno
     */
    public Aluno(String nome , RelaQueue queue)
    {
        this.nome = nome;
        this.queue = queue;
        this.conhecimento = 0;
        this.comportamento = new Esforcado(this); //seguindo orientacao dada no roteiro
    }
 
    public void fazEEntregaRelatorio()
    {
        double qualidade = (2 * this.getDedicacao() + 1 * this.getInteligencia() ) / 3 ;
        double originalidade = (1 * this.getDedicacao() + 2 * this.getInteligencia() ) / 3 ;       
        Relatorio rela = new Relatorio (qualidade, originalidade, this);
        queue.queue(rela);
        this.conhecimento = this.conhecimento + 1;
    }
 
    public int getConhecimento(){
        return conhecimento;    
    }  
 
    public String getNome() {
        return nome;
    }
 
    public double getInteligencia() {
        return this.comportamento.getInteligencia();
    }
 
    public double getDedicacao() {
        return this.comportamento.getDedicacao();
    }
 
    public void setComportamento(Comportamento comportamento) throws Exception{
        this.comportamento = comportamento;
    }
 
}

As seis subclasses de Comportamento estão mostradas a seguir. Elas foram criadas de acordo com o que foi especificado no roteiro do laboratório. Todas as subclasses de Comportamento têm uma estrutura bastante semelhante entre si.

Classe Summa

public class Summa extends Comportamento
{
 
double dedicacao = 1.0;
double inteligencia = 1.0;
 
    /**
     * Constructor for objects of class Summa
     */
    public Summa(Aluno aluno)
    {
        super(aluno);
    }
 
    public double getDedicacao()
    {
        return dedicacao;
    }
 
    public double getInteligencia()
    {
        return inteligencia;
    }
}

Classe SafoPreguicoso

import java.util.*;
 
public class SafoPreguicoso extends Comportamento
{
    double inteligencia = 1.0;
 
    /**
     * Constructor for objects of class SafoPreguicoso
     */
    public SafoPreguicoso(Aluno aluno)
    {
        super(aluno);
    }
 
    public double getDedicacao()
    {
        return generateRandomDe0aMeio();
    }
 
    public double getInteligencia()
    {
        return inteligencia;
    }
 
    /**
     * Um método público que gera números aleatórios
     */
    public double generateRandomDe0aMeio()
    {
        Random generator = new Random();
        double r = generator.nextDouble();
        return r * 0.5;
    }  
}

Classe Esforcado

public class Esforcado extends Comportamento
{
 
double dedicacao = 1.0;
double inteligencia = 0.5;
 
    /**
     * Constructor for objects of class Esforcado
     */
    public Esforcado(Aluno aluno)
    {
        super(aluno);
    }
 
    public double getDedicacao()
    {
        return dedicacao;
    }
 
    public double getInteligencia()
    {
        return inteligencia;
    }
}

Classe Imprevisivel

import java.util.*;
 
public class Imprevisivel extends Comportamento
{
    double inteligencia = 1.0;
 
    /**
     * Constructor for objects of class Imprevisivel
     */
    public Imprevisivel(Aluno aluno)
    {
        super(aluno);
    }
 
    public double getDedicacao()
    {
        return generateRandomDe0a1();
    }
 
    public double getInteligencia()
    {
        return generateRandomDe0a1();
    }
 
    /**
     * Um método público que gera números aleatórios
     */
    public double generateRandomDe0a1()
    {
        Random generator = new Random();
        double r = generator.nextDouble();
        return r;
    }  
}

Classe Pemba

import java.util.*;
 
public class Pemba extends Comportamento
{
    double inteligencia = 1.0;
 
    /**
     * Constructor for objects of class Pemba
     */
    public Pemba(Aluno aluno)
    {
        super(aluno);
    }
 
    public double getDedicacao()
    {
        return generateRandomDe0aMeio();
    }
 
    public double getInteligencia()
    {
        return generateRandomDe0aMeio();
    }
 
    /**
     * Um método público que gera números aleatórios
     */
    public double generateRandomDe0aMeio()
    {
        Random generator = new Random();
        double r = generator.nextDouble();
        return r * 0.5;
    }  
}

Classe Burro

public class Burro extends Comportamento
{
 
double dedicacao = 0.0;
double inteligencia = 0.0;
 
    /**
     * Constructor for objects of class Burro
     */
    public Burro(Aluno aluno)
    {
        super(aluno);
    }
 
    public double getDedicacao()
    {
        return dedicacao;
    }
 
    public double getInteligencia()
    {
        return inteligencia;
    }
}

Uma outra forma de resolver o problema é a criação de um método em Comportamento que atribuísse dedicação e inteligência aos alunos somente com o input do tipo, sem a necessidade de criar seis subclasses para Comportamento. Para uma posterior alteração no programa, como a inclusão de mais tipos, seria mais fácil trabalhar dessa forma que criar uma nova classe a cada novo tipo, repetindo quantidade considerável de código.

A possibilidade de incluir alunos de instituições diferentes foi implementada com a criação de três novas subclasses de Aluno, AlunoITA, AlunoUSP e AlunoUnicamp. Conforme especificações do laboratório, foram tratados alguns casos de exceção: alunos do ITA não podem ser burros; alunos da USP e da Unicamp podem ser nem Summa nem safos preguiçosos.

A seguir, os códigos dessas três subclasses de Aluno:

Classe AlunoITA

public class AlunoITA extends Aluno
{
    /**
     * Constructor for objects of class AlunoITA
     */
    public AlunoITA(String nome, RelaQueue fila)
    {
        super(nome, fila);
    }
 
    public void setComportamento (Comportamento comportamento) throws Exception 
    {
        if (comportamento instanceof Burro) throw new Exception(); //iteanos nao sao burros
        super.setComportamento(comportamento);
    }
}

Classe AlunoUSP

public class AlunoUSP extends Aluno
{    /**
     * Constructor for objects of class AlunoUSP
     */
    public AlunoUSP(String nome, RelaQueue fila)
    {
        super(nome, fila);
    }
 
    public void setComportamento (Comportamento comportamento) throws Exception 
    {
        //aluno da USP nao pode ser summa
        if (comportamento instanceof Summa) throw new Exception();
        //aluno da USP nao pode ser safo preguicoso
        if (comportamento instanceof SafoPreguicoso) throw new Exception(); 
        super.setComportamento(comportamento);
    }
}

Classe AlunoUnicamp

public class AlunoUnicamp extends Aluno
{    /**
     * Constructor for objects of class AlunoUnicamp
     */
    public AlunoUnicamp(String nome, RelaQueue fila)
    {
        super(nome, fila);
    }
 
    public void setComportamento (Comportamento comportamento) throws Exception 
    {
        //aluno da Unicamp nao pode ser summa
        if (comportamento instanceof Summa) throw new Exception();
        //aluno da Unicamp nao pode ser safo preguicoso
        if (comportamento instanceof SafoPreguicoso) throw new Exception(); 
        super.setComportamento(comportamento);
    }
}

Devido a essas alterações, a classe Simulador precisou sofrer adaptações. Seguindo as especificações, após o usuário informar a quantidade de alunos, devem ser informadas a instituição em que o aluno estuda e o comportamento desse aluno. No código, a estrutura de armazenamento das informações é bem diferente, após a utilização de Strategy. O código da nova classe Simulador está abaixo:

Classe Simulador (segunda parte)

import java.io.*;
import java.util.*;
 
public class Simulador
{
    public static void main(String[] args)
    {
        RelaQueue fila = new RelaQueue();
        Professor prof = new Professor(fila);
        Vector vetorAluno = new Vector();
        Aluno aluno;
 
        Console console = System.console();
        if(console != null)
        {
            //Criacao de quantos alunos o usuario desejar
 
            System.out.print("\nDeseja incluir quantos alunos? ");      
            Scanner scanner = new Scanner(console.reader());
            int nalunos = scanner.nextInt();
            for (int i=0; i<nalunos; i++) 
            {
                 //Leitura do nome do aluno
                 System.out.print("\nDigite o nome do aluno #"+ (i+1) +": ");
                 String nome = scanner.next();
 
                 //Selecao da instituicao onde ele estuda
                 System.out.print("\nSelecione a instituicao onde ele estuda: ");
                 System.out.println("\n 1- ITA\n 2- USP\n 3- Unicamp");
                 int instituicao = scanner.nextInt();
                 while (instituicao < 1 || instituicao > 3) {
                     System.out.print("Opcao invalida. Tente novamente: ");
                     instituicao = scanner.nextInt();
                    }
                 if (instituicao == 1) aluno = new AlunoITA(nome, fila);
                 else if (instituicao == 2) aluno = new AlunoUSP(nome, fila);
                 else aluno = new AlunoUnicamp(nome, fila);
 
                 int erro = 1;
 
                 while (erro!=0) {
 
                     //Selecao do tipo de aluno que esta sendo criado   
                     System.out.print("\nSelecione o tipo do aluno: ");
                     System.out.println("\n 1- Summa\n 2- Safo preguicoso \n 3- Esforcado");
                     System.out.println(" 4- Imprevisivel\n 5- Pemba\n 6- Burro");
                     int tipo = scanner.nextInt();
                     while (tipo < 1 || tipo > 6) {
                         System.out.print("Opcao invalida. Tente novamente: ");
                         tipo = scanner.nextInt();
                        }
 
                     switch (tipo) {
                         case 1: {
                               try {
                                    aluno.setComportamento(new Summa(aluno));
                                    erro = 0;
                                } catch (Exception e) {
                                    System.out.println("Voce tentou fazer algo impossivel!");
                                    erro = 1;
                                }
                                break;
                            }
 
                            case 2: {
                                try {
                                    aluno.setComportamento(new SafoPreguicoso(aluno));
                                    erro = 0;
                                } catch (Exception e) {
                                    System.out.println("Voce tentou fazer algo impossivel!");
                                    erro = 1;
                                }
                                break;
                            }
 
                            case 3: {
                                try {
                                    aluno.setComportamento(new Esforcado(aluno));
                                    erro = 0;
                                } catch (Exception e) {
                                    System.out.println("Voce tentou fazer algo impossivel!");
                                    erro = 1;
                                }
                                break;
                            }
 
                            case 4: {
                                try {
                                    aluno.setComportamento(new Imprevisivel(aluno));
                                    erro = 0;
                                } catch (Exception e) {
                                    System.out.println("Voce tentou fazer algo impossivel!");
                                    erro = 1;
                                }                         
                                break;
                            }
 
                            case 5: {
                                try {
                                    aluno.setComportamento(new Pemba(aluno));
                                    erro = 0;                                    
                                } catch (Exception e) {
                                    System.out.println("Voce tentou fazer algo impossivel!");
                                    erro = 1;                                    
                                }   
                                break;
                            }
 
                            case 6: {
                                try {
                                    aluno.setComportamento(new Burro(aluno));
                                    erro = 0;                                    
                                } catch (Exception e) {
                                    System.out.println("Voce tentou fazer algo impossivel!");
                                    erro = 1;                                    
                                }
                                break;
                            }
                        }
                    }
 
                 vetorAluno.addElement(aluno);
            }      
 
            //Alunos fazem e entregam o relatorio
 
            for (int i=0; i<nalunos; i++) {
             aluno = (Aluno) vetorAluno.elementAt(i);
             aluno.fazEEntregaRelatorio();                     
            }
 
            //Professor corrige os relatorios entregues
            System.out.println("\nResultado da correcao do professor: \n");     
            prof.corrigirRelatorios();
        }
        else
        {
            throw new RuntimeException("Can't run w/out a console!");
        }
    }
}

Por fim, foi construída uma fila de elementos genéricos, que permite maior flexibilização da utilização do programa - antes o limite de alunos armazenados era 10. A classe RelaQueue se tornou uma subclasse de Queue<Relatorio>, com o objetivo de manter a compatibilidade do que estava sendo utilizado anteriormente.

A seguir, os códigos das classes RelaQueue e Queue<T>:

Classe RelaQueue

public class RelaQueue extends Queue<Relatorio> {
}

Classe Queue<T>

import java.util.*;
 
public class Queue<T>{
    private Vector<T> fila  = new Vector<T>();
 
    public void queue(T elemento)
    {
        fila.add(elemento);
    }
 
    public T dequeue()
    {
        if (fila.size() == 0) return null;
        else {
                T valor = fila.firstElement();
                fila.removeElementAt(fila.lastIndexOf(valor));
                return valor;                     
            }
    }
}

Para relembrar algumas classes utilizadas no laboratório anterior que não foram modificadas nesta atividade, estão listados os códigos das classes Relatorio e Professor:

Classe Relatorio

public class Relatorio
{
    double qualidade; 
    double originalidade;  
    Aluno aluno;
 
    /**
     * Constructor for objects of class Relatorio
     */
    public Relatorio(double qualidade, double originalidade, Aluno aluno)
    {
        this.qualidade = qualidade;
        this.originalidade = originalidade;
        this.aluno = aluno;       
    }
 
    public Aluno getAluno(){
        return this.aluno;
    }
 
    public double getQualidade(){
        return this.qualidade;
    }
 
    public double getOriginalidade(){
        return this.originalidade;
    }    
 
}

Classe Professor

import java.util.*;
public class Professor
{
 
    RelaQueue queue;
 
    /**
     * Constructor for objects of class Professor
     */
    public Professor(RelaQueue queue)
    {
        this.queue = queue;
    }
 
        /**
     * Um método público que gera números aleatórios
     */
    //adaptado do exemplo "classe louca"
    public double fatorAleatorioDe0a1()
    {
        Random generator = new Random();
        double r = generator.nextDouble();
        return r;
    }    
 
    private double corrigeRelatorio(Relatorio rela)
    {
        double nota = 10*( rela.getQualidade() + rela.getOriginalidade() + this.fatorAleatorioDe0a1() ) / 3;      
        return nota;
    }
 
    public void corrigirRelatorios(){
 
        Relatorio rela = queue.dequeue();
 
        while (rela!=null) {
            System.out.println(rela.getAluno().getNome()+" : "+this.corrigeRelatorio(rela));       
            rela = queue.dequeue();
        }
    }
}

O diagrama abaixo torna mais simples a visualização da construção feita.

lab2-diagrama.JPG

Resultados obtidos

Foram realizados testes utilizando os quatro métodos fornecidos na classe de testes fornecida no roteiro. Abaixo estão mostrados os resultados obtidos.

lab2-resultados-parte2.JPG

Outros testes também foram efetuados, por meio da inserção de informações por meio do teclado. A seguir, estão listados os resultados obtidos.

lab2-resultados-parte2-2.JPG

Conclusão

Ficou clara uma das vantagens das linguagens orientadas a objeto: a reutilização de códigos. Houve classes que não tiveram quaisquer alterações para nova utilização.

A utilização de uma fila de genéricos mostrou toda a flexibilidade que a orientação a objetos permite, assim como o tratamento de exceções, que torna o código de mais fácil de alterar no futuro.

Vale observar que o aluno teve que procurar por conta própria as informações sobre a leitura por meio do teclado, visto que os links fornecidos não foram bem compreendidos.

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