aluno: Igor de Sousa Almeida
ano/sem: 2008/2o.
data do laboratório (num. da semana) : 20/08/2008 (4)
Introdução
Utilizando do projeto realizado no último laboratório, foi realizada uma extensão do mesmo, com a criação de novas subclasses de alunos dependendo com a sua Universidade e uma divisão de seus comportamentos em uma nova classe separada.
Devido ao grande número de classes novas, o projeto foi divido em diversos pacotes para uma maior organização do mesmo. Dessa forma, foram criados três pacotes, comportamentos, com as subclasses de Comportamento, alunos, com as subclasses de Aluno e o restante das classes foram colocadas num pacote geral.

Figura 1: Divisão de pacotes no projeto.
Desenvolvimento
1. Criação da classe Simulador:
Foi criada uma classe simulador para o projeto do 1° laboratório. Esse Simulador permite inserir um número de alunos, sendo eles esforçados ou safos preguiçosos, e depois faz com que eles produzam relatórios os quais são corrigidos e mostrados na tela para o operador.
Classe Simulador:
import javax.swing.JOptionPane; public class Simulador { public static void main(String[] Args) { int n, al; String nome; boolean erro; do { try { erro = false; n = Integer.parseInt(JOptionPane.showInputDialog("Quantos alunos vc deseja inserir?")); RelaQueue queue = new RelaQueue(); Professor prof = new Professor(queue); Aluno[] arrayalunos = new Aluno[n]; for(int i = 0; i < n;i++) { nome = JOptionPane.showInputDialog("Digite o nome do aluno"); do { try { erro = false; al = Integer.parseInt(JOptionPane.showInputDialog("O aluno e safo preguicoso(0) ou e esforcado(1)?")); if(al == 1) arrayalunos[i] = new AlunoEsforcado(nome,queue); else if(al == 0) arrayalunos[i] = new AlunoSafoPreguicoso(nome,queue); }catch(NumberFormatException ex){erro = true;} }while(erro == true); } for(int i = 0; i < n; i++) { arrayalunos[i].fazEEntregaRelatorio(); } System.out.println("Alunos fazem e entregam relatorios..."); System.out.println("Correcao do professor:"); prof.corrigirRelatorios(); }catch(NumberFormatException ex){erro = true;} }while(erro == true); } }

Figura 2: Esquema do 1° laboratório com a adição do Simulador.




Figura 3: Teste realizado.
2. Alteração nos Alunos:
Para criar diferentes tipos de Aluno (variando com a sua Universidade de origem) foi decidido separarar o comportamento do aluno (safo preguiçoso, esforçado) em uma nova classe abstrata Comportamento, que possui os métodos abstratos getInteligencia() e getDedicacao(). A partir daí, também criamos novos tipos de comportamento, Burro, Pemba, Imprevisivel e Summa cada um com as suas inteligencia e dedicacao características. Além disso, Aluno deixa de ser uma classe abstrata e é criado o método setComportamento para que o comportamento do aluno seja escolhido.
Classe Aluno alterada:
package geral;
import comportamentos.Esforcado;
import comportamentos.*;
public class Aluno
{
String nome;
RelaQueue queue;
int conhecimento = 0;
Comportamento comportamento;
public Aluno(String nome, RelaQueue queue){
this.nome = nome;
this.queue = queue;
this.comportamento = new Esforcado(this);
}
public void fazEEntregaRelatorio(){
this.getConhecimento();
double qualidade = (2 * this.getDedicacao() + 1 * comportamento.getInteligencia() ) / 3 ;
double originalidade = (1 * this.getDedicacao() + 2 * comportamento.getInteligencia() ) / 3 ;
Relatorio rela = new Relatorio(qualidade,originalidade,this);
queue.queue(rela);
}
public void getConhecimento(){
conhecimento = conhecimento + 1;
}
public double getInteligencia(){
return comportamento.getInteligencia();
}
public double getDedicacao(){
return comportamento.getDedicacao();
}
public String getNome(){
return nome;
}
public void setComportamento(Comportamento comportamento) throws Exception{
this.comportamento = comportamento;
}
}
Classe abstrata Comportamento:
package geral;
import geral.Aluno;
public abstract class Comportamento
{
private Aluno aluno;
public Comportamento(Aluno aluno){
this.aluno = aluno;
}
public abstract double getInteligencia();
public abstract double getDedicacao();
}
Subclasse Esforcado:
package comportamentos;
import geral.*;
import geral.Aluno;
public class Esforcado extends Comportamento
{
double inteligencia = 0.5;
double dedicacao = 1;
public Esforcado(Aluno aluno){
super(aluno);
}
public double getInteligencia(){
return inteligencia;
}
public double getDedicacao(){
return dedicacao;
}
}
Subclasse Burro:
package comportamentos;
import geral.*;
import geral.Aluno;
public class Burro extends Comportamento
{
double inteligencia = 0;
double dedicacao = 0;
public Burro(Aluno aluno){
super(aluno);
}
public double getInteligencia(){
return inteligencia;
}
public double getDedicacao(){
return dedicacao;
}
}
Subclasse Pemba:
package comportamentos;
import geral.*;
import geral.Aluno;
public class Pemba extends Comportamento
{
public Pemba(Aluno aluno){
super(aluno);
}
public double getInteligencia(){
double r = Math.random();
return r * 0.5;
}
public double getDedicacao(){
double r = Math.random();
return r * 0.5;
}
}
Subclasse Imprevisivel:
package comportamentos;
import geral.*;
import geral.Aluno;
public class Imprevisivel extends Comportamento
{
public Imprevisivel(Aluno aluno){
super(aluno);
}
public double getInteligencia(){
double r = Math.random();
return r;
}
public double getDedicacao(){
double r = Math.random();
return r;
}
}
Subclasse SafoPreguicoso:
package comportamentos;
import geral.*;
import geral.Aluno;
public class SafoPreguicoso extends Comportamento
{
double inteligencia = 1;
public SafoPreguicoso(Aluno aluno){
super(aluno);
}
public double getInteligencia(){
return 1;
}
public double getDedicacao(){
double r = Math.random();
return r * 0.5;
}
}
Subclasse Summa:
package comportamentos;
import geral.*;
import geral.Aluno;
public class Summa extends Comportamento
{
double inteligencia = 1;
double dedicacao = 1;
public Summa(Aluno aluno){
super(aluno);
}
public double getInteligencia(){
return inteligencia;
}
public double getDedicacao(){
return dedicacao;
}
}

