-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Exercicio 8:
- Não é necessário o capitalize dentro do método
to_s(). Já estamos usando ele nos métodosname=einitialize, dessa forma ele sempre vai chegar formatado na hora doto_s(). - Podemos reaproveitar o método
name=e utilizar ele também noinitialize, dessa forma, se amanhã a gente quiser colocar um padrão deupcaseao invés decapitalizeé só alterar no métodoname=que já vai funcionar para o restante da classe. - Podemos remover o
@nos casos de leitura do valor da variável também, uma vez quehealthé umattr_readerenameumattr_accessor. No caso denamenão podemos remover o@da escrita pois estamos sobreescrevendo esse método (name=) e no caso dehealthnão podemos remover pois oattr_readersó da acesso a leitura e não a escrita.
class Player
attr_reader :health
attr_accessor :name
def initialize(new_name, health)
self.name = new_name
@health = health
end
def to_s()
"I'm #{name} with a health of #{health} and socre of #{score}."
end
def blam
@health -= 10
end
def w00t
@health += 15
puts "Player got w00ted"
end
def score
@health + name.length
end
def name=(new_name)
@name = new_name.capitalize
end
end
Exercicio 11:
- Você inicializou um game e não usou ele:
chipmunks = Game.new("Chipmunks"). Só tomar cuidado para não criarmos N instancias e não usa-las.
Exercicio 12:
- Cuidado ao copiar as mensagens de retorno. No spec
has a string representationvocê valida se a string é igual a que você retorna no métodoto_s()e esse retorno tem um erro de gramatica. Se você tivesse feito o spec sem copiar o texto de retorno (pelo erro, imagino que foi o que ocorreu), você teria visto que teria que colocarscoree nãosocreno retorno da mensagem e iria corrigir no código. Esse é o principal motivo de usarmos o rspec. Ele tem que nos ajudar a achar erros no nosso código desenvolvido. - O teste
has an initial target funding amountvocê está usando o valor 200 na mão. Poderia usar a variável@target_fundingpara garantir que se mudar o valor dessa variável o spec não quebra.
Exercicio 13:
- Seu spec
is fully fundednão faz sentido. Ele deveria retornar que o projeto está fully funded e está retornando o oposto. Nesse caso temos um spec que não serve para muita coisa. Deveriamos ter um spec que iria retornarexpect(@project).to be_fully_funded. - O método
fully_funded?poderia usar outro método já existente para saber se já completou ou não o valor que espera cada projeto. Por exemplo:
class Project
attr_reader :funding, :target_funding
attr_accessor :name
def initialize( name, funding = 0, target_funding = 1000 )
@name = name.capitalize
@funding = funding
@target_funding = target_funding
end
def to_s
"O projeto #{@name.upcase} tem investimento acumulado de R$ #{@funding} de R$ #{@target_funding} desejados. Faltam R$ #{funding_left} para o objetivo ser alcancado!"
end
def add_fund
@funding += 25
puts "O projeto #{@name.upcase} recebeu mais fundos =D."
end
def remove_fund
@funding -= 15
puts "O projeto #{@name.upcase} perdeu alguns fundos =(."
end
def funding_left
target_funding - funding
end
def name=(new_name)
@name = new_name.capitalize
end
def fully_funded?
funding_left <= 0
end
end
Dessa forma, se amanhã tiver um novo fator que altera no valor do fundo, mudamos apenas o método funding_left e o método fully_funded? continua funcionando normalmente.
- Dentro do método
Die#request_fundingnão temos necessidade de ter a variávelnumber_rolledpois não usamos ela em nenhum outro lugar. Poderia chamar diretamentecase die.rolldentro dowhen. - Seu spec passa bunitinho porque você criou o stub dele, porém seu código não está implementado. Se nesse momento rodar o código na mão, você iria ver que não funcionaria.
Exercicio 14
- Mesmas observação da variável que não é utilizada em mais de um local dentro do método
take_turn. - Você implementou a classe
Diedo fundraising porém ela foi criada sem usar oattr numberque está na classe sem utilidade nenhuma. Temos que ter muita atenção ao adicionar qualquer coisa em uma clsse. Temos que ter certeza que precisamos ou não daquilo, senão vira uma bola de neve que só cresce e a gente perde o controle. Poderia implementar essa classe igual a de cima que eu dei uma ideia diferente.
Exercicio 15
- Você poderia ter feito um método para imprimir os valores dos strings players e dos wimpies players. Repare que o puts é exatamente igual. Você poderia ter abstraido isso para um método apenas. Por exemplo:
require_relative 'player'
require_relative 'die'
require_relative 'game_turn'
class Game
attr_reader :title
def initialize(title)
@title = title
@players = []
end
def add_player(player)
@players << player
end
def play(rounds)
print_message("\n\n#{@title}'s game")
1.upto(rounds) do |round|
print_message("\nNew round: #{round}")
@players.each do |player|
GameTurn.take_turn(player)
print_message(player)
end
end
end
def print_stats
print_message("\n\n#{@title}'s Stats")
strongs, wimpies = get_strong_and_wimpies_players
print_name_and_health(strongs, 'strong')
print_name_and_health(wimpies, 'wimpy')
print_name_and_health_sorted
end
def get_strong_and_wimpies_players
@players.partition{ |player| player.strong? }
end
def print_name_and_health(players, player_type)
print_message("\n#{players.length} #{player_type} player:")
players.each { |player| print_message("#{player.name} (#{player.health})") }
end
def print_name_and_health_sorted
print_message("\n\n#{@title}'s High Scores")
@players.sort.each do |player|
print_message("#{player.name}".ljust(20, '.') + "#{player.score}")
end
end
def print_message(message)
puts(message)
end
end
Você fez algo parecido no projeto fundraising, mudei apenas algumas coisas. Coloquei o puts dentro do método responsável por printar na tela os dados pois é ele que sabe se vai usar o método puts ou se amanha vai usar algum outro, então se for mudar, muda em um método apenas. Você vai perceber que todos puts dessa classe sumiram e temos apenas 1 em apenas 1 método. Se no futuro isso começar a se repetir em várias classes, podemos criar uma classe responsável por printar os dados na tela e usar apenas 1 método em todo o projeto para printar os dados na tela. Dessa forma, se um dia a gente mudar o método que imprime na tela, mudamos apenas em um local.
Exercicio 19
- Pequena observação: podemos usar o
health.to_iao inves deInteger(health). É mais comum usar comto_i. Mas não está errado!
Exercicio 20
- Quando você coloca variáveis como
funding1fica díficil de entender o código rapidamente. Vamos sempre tentar sermos o mais claro possível na hora de dar um nome a uma variável. - O método
add_fundeadd_pledgesó muda 1 linha de código e o resto está igual. Dava para refatorar e abstrair para outro método algumas coisas né? O que acha? Algo do tipo:
require_relative 'project'
class HalfWayProject < Project
def initialize(name, funding, target_funding, extra_funding=500)
super(name,funding,target_funding)
@extra_funding = extra_funding
end
def half_way_reached?(old_funding, new_funding)
!old_funding_reached_half_way?(old_funding) && new_funding_reached_half_way?(new_funding)
end
def add_fund
old_funding = total_funds
super
give_extra_funding(old_funding)
end
def add_pledge(pledge)
old_funding = total_funds
super(pledge)
give_extra_funding(old_funding)
end
private
def give_extra_funding(old_funding)
new_funding = total_funds
if half_way_reached?(old_funding, new_funding)
@funding += @extra_funding
end
end
def old_funding_reached_half_way?(old_funding)
(old_funding >= target_funding / 2)
end
def new_funding_reached_half_way?(new_funding)
(new_funding >= target_funding/2)
end
end
Quanto mais claro ficar nosso código e quanto mais a gente não repetir o mesmo código varias e varias vezes, melhor é para todos nós!
- Sempre que a gente tiver algum método que usamos apenas dentro da classe, ou seja, não vai ser um método aberto para qualquer interface usar, vamos colocar ele dentro dos métodos privados da forma que fiz acima. Esse conceito é claro para você? Caso não seja me pergunte!
Exercicio 21
- Faltou o spec do loaded_die heim :(
- Faltou o spec do game_turn heim :(