• Like
Object Oriented Programming
Upcoming SlideShare
Loading in...5
×

Object Oriented Programming

  • 128 views
Uploaded on

Second part of the Agile Development with Ruby on Rails course for the Computer's Science junior enterprise. …

Second part of the Agile Development with Ruby on Rails course for the Computer's Science junior enterprise.

It is shown

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
128
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
2
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. ORIENTAÇÃO AOBJETOS17 e 19 de Abrilmarcoafilho@gmail.commarcoafilho@marcoafilho
  • 2. LICENÇA
  • 3. MARCO ANTONIOFILHOCOORDENADOR DE TI INPACT.ME
  • 4. UM POUCODE RUBY
  • 5. 10 COISAS SOBRE RUBY#  1.  Tudo  eh  um  objeto  5.times  {  print  "Hello  World!"  }    #  2.  Blocos    sample_array.each  {  |element|  print  element  }    #  3.  Retorno  de  funcao  implicito    def  sum(a,b)      a  +  b  end    #  4.  Tudo  eh  aberto    class  Fixnum      def  previous          self  –  1      end  end  6.previous      #  5.  Operadores  unarios.  Nao  ha  ++,  -­‐-­‐;  Use  +=  
  • 6. 10 COISAS SOBRE RUBY#  6.  Atribuicao  paralela  a,  b  =  b,  a    #  7.  Cada  string  é  um  objeto  print  "hello".object_id  print  "hello".object_id  #  Um  novo  objeto    #  8.  Verdadeiro  e  falso  em  Ruby  if  0      print  "Hello  World"  end    #  9.  Suporte  a  faixa  de  numeros  e  expressoes  regulares  de  forma  nativa  (1..10).each  {  print  "Hello  World"  }    #  10.  Indicadores  de  metodo  class  Woman      def  loves?(thing)          thing  ==  "chocolate"  ?  true  :  false      end  end  
  • 7. APLICAÇÃO SIMPLESputs  "Welcome!  What  do  you  want  to  be?"  #  Imprime  na  tela  choice  =  gets.strip  #  Lê  do  teclado  e  remove  n    if  choice  ==  "Knight"  #  Comparacao  em  if      puts  "Then  a  princess  you  must  save"  elsif  choice  ==  "Wizard"  #  Else  if  com  condicao      puts  "Then  a  book  you  must  find"  else      puts  "Just  stay  at  home"  end    puts  "What  is  your  strength?"    choice  =  gets.to_i  #  Le  do  teclado  e  converte  para  int  damage  =  choice.times.collect  do    rand(6)  +  1  end.inject(:+)  puts  "You  did  #{damage}  damage"  #  String  com  interpolacao        
  • 8. EXERCÍCIOOBJETIVOCriar o primeiro programa em Ruby: Calculadora de dano.MÉTODO§  Crie arquivo calculator.rb;§  Leia do teclado a força e depois leia a armadura;§  Para cada unidade de força jogue um dado de seis lados. A soma é o valor de ataque;§  Para cada unidade de armadura jogue um dado de seis lados. A soma é o valor de defesa;§  A subtração do ataque com a defesa é o dano total. Apresente este resultado;§  Para executar o programa no terminal execute ruby calculator.rb15 MIN
  • 9. UM POUCODE ARQUITETURA
  • 10. MVCMODELS- Representam os modelos do sistemaCONTROLLERS- Representam as ações do sistemaVIEWS- Interfaces resultantes de açõesASSETS- Arquivos auxiliares (images, js, css)BIN- Arquivo bináriosLIB- Módulos auxiliares
  • 11. INICIALIZAÇÃO#  bin/nome_da_aplicacao.rb  libs  =  [      File.expand_path(../../lib,  __FILE__),          File.expand_path(../../app,  __FILE__)  ]  $LOAD_PATH.unshift  *Dir.glob(libs)    require  "nome_da_aplicacao"  #  lib/nome_da_aplicacao.rb  #  inicialmente  vazio  $  ruby  bin/nome_da_aplicacao.rb  Para executar faça uso do seguinte comando no terminal:
  • 12. EXERCÍCIOOBJETIVOConstruir a sua arquiteturaMÉTODO§  A partir dos conceitos dados monte a sua arquitetura MVC;§  Crie o arquivo de inicialização da aplicação;§  Crie o arquivo de gerenciamento de dependências;§  Para testar coloque um comando para escrita na tela no arquivo de dependências;§  Execute;§  Se funciona, apague a linha usada o comando de escrita na tela;5 MIN
  • 13. BATALHADE CONCEITOS
  • 14. CONCEITOS DE OOClasseAtributosMétodosCharacternamestrskillattack()defend()stringintintCharacter #2namestrskillattack()defend()James32Character #1namestrskillattack()defend()Marc24Character #3namestrskillattack()defend()Leon13INSTÂNCIAS
  • 15. CLASSESClasseAtributosMétodosDungeonnametypestringstringDungeon #2nametypeGarliaPrisonDungeon #1nametypeSyrusCastleINSTÂNCIAS
  • 16. CLASSES ESTÁTICASDiesides intself.roll()Não pode ser instanciada!Só há um dado no jogo
  • 17. MÓDULOS EM RUBY#  lib/save_the_princess/die.rb  class  Die      @@sides  =  6        #  Roll  the  die      #  You  can  change  the  amount  of  sides.  Default  is  6.      def  self.roll(sides  =  @@sides)          rand(6)  +  1      end  end  #  lib/save_the_princess.rb  require  "save_the_princess/die.rb"  Adicionar classe à lista de dependências
  • 18. INTERACTIVE RUBY$  irb  -­‐Ibin  -­‐rsave_the_princess  >  Die.roll  =>  4  Ambiente interativo para desenvolvimento e teste de comandos em Ruby
  • 19. CLASSES EM RUBY#  app/models/character.rb  class  Character      #  Character  profile  attributes      attr_accessor  :name      attr_accessor  :strength,  :skill,  :resistance,  :armor,  :fire_power            #  The  sum  of  the  amount  of  strength  die  rolls.      def  attack          strength.times.collect  do                Die.roll          end.inject(:+)      end        #  The  sum  of  the  amount  of  armor  die  rolls.      def  defend          armor.times.collect  do              Die.roll          end.inject(:+)      end  end  LEMBRE-SE DE ADICIONAR A DEPENDÊNCIA!
  • 20. INTERACTIVE RUBY$  irb  -­‐Ibin  -­‐rsave_the_princess  >  character  =  Character.new  >  character.name  =  "Marc"  >  character.name  =>  "Marc"  >  character.strength  =  3  >  character.attack  =>  15  >  character.defend  NoMethodError:  undefined  method  `times  for  nil:NilClass  #  lib/save_the_princess.rb  require  "save_the_princess/die.rb"  require  "models/character.rb"    LEMBRETE
  • 21. EXERCÍCIOOBJETIVOEscrever as classes Die e Character;MÉTODO§  Na classe Die deve existir o método self.roll representando um jogar de dados;§  Na classe Character defina os seus atributos e os métodos attack e defend;§  Execute no IRB;§  Em Character adicione um método para calcular a vida do personagem:§  O método calculate_health_points é baseado na resistência do usuário;§  É necessário guardar a vida em um atributo chamado max_health_points;30 MIN
  • 22. CONSTRUTORESclass  Character        ...      attr_accessor  :max_health_points            #  Character  constructor.  Sets  the  attributes  default  values.      def  initialize(params  =  {})          @name              =  params[:name]  ||  ""          @strength      =  params[:strength]  ||  0          @skill            =  params[:skill]  ||  0          @resistance  =  params[:resistance]  ||  0          @armor            =  params[:armor]  ||  0          @fire_power  =  params[:fire_power]  ||  0                    calculate_max_health_points      end  end  self.name  =  @name  =  ...  
  • 23. INTERACTIVE RUBY$  irb  -­‐Ibin  -­‐rsave_the_princess  >  c  =  Character.new  name:  "Marc",  strength:  2,  skill:  4,  resistance:  2  =>  #<Character:0x007fcf2210f3d0  @name="Marc",  @strength=2,  @skill=4,  @resistance=2,  @armor=0,  @fire_power=0,  @max_health_points=12>  >  c.name  =>  "Marc"  >  c.max_health_points  =  200  >  c.max_health_points  200  
  • 24. HERANÇACharacternamestrskillattack()defend()stringintintKnightslash()Priestheal()Archerfire_arrow()SUB-CLASSESINSTÂNCIAS
  • 25. HERANÇAclass  Knight  <  Character            #  Do  an  attack  with  a  bonus  of  3      def  slash          attack  +  3      end  end  $  irb  -­‐Ibin  -­‐rsave_the_princess  >  k  =  Knight.new  name:  "Marc",  strength:  2,  skill:  4,  resistance:  2  =>  #<Knight:0x007ffcf280e750  @name="Marc",  @strength=2,  @skill=4,  @resistance=2,  @armor=0,  @fire_power=0,  @max_health_points=8>  >  k.slash  =>  9  >  c  =  Character.new  name:  "James",  strength:  3,  skill:  2,  resistance:  1  =>  #<Character:0x007f93a30f90e0  @name="James",  @strength=3,  @skill=2,  @resistance=1,  @armor=0,  @fire_power=0,  @max_health_points=3>  >  c.slash  NoMethodError:  undefined  method  `slash  for  #<Character:0x007f93a30f90e0>  
  • 26. EXERCÍCIOOBJETIVOEscrever a classe Dungeon e as classes filhas de Character;MÉTODO§  Com o que já aprendeu construa a classe Dungeon, com seu nome e tipo;§  Combine com o colega ao lado quais classes filhas cada um vai escrever;§  Escreva as classes e partilhe com o seu colega;§  No arquivo de inicialização carregue um array de personagens e masmorras para disponibilizarpara a aplicação, sem ter a necessidade de criar toda vez que é inicializada.50 MIN#  bin/save_the_princess.rb  @characters  =  [Character.new  ...,  ...]  
  • 27. MODIFICADORES DE ACESSOclass  Character        ...      attr_reader  :max_health_points            private      #  Calculate  max  health  based  on  resistance.      def  calculate_max_health_points          ...      end  end  >  c  =  Character.new  name:  "James",  strength:  3,  skill:  2,  resistance:  1  =>  #<Character>  >  c.max_health_points  =  1000  NoMethodError:  undefined  method  `max_health_points=  for  #<Character>  >  c.calculate_max_health_points  NoMethodError:  private  method  `calculate_max_health_points  called  for  #<Character>  >  c.max_health_points  5  
  • 28. QUE A BATALHACOMECE!!!
  • 29. Battle...start()start_round()start_turn()COESÃO E ACOPLAMENTOfazendo mais do que deveria == baixa coesão
  • 30. Battle...start()COESÃO E ACOPLAMENTOmuitas dependências == alto acoplamentoRound...start()Turn...start()
  • 31. Battle...start()ALTA COESÃO E BAIXO ACOPLAMENTORound...start()Turn...start()Importante! Ruby não possui interfaces. É necessário implementar uma solução.OBJETIVOClasse deve fazer o que propõeClasse deve possuir o mínimo de relacionamento possível
  • 32. A BATALHAREGRAS1. Iniciativa: Joga-se um dado. Aquele que obtiver maior valor ataca primeiro. Caso igual joga-se de novo;2. Ataque: Caso seja um ataque normal, seguir para 3, senão fazer um teste de habilidade;3. Dano: A soma resultante de lances de dados equivalente à força ou poder de fogo;4. Defesa: A soma resultante de lances de dados equivalente à defesa. Valor do dano é subtraído;5. Pontos de vida: O dano que ultrapassa a soma da Armadura é subtraído de seus pontos de vida;6. Retaliação: Se ainda estiver vivo, o lutador que foi atacado revida e os passos 2 a 4 são repetidos;
  • 33. CLASSES DE COMBATE#  app/models/battle.rb  class  Battle      attr_accessor  :challenger,                                  :opponent        #  Armazena  os  combatentes      def  initialize(params  =  {})      end        #  Instancia  rodadas  até  que        #  os  pontos  de  vida  de  um        #  pesonagem  chegue  a  zero.        #  Recupera  os  combatentes.      def  start      end  end  #  app/models/battle.rb  class  Battle::Round      attr_accessor  :challenger,                                  :opponent        #  Armazena  os  combatentes      def  initialize(params  =  {})      end        #  Verifica  quem  terá  a        #  iniciativa  e  istancia        #  turnos.        def  start      end  end  #  app/models/battle.rb  class  Battle::Round::Turn      attr_accessor  :attacker,                                  :defender        #  Armazena  os  combatentes      def  initialize(params  =  {})      end        #  Calcula  o  dano  feito  em        #  combate.      def  start      end  end  
  • 34. EXERCÍCIOOBJETIVOEscrever a classe Battle e todas as suas dependências;MÉTODO§  Desenvolva as classes Turn, Round e Battle nesta ordem;30 MIN
  • 35. EXERCÍCIOOBJETIVOAdicionar class Team. Uma dungeon pode ter vários times;MÉTODO§  Desenvolver uma classe Team que tem um nome e um vetor de Characters;§  Adicione ao método initialize da Dungeon para receber times de oponentes como parâmetro;§  Crie um método visit para Team que receba uma Dungeon como parâmetro;§  Nesse método os oponentes presentes naquela dungeon devem ser enfrentados;§  O vencedor será a batalha entre o primeiro do time 1 luta contra o primeiro do time 2;2 HORAS
  • 36. BOASPRÁTICAS
  • 37. DON’T REPEAT YOURSELF (DRY)#  app/models/character.rb  class  Character      ...            #  The  sum  of  the  amount  of  strength  die  rolls.      def  attack          [strength,  fire_power].max.times.collect  do                Die.roll          end.inject(:+)      end        #  The  sum  of  the  amount  of  armor  die  rolls.      def  defend          armor.times.collect  do              Die.roll          end.inject(:+)      end  end  
  • 38. DON’T REPEAT YOURSELF (DRY)#  app/models/character.rb  class  Character      ...            #  The  sum  of  the  amount  of  strength  die  rolls.      def  attack          roll_die_for  [strength,  fire_power].max      end        #  The  sum  of  the  amount  of  armor  die  rolls.      def  defend          roll_die_for  armor      end        protected      def  roll_die_for(attribute)          attribute.times.map{  Die.roll  }.inject(:+)      end  end  
  • 39. CharacterCONVENTION OVER CONFIGURATIONcharacter.rb charactersNome de arquivo Nome de classe Nome de tabela§  ClassesEmCamelCase;§  variaveis_e_funcoes_sempre_minusculas;§  CONSTANTES_SEMPRE_MAIUSUCLAS;
  • 40. DOCUMENTERDOCDocumentar a aplicação em Ruby é simples:$  rdoc  -­‐-­‐all  Parsing  sources...  100%  [12/12]    UTF-­‐8                                                                                                                            Generating  Darkfish  format  into  /Users/marco/Projects/Rails/save-­‐the-­‐princess/doc...  Files:            12  Classes:        10  (10  undocumented)  Modules:          1  (  1  undocumented)  Constants:      1  (  1  undocumented)  Attributes:  21  (20  undocumented)  Methods:        38  (33  undocumented)  Total:            71  (65  undocumented)      8.45%  documented  Elapsed:  0.8s  
  • 41. EXERCÍCIOOBJETIVORefatorar a classe Battle e seus sub-módulos;MÉTODO§  Simplificar as funções das classes criando classes mais específicas;§  Garantir que a classe funciona da mesma forma;§  Gere a documentação do seu projeto com RDoc;1 HORA
  • 42. EXERCÍCIOOBJETIVOClasse Battle deve prover batalhas entre times;MÉTODO§  Alterar a classe Battle para receber dois times (ao invés de characters);§  Para cada personagem no time desafiante (challenger) deve ser feita uma rodada escolhendo uminimigo aleatório, assim como, o time desafiado (opponent) deve ter uma rodada para cadaintegrante escolhendo um adversário aleatório;§  Tente fazer o mínimo de alterações nas classes Turn e Round;4 HORAS#  Dica  @challengers.each  do  |challenger|      Round.new  challenger:  challenger,  opponent:  @opponents.shuffle[0]  end  
  • 43. DÚVIDAS?? ????????? ?
  • 44. MUITO OBRIGADO!marcoafilho@gmail.commarcoafilho@marcoafilho