Figura 4: Pacote de comportamentos.
3. Alunos de instituições diferentes:
Extendeu-se a classe Aluno em três classes AlunoITA, AlunoUSP e AlunoUnicamp. Essas classes diferenciam a partir de exceções nos seus tipos de comportamentos. Um AlunoITA não pode ter um comportamento Burro e um AlunoUSP ou um AlunoUnicamp não podem ter comportamentos SafoPreguicoso e Summa. A exceção de setComportamento que foi colocada na Classe Aluno alterada é especificada abaixo nos códigos das subclasses.
Subclasse AlunoITA:
package alunos;
import geral.Aluno;
import comportamentos.Burro;
import geral.*;
public class AlunoITA extends Aluno
{
public AlunoITA(String nome, RelaQueue queue)
{
super(nome,queue);
}
public void setComportamento(Comportamento comportamento) throws Exception
{
if(comportamento instanceof Burro) throw new Exception("Um iteano n pode ser burro!");
super.setComportamento(comportamento);
}
}
Subclasse AlunoUSP:
package alunos;
import geral.Aluno;
import comportamentos.Summa;
import geral.*;
public class AlunoUSP extends Aluno
{
public AlunoUSP(String nome, RelaQueue queue)
{
super(nome,queue);
}
public void setComportamento(Comportamento comportamento) throws Exception
{
if(comportamento instanceof Summa || comportamento instanceof SafoPreguicoso) throw new Exception("Somente um iteano pode ser summa ou safo preguicoso!");
super.setComportamento(comportamento);
}
}
Subclasse AlunoUnicamp:
package alunos;
import geral.*;
import comportamentos.Summa;
import geral.Aluno;
public class AlunoUnicamp extends Aluno
{
public AlunoUnicamp(String nome, RelaQueue queue)
{
super(nome,queue);
}
public void setComportamento(Comportamento comportamento) throws Exception
{
if(comportamento instanceof Summa || comportamento instanceof SafoPreguicoso) throw new Exception("Somente um iteano pode ser summa ou safo preguicoso!");
super.setComportamento(comportamento);
}
}

