Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Pense 4 vezes antes de fazer herança

Pense 4 vezes antes de fazer herança

Herança é uma maneira de especializar um comportamento presente em nossas aplicações. Parece uma ideia muito boa, então porque será que existem tantos artigos dizendo que "herança é ruim" ou "composição é melhor que herança"?

Herança é um conceito muito poderoso e útil, que pode nos ajudar de muitas maneiras. Porém, nem sempre é a ferramenta certa para resolver o problema.

534f215d73d93dae9314db40d9746acd?s=128

Leonardo Tegon

October 11, 2019
Tweet

Transcript

  1. Pense 4 vezes antes de fazer herança Leonardo Tegon -

    TDC Recife 2019
  2. Leonardo Tegon twitter.com/tegonl github.com/tegon

  3. None
  4. Birigui

  5. None
  6. Herança

  7. Programação Orientada a Objetos

  8. Representação do mundo real

  9. class Animal def andar end def falar end end

  10. class Cachorro < Animal end class Gato < Animal end

  11. None
  12. Pense em uma fruta

  13. None
  14. None
  15. #1. Objetos devem ser modelados do ponto de vista de

    negócio
  16. None
  17. None
  18. None
  19. None
  20. None
  21. None
  22. #2. Princípio de substituição de Liskov

  23. O mesmo código que funciona com um tipo, deve funcionar

    com um subtipo
  24. passaros.each do |passaro| passaro.voar end

  25. passaros.each do |passaro| passaro.voar end => NotImplementedError: pinguins não voam

  26. passaros.each do |passaro| passaro.voar unless passaro.is_a?(Pinguim) end

  27. Mensagens que recebe e envia

  28. Forte acoplamento

  29. #3. Não deve ser somente para reutilizar código

  30. class TextField def initialize(name, size, value) @name, @size, @value =

    name, size, value end def render ... end end
  31. class TextField def initialize(name, size, value) @name, @size, @value =

    name, size, value end def render ... end end
  32. class DateField < TextField def initialize(name, size, value) super(name, size,

    format_date(value)) end def format_date(value) value.strftime("%Y-%m-%d") end end
  33. class DateField < TextField def initialize(name, size, value) super(name, size,

    format_date(value)) end def format_date(value) value.strftime("%Y-%m-%d") end end
  34. class DateField < TextField def initialize(name, size, value) super(name, size,

    format_date(value)) end def format_date(value) value.strftime("%Y-%m-%d") end end
  35. class TimeField < DateField def format_date(value) value.strftime("%T.%L") end end

  36. class TimeField < DateField def format_date(value) value.strftime("%T.%L") end end

  37. Cuidado com especializações pequenas

  38. class TimeField < DateField def format_date(value) ... end end

  39. Cuidado ao remover comportamentos

  40. class DateField < TextField def initialize(name, size, value) super(name, size,

    format_date(value)) end def format_date(value) value.strftime("%Y-%m-%d") end end
  41. class DateField < TextField def initialize(name, value) super(name, nil, format_date(value))

    end def format_date(value) value.strftime("%Y-%m-%d") end end
  42. Composição

  43. class TextField def initialize(name, size, value, formatter) @name, @size =

    name, size @value = formatter.format(value) end def render ... end end
  44. class DateFormatter def self.format(value) value.strftime("%Y-%m-%d") end end

  45. Don't repeat yourself

  46. None
  47. Don't repeat yourself?

  48. #4. The Rule of Three

  49. Três lugares ao invés de dois

  50. https://martinfowler.com/books/refactoring.html

  51. Regra não, guia

  52. Duplication is far cheaper than the wrong abstraction — Sandi

    Metz
  53. None
  54. Reconsidere a abordagem

  55. Junte seu time e converse sobre o domínio

  56. Junte seu time e converse sobre os casos de uso

  57. Deixe as coisas iguais para achar o que é diferente

  58. A chegada de uma nova feature que não encaixa na

    abstração atual é o melhor momento para refatorar
  59. Valeu! twitter.com/tegonl github.com/tegon

  60. Referências • https://thoughtbot.com/blog/reusable-oo-composition-vs-inheritance • https://medium.com/@rdsubhas/10-modern-software-engineering-mistakes-bc67fbef4fc8 • https://www.bennadel.com/blog/2483-object-thinking-by-david-west.htm • https://www.bennadel.com/blog/3108-elegant-objects-by-yegor-bugayenko.htm •

    https://www.sandimetz.com/blog/2016/1/20/the-wrong-abstraction • https://twitter.com/sandimetz/status/496627913010470912?lang=en • https://www.youtube.com/watch?v=8bZh5LMaSmE • https://www.youtube.com/watch?v=29MAL8pJImQ • https://www.youtube.com/watch?v=_f2LYPpueAY • https://www.youtube.com/watch?v=CXyNZYDO07Q
  61. Referências • https://www.deconstructconf.com/2018/sandi-metz-polly-want-a-message • https://programmingisterrible.com/post/176657481103/repeat-yourself-do-more-than- one-thing-and • https://www.thoughtworks.com/insights/blog/composition-vs-inheritance-how-choose • https://www.rubypigeon.com/posts/refactoring-inheritance-composition-data/

    • https://www.tomdalling.com/blog/software-design/ solid-class-design-the-liskov-substitution-principle/ • https://super.abril.com.br/mundo-estranho/tomate-e-fruta/ • https://en.wikipedia.org/wiki/Ruleofthree(computerprogramming) • https://en.wikipedia.org/wiki/Liskovsubstitutionprinciple • https://pt.wikipedia.org/wiki/Herança
  62. Créditos das Fotos • Olhar Angolano: https://unsplash.com/photos/95fbuDeudRg • Sergio Souza:

    https://unsplash.com/photos/gTSi041JpVc • Jason Roberts: https://unsplash.com/photos/6AQY7pO1lS0 • Ricardo Viana: https://unsplash.com/photos/-tYsPFKMm7g • Alex Ghizila: https://unsplash.com/photos/UD_j10SKj5g • Thibault Penin: https://unsplash.com/photos/3HInbCmQ8ro • Dmitry Bayer: https://unsplash.com/photos/c5Nzpjd1sn4 • Michał Parzuchowski: https://unsplash.com/photos/geNNFqfvw48 • Perry Grone: https://unsplash.com/photos/lbLgFFlADrY