Lab2 Alexandre Albizzati

aluno: Alexandre Couto Albizzati
ano/sem: 2008/2o.
data do laboratório (num. da semana) : 06/08/2008 (2)

Introdução

A idéia deste lab foi ampliar o programa desenvolvido no lab1.
A primeira parte consistiu em, a partir do lab1, criar uma classe simulador, que contivesse a função main. A segunda parte foi ampliar as possibilidades para os tipos de alunos, alterando um pouco a estrutura das classes e criando uma classe Queue, para fazer o trabalho que RelaQueue fazia, porém usando tipos genéricos.
Trabalhou-se nesse lab com o tratamento de Exceções, gerando restrições no momento da criação de algumas características dos alunos.

No final foi ainda necessário ajustar a classe simulador para esta nova estrutura.

Desenvolvimento

Os tipos de aluno diferentes agora são muitos.
A classe aluno tornou-se concreta e criou-se uma classe abstrata chamada Comportamento. Esta classe admite 6 subclasses: Esforçado, SafoPreguicoso, Summa, Pemba, Burro e Imprevisivel. Dessa forma ganhamos em desacoplamento, já que Aluno apenas precisa ter um "comportamento", não sendo necessário duplicação de código.
A classe aluno ainda possui três subclasses para dizer de onde é o aluno: AlunoITA, AlunoUSP e AlunoUnicamp. Estas classes possuem algumas restrições, estabelecidas por meio do tratamento de exceções.

Pergunta: "De que outra forma você resolveria os problemas expostos acima?"
Resposta: Poderia resolver implementando interfaces. Os alunos poderiam implementar um comportamento por meio de interfaces, o que os forçaria a ter um comportamento, ao mesmo tempo que evitaria duplicação de código desnecessariamente.

As principais mudanças das classes são mostradas abaixo.
A classe Aluno deixou de ser abstrata e agora possui uma variável do tipo Comportamento. A classe Comportamento é abstrata, possuindo os dois métodos abstratos: getInteligencia() e getDediacacao().
A classe Comportamento possui 6 subclasses (já citadas) que, além de sobreescreverem os dois métodos abstratos de Comportamento, ainda possuem um construtor que apenas faz referência ao construtor de sua superclasse. Como exemplo tempos o código do contrutor da subclasse Esforcado:

public Esforcado(Aluno aluno)
    {
        super(aluno);
    }

O construtor de Comportamento é mostrado abaixo:

public Comportamento(Aluno al)
    {
        aluno = al;
    }

O construtor de Aluno:

// Construtor
    public Aluno(String nome, RelaQueue relaQueue)
    {
        this.comportamento = new Esforcado(this);
        this.nome = nome;
        this.queue = relaQueue;
    }

Dessa forma, quando aluno é criado, tem como variável de instância "comportamento", e como padrão, ela é do tipo Esforcado. O método setComportamento() permite alternar entre outros tipos. Ele é mostrado abaixo:

public void setComportamento(Comportamento comport) throws Exception
    {
        this.comportamento = comport;
    }

É importante observar ainda que Aluno possui os métodos getInteligencia() e getDedicacao(), mas no fundo estes são invocações dos métodos getInteligencia() e getDedicacao() de sua variavel comportamento:

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

A classe Aluno ainda pode ter três subclasses diferentes: AlunoITA, AlunoUSP e AlunoUnicamp.
Cada uma destas subclasses possuem restrições que foram tratadas utilizando Exception.
O código de AlunoITA é mostrado abaixo:

public class AlunoITA extends Aluno
{
 
    public AlunoITA(String nome, RelaQueue relaQueue)
    {
    super(nome,relaQueue);
    }
 
    public void setComportamento(Comportamento comportamento) throws Exception 
    {
        if(comportamento instanceof Burro) throw new Exception(); //iteanos não são burros!
        super.setComportamento(comportamento); //faz o que a superclasse Aluno faz.
    }
 
}

A classe RelaQueue tornou-se uma subclasse da nova classe Queue. A classe RelaQueue esvaziou-se e o seu conteúdo foi tranferido para a classe Queue, sofrendo algumas adaptações para lidar com o tipo genérico. O algoritmo, contudo, permaneu o mesmo. Tentei utilizar a classe Vector, mas não consegui, então optei por utilizar array.
O código da classe Queue é mostrado abaixo:

import java.util.*;
 
public class Queue<T extends Object>
{
 
    private Object[] array = new Object[10];
    private int inicio=0;
    private int fim=0;
 
        //Metodos queue e dequeue
    public void queue(T elem)
    {
        // Maximo de 10 elementos
        if((fim+1)==inicio||(fim+1)==(inicio+10))
        {
            System.out.println("Fila cheia!");
        }
        else
        {
            array[fim]=elem;
            fim = (fim + 1) % 10;
        }
    }
 
    public T dequeue()
    {
      T valor;
      valor = (T)array[inicio];
      if(inicio!=fim)
      {
      inicio = (inicio + 1) % 10;
      return valor;
      }
      else return null;
 
    }
 
    public int getInicio()
    {
      return inicio;
    }
 
    public int getFim()
    {
      return fim;
    }
}

A classe Simulador antes das alterações é mostrada abaixo:

import java.io.Console;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.IOException;
 
