- Notifications
You must be signed in to change notification settings - Fork3
serradura/dicas-de-programacao-em-ruby
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Registrar dicas de programação que surgiram por conta de uma conversa/pergunta que rolou no grupoRuby Brasil do Telegram.
Por favor registre dúvidas e/ou sugestões comoissues. 😉
Contribuições são mais que bem-vindas! 😊
A ideia deste projeto é demonstrar pequenas dicas/mudanças para aprimorar o exemplo abaixo.
Por conta disso, seguiremos a proposta original implementando o código com palavras/termos em português.
Porém, como é de conhecimento de mercado é recomendado que você pratique/desenvolva em inglês (confira alguns motivos).
classUserattr_accessor:nome,:idade,:cidadedefboasvindasputs'Seja bem-vindo ' <<nome <<'!'puts'Você quer jogar?'puts'Digite S ou N'resposta=getsifresposta.downcase[0] ==('s')jogar=trueelsejogar=falseendreturnjogarendend# Uso:user=User.newuser.nome='André'user.idade='30'user.cidade='São José do Rio Preto'ifuser.boasvindasputs'Iniciando jogo...'end
1) Use o menu dedicas:
Configurando o projeto
- Instale o Ruby (dica:rbenv)
- Instale o bundler:
gem install bundler
- Execute o bundler:
bundle install
Executando os testes
bundleexec rspec
Sugestão:
Após configurar, acesso o primeiro commitgit checkout f42f6b92
e aplique os conceitos deste guia. Feito isso, use a suite de testes para verificar se o comportamento da aplicação continua sendo o garantido.
Exemplos de boas práticas de desenvolvimento de software em Ruby + técnicas de refatoração.
400d121
Dica 1 - Interpolação🔗11445ef
Dica 2 - Use métodos privados🔗824501f
Dica 3 - Remova variáveis desnecessárias🔗f6300e9
Dica 4 - Defina métodos predicativos🔗9f8f36e
Dica 5 - Ternário🔗b7fb557
Dica 6 - Elimine a condicional quando o retorno for um boolean🔗baeb46e
Dica 7 - return é opcional quando usado na última linha de um método🔗f86e29d
Dica 8 - Use o construtor + getters (métodos somente leitura)🔗4d79c49
Dica 9 - Use keywords arguments🔗ec016e0
Dica 10 - Escreva métodos e variáveis no formato snake_case🔗66b1048
Dica 11 - Separe classes por responsabilidade (coesão)🔗b690234
Dica 12 - Organize os métodos por responsabilidade (coesão)🔗
Dica 1 [diff]
Faça uso de interpolação, é mais performático que concatenar strings.
Link para aprender mais sobre o assunto.
classUserattr_accessor:nome,:idade,:cidadedefboasvindasputs"Seja bem-vindo#{nome}!"puts'Você quer jogar um jogo?'puts'Digite S ou N'resposta=getsifresposta.downcase =='s'jogar=trueelsejogar=falseendreturnjogarendend
Dica 2 [diff]
Use métodos privados, para:
- Encapsular/esconder comportamentos
- Melhorar a legibilidade de métodos públicos
- Permitir reuso
classUserattr_accessor:nome,:idade,:cidadedefboasvindasimprime_perguntaresposta=getsreturnprosseguir_para_o_jogo(resposta)endprivatedefimprime_perguntaputs"Seja bem-vindo#{nome}!"puts'Você quer jogar?'puts'Digite S ou N'enddefprosseguir_para_o_jogo(resposta)ifresposta.downcase[0] =='s'jogar=trueelsejogar=falseendreturnjogarendend
Dica 3 [diff]
Remova variáveis caso o valor atribuído seja o último a ser retornado.(Mudança: Foi removido a variáveljogar
do métodoprosseguir_para_o_jogo
).
classUserattr_accessor:nome,:idade,:cidadedefboasvindasimprime_perguntaresposta=getsreturnprosseguir_para_o_jogo(resposta)endprivatedefimprime_perguntaputs"Seja bem-vindo#{nome}!"puts'Você quer jogar?'puts'Digite S ou N'enddefprosseguir_para_o_jogo(resposta)ifresposta.downcase[0] =='s'trueelsefalseendendend
Dica 4 [diff]
Defina métodos predicativos (terminam com?
- interrogação) quando o resultado do mesmo for umboolean
(true
oufalse
).
classUserattr_accessor:nome,:idade,:cidadedefboasvindasimprime_perguntaresposta=getsreturnprosseguir_para_o_jogo?(resposta)endprivatedefimprime_perguntaputs"Seja bem-vindo#{nome}!"puts'Você quer jogar?'puts'Digite S ou N'enddefprosseguir_para_o_jogo?(resposta)ifresposta.downcase[0] =='s'trueelsefalseendendend
Dica 5 [diff]
Use um ternário para expressar condicionais simples/curtas.
Link para aprender mais sobre o assunto.
classUserattr_accessor:nome,:idade,:cidadedefboasvindasimprime_perguntaresposta=getsreturnprosseguir_para_o_jogo?(resposta)endprivatedefimprime_perguntaputs"Seja bem-vindo#{nome}!"puts'Você quer jogar?'puts'Digite S ou N'enddefprosseguir_para_o_jogo?(resposta)resposta.downcase[0] =='s' ?true :falseendend
Dica 6 [diff]
Elimine o ternário/expressão condicional quando o retorno for um boolean.
classUserattr_accessor:nome,:idade,:cidadedefboasvindasimprime_perguntaresposta=getsreturnprosseguir_para_o_jogo?(resposta)endprivatedefimprime_perguntaputs"Seja bem-vindo#{nome}!"puts'Você quer jogar?'puts'Digite S ou N'enddefprosseguir_para_o_jogo?(resposta)resposta.downcase[0] =='s'endend
Dica 7 [diff]
Métodos sempre retornam o resultado da última linha, logo o uso de return se torna opcional/desnecessário.
classUserattr_accessor:nome,:idade,:cidadedefboasvindasimprime_perguntaresposta=getsprosseguir_para_o_jogo?(resposta)endprivatedefimprime_perguntaputs"Seja bem-vindo#{nome}!"puts'Você quer jogar?'puts'Digite S ou N'enddefprosseguir_para_o_jogo?(resposta)resposta.downcase[0] =='s'endend
Dica 8 [diff]
Faça uso do construtor + getters (métodos de leitura) para evitar que o estados do(s) seu(s) objetos se corrompa por conta de uma manipulação indevida/equivocada.
classUserattr_reader:nome,:idade,:cidadedefinitialize(nome,idade,cidade)@nome=nome@idade=idade@cidade=cidadeenddefboasvindasimprime_perguntaresposta=getsprosseguir_para_o_jogo?(resposta)endprivatedefimprime_perguntaputs"Seja bem-vindo#{nome}!"puts'Você quer jogar?'puts'Digite S ou N'enddefprosseguir_para_o_jogo?(resposta)resposta.downcase[0] =='s'endend# Uso:user=User.new('André','30','São José do Rio Preto')ifuser.boasvindasputs'Iniciando jogo...'end
Dica 9 [diff]
Faça uso de keywords arguments para tornar os argumentos/dependências de seus métodos mais expressivos.
classUserattr_reader:nome,:idade,:cidadedefinitialize(nome:,idade:,cidade:)@nome=nome@idade=idade@cidade=cidadeenddefboasvindasimprime_perguntaresposta=getsprosseguir_para_o_jogo?(resposta)endprivatedefimprime_perguntaputs"Seja bem-vindo#{nome}!"puts'Você quer jogar?'puts'Digite S ou N'enddefprosseguir_para_o_jogo?(resposta)resposta.downcase[0] =='s'endend# Uso:user=User.new(nome:'André',idade:'30',cidade:'São José do Rio Preto')ifuser.boasvindasputs'Iniciando jogo...'end
Dica 10 [diff]
Por convensão Ruby faz uso desnake_case
na declaração de métodos e variáveis, quando o mesmo contém mais de um termo. Com isso o métodoboasvindas se tornaboas_vindas.
classUserattr_reader:nome,:idade,:cidadedefinitialize(nome:,idade:,cidade:)@nome=nome@idade=idade@cidade=cidadeenddefboas_vindasimprime_perguntaresposta=getsprosseguir_para_o_jogo?(resposta)endprivatedefimprime_perguntaputs"Seja bem-vindo#{nome}!"puts'Você quer jogar?'puts'Digite S ou N'enddefprosseguir_para_o_jogo?(resposta)resposta.downcase[0] =='s'endend
Dica 11 [diff]
Separe suas classes de acordo com suas responsabilidades (que conceito elas expressam?).Isso poderá facilitar a manutenção e entendimento do código.
PS: Responsabilidade única/pouca tem haver com o que chamamos decoesão.
classUserattr_reader:nome,:idade,:cidadedefinitialize(nome:,idade:,cidade:)@nome=nome@idade=idade@cidade=cidadeendendclassGameattr_reader:userdefinitialize(user)@user=userenddefstartboas_vindas# Poderá receber mais métodos que venham fazer sentindo ao jogo/projeto...endprivatedefboas_vindasimprime_perguntaresposta=getsprosseguir_para_o_jogo?(resposta)enddefimprime_perguntaputs"Seja bem-vindo#{user.nome}!"puts'Você quer jogar?'puts'Digite S ou N'enddefprosseguir_para_o_jogo?(resposta)resposta.downcase[0] =='s'endenduser=User.new(nome:'André',idade:'30',cidade:'São José do Rio Preto')game=Game.new(user)ifgame.startputs'Iniciando jogo...'end
Dica 12 [diff]
Organize os métodos de acordo com suas responsabilidades.Assim como as classes isso poderá facilitar a manutenção e entendimento do código.
PS: Essa prática também tem haver com o que chamamos decoesão.
Mudança:
Perceba que na versão anterior, o métodoboas_vindas
tem diversas responsabilidades.Além disso, ele retorna um boolean e não aplica a convenção de predicado (nem sempre isso será necessário).
O que fizemos para melhorar?
Nessa versão o início do jogo (start), tem duas etapas:
- Começa com uma pergunta
- Processa a resposta para resolver se o mesmo será ou não iniciado.
Dada essa estrutura, criamos métodos para representar cada uma dessas etapas.
classUserattr_reader:nome,:idade,:cidadedefinitialize(nome:,idade:,cidade:)@nome=nome@idade=idade@cidade=cidadeendendclassGameattr_reader:userdefinitialize(user)@user=userenddefstartresposta=pergunta_se_deseja_jogarprosseguir_para_o_jogo?(resposta)endprivatedefpergunta_se_deseja_jogarimprime_perguntagetsenddefimprime_perguntaputs"Seja bem-vindo#{user.nome}!"puts'Você quer jogar?'puts'Digite S ou N'enddefprosseguir_para_o_jogo?(resposta)resposta.downcase[0] =='s'endend
About
Dicas para iniciantes de boas práticas de desenvolvimento de software em Ruby
Topics
Resources
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.