Lab5 Leandro Lima

aluno: Leandro Lima
ano/sem: 2008/2o.
data do laboratório (num. da semana) : 21/12/2008

Introdução

Nesse lab5, foi desenvolvida uma aplicação utilizando a linguagem Ruby e explorando diversos aspectos de sua implementação. Para tal, a atividade desenvolvida foi a de um bolão virtual, onde usuários fazem suas apostas em resultados de jogos de futebol.

Desenvolvimento

Foram feitos os decorators de Thread Safety, os de Persistência e os Builders. As demais etapas não puderam ser completadas a tempo. As implementações visaram eliminar condições de múltiplas threads, entre outras causas, que pudessem gerar situações indesejadas.

Decorators de Thread Safety

MatchThreadSafeDecorator

Com esse Decorator, iremos decorar os métodos make_bet e finalize de Match para evitar que alterações no conteúdo das suas instâncias provoquem condições de corrida.

require 'decorators/decorator'
 
module Decorators
# Objetivo: decorar os métodos make_bet e finalize
  class MatchThreadSafeDecorator < Decorator
 
    include MonitorMixin
 
    def make_bet(score, user)
      synchronize do
        @decorated.make_bet(score, user)
      end
    end
 
    def finalize(final_score)
      synchronize do
        @decorated.finalize(final_score)
      end
    end
 
  end

MatchListThreadSafeDecorator

Com esse Decorator, foi implementada uma solução para decorar MatchList de forma a permitir que o método add construa Matchs decorados, levando em conta as condições de Thread Safety.

require 'decorators/decorator'
module Decorators
 
  class MatchListThreadSafeDecorator < Decorator
 
    def initialize(decorated)
      old_match_decorator = decorated.item_decorator
      decorated.item_decorator = lambda do |match|
        MatchThreadSafeDecorator.new( old_match_decorator.call(match) )
      end
      super
    end
 
    def add(name, end_time)
    synchronize do
        match = @decorated.add(name, end_time)
    end
      match
    end
  end
end

Decorators de Persistência

Agora, estaremos implementando decorators para utilizar os métodos save e load_list em MatchPersistanceDecorator e add em MatchListPersistanceDecorator. Foi necessário armazenar uma referência ao objeto MatchList decorado, para conseguir chamar seu método save.

MatchPersistanceDecorator

require 'decorators/decorator'
module Decorators
 
  class MatchPersistanceDecorator < Decorator
 
    def initialize(decorated_obj, list)
      super(decorated_obj)
      @match_list = list
    end
 
    def make_bet(score, user)
      aposta = @decorated.make_bet(score, user)
      @match_list.save
      return aposta
    end
 
    def finalize(final_score)
      placar = @decorated.finalize(final_score)
      @match_list.save
      return placar
    end
 
  end
end

MatchListPersistanceDecorator

Em seguida, criamos a classe MatchListPersistanceDecorator para fazer com que o método add crie matches decorados.

require 'decorators/decorator'
module Decorators
  class MatchListPersistanceDecorator < Decorator
    def initialize(decorated)
      old_match_decorator = decorated.item_decorator
      decorated.item_decorator = lambda do |match|
        MatchListThreadSafeDecorator.new( old_match_decorator.call(match) )
      end
      super
    end
end
end

Builders para UserList e MatchList com os Decorators

Com o padrão Builder visto em aula, iremos construir instâncias com os padrões decorados a serem escolhidos.

MatchListBuilder

class MatchListBuilder
 
  def add_persistance
    @match_list = MatchListPersistanceDecorator.new(@decorated)
    @added_persistance = true
  end
 
  def add_logging
    @match_list = MatchListLoggerDecorator.new(@decorated)
  end
 
  def add_thread_safety
    @match_list = MatchListThreadSafeDecorator.new(@decorated)
  end
 
  def add_all
    @match_list = MatchListPersistanceDecorator.new(@decorated)
    @match_list = MatchListLoggerDecorator.new(@decorated)
    @match_list = MatchListThreadSafeDecorator.new(@decorated)
    @added_persistance = true
  end
 
  def match_list
    @match_list.load_list if @added_persistance
    @match_list
  end
 
end

UserListBuilder

class UserListBuilder
 
  def add_persistance
    @user_list = ListPersistanceDecorator.new(@decorated)
    @added_persistance = true
  end
 
  def add_logging
    @user_list = UserListLoggerDecorator.new(@decorated)
  end
 
  def add_thread_safety
    @user_list = ListThreadSafeDecorator.new(@decorated)
  end
 
  def add_all
    @user_list = ListPersistanceDecorator.new(@decorated)
    @user_list = UserListLoggerDecorator.new(@decorated)
    @user_list = ListThreadSafeDecorator.new(@decorated)
    @added_persistance = true
  end
 
  def user_list
    @user_list.load_list if @added_persistance
    @user_list
  end
 
end

Conclusão

Nesse laboratório, pudemos ver a importância da linguagem Ruby na solução de problemas envolvendo padrões de projetos, com a exemplificação do bolão virtual. O uso do padrão Builder foi explorado, fazendo com que sejam escolhidos os decorators das instâncias. A referência à persistência de dados também foi abordada, fazendo com que também seja levado em conta esse aspecto, já que os dados recuperados tem de ser consistentes com os gravados. As implementações dos Decorators tiveram como finalidade facilitar a formação de instâncias com características específicas dentre uma seleção. Numa aplicação envolvendo múltiplas threads, é essencial que não haja conflito entre os pedidos e, para tal, as classes criadas foram de vital importância.

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