Figura 5: Pacote de alunos.
4. Alteração do Simulador:
O Simulador teve que ser alterado para englobar as novas classes inseridas.
Classe Simulador modificada:
package geral;
import alunos.AlunoUnicamp;
import comportamentos.*;
import alunos.AlunoUSP;
import geral.Aluno;
import alunos.AlunoITA;
import javax.swing.JOptionPane;
public class Simulador
{
public static void main(String[] Args)
{
Integer i, n, origem, comportamento;
String nome;
boolean erro = false, erro2 = false;
do{
try{
erro = false;
n = Integer.parseInt(JOptionPane.showInputDialog("Quantos alunos vc deseja inserir?"));
RelaQueue queue = new RelaQueue();
Professor prof = new Professor(queue);
Aluno[] arrayalunos = new Aluno[n];
for(i = 0; i < n;i++)
{
nome = JOptionPane.showInputDialog("Digite o nome do aluno");
do
{
try
{
erro = false;
origem = Integer.parseInt(JOptionPane.showInputDialog("Digite a origem do aluno:\nITA(0) \nUSP(1) \nUnicamp(2)"));
if(origem == 0) arrayalunos[i] = new AlunoITA(nome,queue);
else if(origem == 1) arrayalunos[i] = new AlunoUSP(nome,queue);
else if(origem == 2) arrayalunos[i] = new AlunoUnicamp(nome,queue);
}catch(NumberFormatException ex){
erro = true;
JOptionPane.showMessageDialog(null, "Numero invalido para a origem!");
}
}while(erro == true);
do
{
try
{
erro = false; erro2 = false;
comportamento = Integer.parseInt(JOptionPane.showInputDialog("Digite o comportamento do aluno:\nEsforcado(0) \nPemba(1) \nImprevisivel(2) \nSafo(3) \nBurro(4) \nSumma(5)"));
if(comportamento == 0) arrayalunos[i].setComportamento(new Esforcado(arrayalunos[i]));
else if(comportamento == 1) arrayalunos[i].setComportamento(new Pemba(arrayalunos[i]));
else if(comportamento == 2) arrayalunos[i].setComportamento(new Imprevisivel(arrayalunos[i]));
else if(comportamento == 3) arrayalunos[i].setComportamento(new SafoPreguicoso(arrayalunos[i]));
else if(comportamento == 4) arrayalunos[i].setComportamento(new Burro(arrayalunos[i]));
else if(comportamento == 5) arrayalunos[i].setComportamento(new Summa(arrayalunos[i]));
}catch(NumberFormatException ex){
erro = true;
JOptionPane.showMessageDialog(null, "Numero invalido para o comportamento!");
}
catch(Exception e){
JOptionPane.showMessageDialog(null,e.fillInStackTrace());
erro2 = true;
}
}while(erro == true || erro2 == true);
}
for(i = 0; i < n; i++)
{
arrayalunos[i].fazEEntregaRelatorio();
}
JOptionPane.showMessageDialog(null, "Alunos fazem e entregam relatorios...");
prof.corrigirRelatorios();
}catch(NumberFormatException ex){
erro = true;
JOptionPane.showMessageDialog(null,"Numero de alunos invalido!");
}
}while(erro == true);
}
}









Figura 6: Teste do simulador modificado.
5. Criação de uma classe Queue com genéricos:
Através de genéricos, modificou-se a classe Queue de uma forma que ela serve para qualquer tipo de objeto. Escolheu-se por usar a classe ArrayList para a implementação dessa nova Queue. A classe RelaQueue é uma extensão da classe Queue, que aceita apenas relatórios como entradas.
Classe Queue com genéricos:
package geral;
import java.util.ArrayList;
public class Queue<T>{
private ArrayList array = new ArrayList();
public void queue(T elem){
array.add(elem);
}
public T dequeue(){
T valor;
if(array.isEmpty()){
System.out.println("Fim dos relatórios!");
valor = null;
}
else{
valor = (T) array.get(0);
array.remove(valor);
}
return valor;
}
}
Subclasse RelaQueue:
package geral;
public class RelaQueue extends Queue<Relatorio> {
}