public class Simulador
{
    public static void main(String[] args)
    {
        Aluno[] alunos = new Aluno[20];
        Console console = System.console();
        String nome;
        String tipo;
        RelaQueue relaQueue = new RelaQueue();
        Professor professor = new Professor(relaQueue);
        int i=0;
        if(console != null)
        {
            //String name = console.readLine("Entre com o numero de alunos: ");
            String var = console.readLine("Vc deseja cadastrar novo aluno? (s/n)");
            if(var.equals("s")){
                while(var.equals("s"))
                {
                  nome = console.readLine("Entre com o nome do aluno: ");
                  tipo = console.readLine("Qual o tipo do seu aluno? 'esforcado' ou 'safopreguicoso'?");
                  if(tipo.equals("esforcado"))  alunos[i] = new AlunoEsforcado(nome,relaQueue);
                  else if(tipo.equals("safopreguicoso"))  alunos[i] = new AlunoSafoPreguicoso(nome,relaQueue);
                  alunos[i].fazEEntregaRelatorio();
                  i++;
                  var = console.readLine("Vc deseja cadastrar novo aluno? (s/n)");
                }
                professor.corrigirRelatorios();
            }
        }
    }
}

Um exemplo da execução:

testesimulador1.JPG

A classe Simulador com as alterações já implementadas é mostrada logo abaixo:

import java.io.Console;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.IOException;
 
public class Simulador
{
    public static void main(String[] args)
    {
        Aluno[] alunos = new Aluno[20];
        Console console = System.console();
        String nome;
        String instituto;
        String tipo;
        RelaQueue relaQueue = new RelaQueue();
        Professor professor = new Professor(relaQueue);
        int i=0;
        if(console != null)
        {
            //String name = console.readLine("Entre com o numero de alunos: ");
            String var = console.readLine("Vc deseja cadastrar novo aluno? (s/n)");
            if(var.equals("s")){
                while(var.equals("s"))
                {
                  nome = console.readLine("Entre com o nome do aluno: ");
                  instituto = console.readLine("Qual a instituição de seu aluno: 'ITA', 'USP' ou 'Unicamp?'");
                  if(instituto.equals("ITA")) alunos[i] = new AlunoITA(nome,relaQueue);             
                  else if(instituto.equals("USP")) alunos[i] = new AlunoUSP(nome,relaQueue);  
                  else if(instituto.equals("Unicamp")) alunos[i] = new AlunoUnicamp(nome,relaQueue);
 
                  tipo = console.readLine("Qual o tipo do seu aluno? 'esforcado', 'preguicoso', 'summa', 'pemba', 'burro' ou 'imprevisivel'?");
                  if(tipo.equals("esforcado"))
                    {
                        try
                        {
                        alunos[i].setComportamento( new Esforcado(alunos[i]) );
                        }catch (Exception e) {
                        System.out.println("Nao deveria lançar erro!");
                        }
                    }
 
                  else if(tipo.equals("preguicoso"))
                    {
                        try
                        {
                        alunos[i].setComportamento( new SafoPreguicoso(alunos[i]) );
                        }catch (Exception e) {
                        System.out.println("Soh iteanos sao safos!");
                        }
                    }
 
                  else if(tipo.equals("summa"))
                    {
                        try
                        {
                        alunos[i].setComportamento( new Summa(alunos[i]) );
                        }catch (Exception e) {
                        System.out.println("Soh iteanos sao summas!");
                        }
                    }
                  else if(tipo.equals("pemba"))
                    {
                        try
                        {
                        alunos[i].setComportamento( new Pemba(alunos[i]) );
                        }catch (Exception e) {
                        System.out.println("Nao deveria dar erro!");
                        }
                    }
                  else if(tipo.equals("burro"))
                    {
                        try
                        {
                        alunos[i].setComportamento( new Burro(alunos[i]) );
                        }catch (Exception e) {
                        System.out.println("Iteanos nao podem ser burros!");
                        }
                    }
                  else if(tipo.equals("imprevisivel"))
                    {
                        try
                        {
                        alunos[i].setComportamento( new Imprevisivel(alunos[i]) );
                        }catch (Exception e) {
                        System.out.println("Nao deveria dar erro!");
                        }
                    }                    
 
                  alunos[i].fazEEntregaRelatorio();
                  i++;
                  var = console.readLine("Vc deseja cadastrar novo aluno? (s/n)");
                }
                professor.corrigirRelatorios();
            }
        }
    }
}

É interessante observar que uma melhoria que poderia ter sido implementada no meu código é um tratamento para a situação em que o operador digita errado o tipo de aluno. (Não tratei esse tipo de erro, assumindo que o operador sempre irá digitar corretamente as entradas).
Um exemplo da execução:

simuladorfinal.JPG

O Diagrama das Classes no BlueJ ficou no final como mostrado abaixo:

diagramaclasses.JPG

Criou-se ainda a classe de testes para verificação do programa. O resultado dos testes é mostrado abaixo:

teste.JPG

Conclusão

Neste lab implementaram-se algumas idéias de padrões de projeto para aumentar o desacoplamento e a coesão entre as classes. Por causa disso, observamos que embora tenhamos aumentado bastante o código, não foi necessário alterar outros pontos como a classe Professor, por exemplo, em outras classes, graças ao desacoplamento entre elas.
Implementamos a classe Simulador, para realmente poder rodar o programa, não ficando apenas nos testes.
Utilizou-se ainda o tratamento de exceções para gerar restrições nas subclasses AlunoITA, AlunoUSP e AlunoUnicamp.
Exploramos também o uso de genéricos, gerando a classe Queue e tornando a RelaQueue uma subclasse daquela.

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