Lab4 Yves Conselvan

aluno: Yves Conselvan
ano/sem: 2008/2o.
data do laboratório (num. da semana) : ??/??/2008 (?)

Introdução

Neste laboratorio nossa tarefa foi fazer a conversão do segundo laboratório, escrito em Java, para Ruby.

Desenvolvimento

Na conversão removi a classe RelaQueue já que Ruby tem tipagem dinâmica. Implementei o método each na classe Queue utilizando os antigos métodos has_next e next (que renomeei para prox), os métodos agora foram tornados privados. Apresento abaixo esta parte do código da classe Queue e o código da classe QueueItem.

class QueueItem
    attr_accessor :prox
    attr_reader :item
 
    @item
    @prox
 
    def initialize item
        @item = item
    end
end
 
class Queue
 
    ...
 
    def each
        while has_next
            yield prox
        end
    end
 
private
 
    def has_next
        ret = true
        if !@iterador.prox
            ret = false
            @iterador = @inicio
        end
        ret
    end
 
    def prox
        ret = @iterador.prox.item
        @iterador = @iterador.prox
        ret
    end
 
end

Na implementação dos comportamentos mantive a classe Comportamento como superclasse das demais pela forma como havia implementado reutilizando o código. Nessa conversão utilizei um hash de opções para passar as definições do comportamento para o construtor da superclasse a partir do construtor de cada tipo de comportamento. Apresento abaixo o código destas classes.

class Comportamento
    @aluno
    @inteligencia
    @dedicacao
    @inteligencia_aleatoria = false
    @dedicacao_aleatoria = false
 
    def initialize parametros
        @aluno = parametros[:aluno]
 
        @inteligencia = parametros[:inteligencia]
        @dedicacao = parametros[:dedicacao]
 
        if parametros[:inteligencia_aleatoria]
            @inteligencia_aleatoria = parametros[:inteligencia_aleatoria]
        end 
 
        if parametros[:dedicacao_aleatoria]
            @dedicacao_aleatoria = parametros[:dedicacao_aleatoria]
        end
 
    end
 
    def inteligencia
        if @inteligencia_aleatoria
            @inteligencia.to_f * rand
        else
            @inteligencia
        end
    end
 
    def dedicacao
        if @dedicacao_aleatoria
            @dedicacao * rand
        else
            @dedicacao
        end
    end
 
end
 
class Esforcado < Comportamento
    def initialize aluno
        options = {:aluno => aluno, :inteligencia => 0.5, :dedicacao => 1}
        super options
    end
end
 
class SafoPreguicoso < Comportamento
    def initialize aluno
        options = {:aluno => aluno, :inteligencia_aleatoria => false, :inteligencia => 1,
             :dedicacao_aleatoria => true, :dedicacao => 0.5}
        super options
    end
end
 
class Summa < Comportamento
    def initialize aluno
        options = {:aluno => aluno, :inteligencia => 1, :dedicacao => 1}
        super options
    end
end
 
class Burro < Comportamento
    def initialize aluno
        options = {:aluno => aluno, :inteligencia => 0, :dedicacao => 0}
        super options
    end
end
 
class Pemba < Comportamento
    def initialize aluno
        options = {:aluno => aluno, :inteligencia_aleatoria => true, :inteligencia => 0.5,
             :dedicacao_aleatoria => true, :dedicacao => 0.5}
        super options
    end
end
 
class Imprevisivel < Comportamento
    def initialize aluno
        options = {:aluno => aluno, :inteligencia_aleatoria => true, :inteligencia => 1,
             :dedicacao_aleatoria => true, :dedicacao => 1}
        super options
    end
end

A classe Relatório que apenas guarda informação ficou com o corpo muito pequeno. A inicializacao é feita no construtor e o acesso através do attr_reader

class Relatorio
    attr_reader :qualidade, :originalidade, :aluno
    @qualidade
    @originalidade
    @aluno
 
    def initialize qualidade, originalidade, aluno
        @aluno = aluno
        @qualidade = qualidade
        @originalidade = originalidade
    end
end

As classes Aluno e Professor que executam basicamente operações matematicas e acesso à propriedades tiveram seus códigos simplificados no acesso às usando attr_writer e attr_reader, e praticamente inalterados em relaçãos às operações.

Para a implementação do simulador criei a classe Sistema que no construtor cria as listas e o professor e chama o método menu. A partir do método menu mantive a estrutura utilizada no código do segundo laboratório. Na entrega de relatórios utilizei o método each da Queue. E ao final da definicao é instanciado um objeto sistema.

class Sistema
 
    ...
 
    def entrega_relatorios
        print "\nEntrega de relatorios\nAlunos na lista de alunos:\n"
        @alunos.each do |aluno|
            puts aluno.nome
            aluno.faz_e_entrega_relatorio                    
        end
    end
 
    ...
 
end
 
Sistema.new

A implementação dos testes ficou bastante parecida com o Java, com a maior alteração na forma de tratamento de exceções. O método de teste das restrições dos alunos exemplifica bem a utilização do tratamento.

class Teste < Test::Unit::TestCase
 
    ...
 
    def test_as_sub_classes_de_aluno_tem_restricoes
        queue = Queue.new() 
        alunoITA = AlunoITA.new("John Smith", queue) 
        alunoUSP = AlunoUSP.new("Mark Smith", queue) 
        alunoUnicamp = AlunoUnicamp.new("Joseph Smith", queue) 
        begin
            alunoITA.comportamento = SafoPreguicoso.new(alunoITA)
            alunoITA.comportamento = Summa.new(alunoITA)
            alunoUSP.comportamento = Burro.new(alunoUSP)
            alunoUnicamp.comportamento = Burro.new(alunoUnicamp)
        rescue
            fail("Não deveria lançar erro!") 
        end
 
        begin
            alunoITA.comportamento = Burro.new(alunoITA) 
            fail("Deveria lançar erro!") 
        rescue
        end
 
        begin
            alunoUSP.comportamento = SafoPreguicoso.new(alunoUSP)
            fail("Deveria lançar erro!") 
        rescue
        end
 
        begin
            alunoUnicamp.comportamento = Summa.new(alunoUnicamp)
            fail("Deveria lançar erro!") 
        rescue
        end
    end
 
end

Apresento abaixo a saída da execução dos testes

teste.jpg

Conclusão

Utilizar Ruby simplifica a programação, como dá para perceber pelo tamanho que o código ficou em comparação com a versão em Java.
Eu não gosto muito de usar Ruby porque acho que essa expressabilidade da linguagem, junto com a fato de ser interpretado, acabam por utilizar mal os recursos do hardware. Apesar da abundância de recursos dos hardwares atuais eu acho que o que mais importa é que quanto menos o processador chavear menos vai dissipar.

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