Figura 7: Pacote geral.
6. Rodando as Classes de Teste:
Foi criada uma Unit Test chamada Testar para implementar os testes.
import geral.*;
import alunos.*;
import comportamentos.*;
public class Testar extends junit.framework.TestCase
{
public void testFuncionaComoOLab1() {
//criando os objetos
RelaQueue queue = new RelaQueue();
Professor prof = new Professor(queue);
// O que muda em termos de interface externa neste lab,
// é a criação dos alunos. O que mostra que o nosso código
// está bem desacoplado e a nossa refatoração não alterou
// o funcionamento dos outros objetos (Professor, Relatório, etc).
Aluno aluno1 = new Aluno("John Smith", queue);
Aluno aluno2 = new Aluno("Mark Smith", queue);
Aluno aluno3 = new Aluno("Joseph Smith", queue);
Aluno aluno4 = new Aluno("Robert Smith", queue);
try {
aluno3.setComportamento( new SafoPreguicoso(aluno3) );
aluno4.setComportamento( new SafoPreguicoso(aluno4) );
} catch (Exception e) {
fail("Não deveria lançar erro!");
}
//teste de alunoesforcado
assertEquals(0.5, aluno1.getInteligencia(), 0.01);
assertEquals(1, aluno1.getDedicacao(), 0.01);
//teste de alunosafo
assertEquals(1.0, aluno3.getInteligencia(), 0.01);
assertTrue(aluno3.getDedicacao() != aluno3.getDedicacao()); //deve ser randomica
assertTrue(aluno3.getDedicacao() < 0.5);
//alunos comecam a fazer os relas
aluno1.fazEEntregaRelatorio();
//roubamos o relatório do primeiro aluno para investigá-lo
Relatorio rela1 = queue.dequeue();
assertEquals(aluno1, rela1.getAluno());
assertTrue(rela1.getAluno().getNome().equals("John Smith"));
assertTrue(rela1.getQualidade() < 0.9);
assertTrue(rela1.getQualidade() > 0.8);
assertTrue(rela1.getOriginalidade() < 0.7);
assertTrue(rela1.getOriginalidade() > 0.6);
//os outros continuam a fazer os relas
aluno2.fazEEntregaRelatorio();
aluno3.fazEEntregaRelatorio();
aluno4.fazEEntregaRelatorio();
//deve exibir a coreção dos relas dos aluno2, aluno3, e aluno4, nesta ordem
//pois "roubamos" o relatório do aluno1
prof.corrigirRelatorios();
}
public void testOsComportamentosFuncionamComoEspecificado() {
RelaQueue queue = new RelaQueue();
Aluno aluno1 = new Aluno("John", queue);
Comportamento summa = new Summa(aluno1);
Comportamento pemba = new Pemba(aluno1);
Comportamento imprevisivel = new Imprevisivel(aluno1);
Comportamento safo = new SafoPreguicoso(aluno1);
Comportamento esforcado = new Esforcado(aluno1);
Comportamento burro = new Burro(aluno1);
//teste de esforcado
assertEquals(0.5, esforcado.getInteligencia(), 0.01);
assertEquals(1, esforcado.getDedicacao(), 0.01);
//teste de burro
assertEquals(0.0, burro.getInteligencia(), 0.01);
assertEquals(0.0, burro.getDedicacao(), 0.01);
//teste de summa
assertEquals(1.0, summa.getInteligencia(), 0.01);
assertEquals(1.0, summa.getDedicacao(), 0.01);
//teste de safo
assertEquals(1.0, safo.getInteligencia(), 0.01);
assertTrue(safo.getDedicacao() != safo.getDedicacao()); //deve ser randomica
assertTrue(safo.getDedicacao() < 0.5);
//teste de imprevisivel
assertTrue(imprevisivel.getInteligencia() != imprevisivel.getInteligencia()); //deve ser randomica
assertTrue(imprevisivel.getInteligencia() < 1.0);
assertTrue(imprevisivel.getDedicacao() != safo.getDedicacao()); //deve ser randomica
assertTrue(imprevisivel.getDedicacao() < 1.0);
//teste de pemba
assertTrue(pemba.getInteligencia() != pemba.getInteligencia()); //deve ser randomica
assertTrue(pemba.getInteligencia() < 0.5);
assertTrue(pemba.getDedicacao() != pemba.getDedicacao()); //deve ser randomica
assertTrue(pemba.getDedicacao() < 0.5);
}
public void testAsSubClassesDeAlunoTemRestricoes() {
RelaQueue queue = new RelaQueue();
AlunoITA alunoITA = new AlunoITA("John Smith", queue);
AlunoUSP alunoUSP = new AlunoUSP("Mark Smith", queue);
AlunoUnicamp alunoUnicamp = new AlunoUnicamp("Joseph Smith", queue);
try {
alunoITA.setComportamento( new SafoPreguicoso(alunoITA) );
alunoITA.setComportamento( new Summa(alunoITA) );
alunoUSP.setComportamento( new Burro(alunoUSP) );
alunoUnicamp.setComportamento( new Burro(alunoUnicamp) );
} catch (Exception e) {
fail("Não deveria lançar erro!");
}
try {
alunoITA.setComportamento( new Burro(alunoITA) );
fail("Deveria lançar erro!");
} catch (Exception e) {
}
try {
alunoUSP.setComportamento( new SafoPreguicoso(alunoUSP) );
fail("Deveria lançar erro!");
} catch (Exception e) {
}
try {
alunoUnicamp.setComportamento( new Summa(alunoUnicamp) );
fail("Deveria lançar erro!");
} catch (Exception e) {
}
}
public void testRelaQueueEhSubclasseDoGenericoQueue() {
Queue<Relatorio> q = new RelaQueue(); //propriedade básica do polimorfismo
}
}
Figura 8: Resultado das classes de testes.
Conclusão
Os conceitos novos envolvidos na produção desse laboratório foram a utilização de exceções e genéricos. Além disso também foi utilizado pela primeira vez, em Java, dispositivos para inserção de dados e uma interface com o operador.





