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

Git Driven Refactoring

Git Driven Refactoring

Often we know that our code needs refactoring, but we have no idea where to start. Maybe we studied some common code smells and learned about the things that we should be avoiding, but memorizing the rules doesn’t automatically lead to fixing all problems. In this talk, we explore how you can use Git to recognize and address violations to each of the SOLID principles. Using diffs, commit history and pull requests you can learn to recognize patterns in code that point to problems. These same tools can help you correct those issues and write more maintainable code.

Ashley Ellis Pierce

November 15, 2017
Tweet

More Decks by Ashley Ellis Pierce

Other Decks in Programming

Transcript

  1. Git Driven
    Refactoring

    View Slide

  2. Ashley Ellis Pierce

    Application Engineer @ GitHub
    @aellispierce

    View Slide

  3. Refactoring?

    View Slide

  4. Changing the structure of
    existing code without
    modifying it’s behavior

    View Slide

  5. We make mistakes

    View Slide

  6. Where we
    went wrong ->
    Where we need to be

    View Slide

  7. Design problem ->
    Refactoring
    technique

    View Slide

  8. Design problem ->
    Refactoring
    technique

    View Slide

  9. View Slide

  10. S.O.L.I.D

    principles

    View Slide

  11. S.O.L.I.D

    Single Responsibility Principle

    View Slide

  12. Single Responsibility Principle
    A class should have only one
    reason to change.


    View Slide

  13. S.O.L.I.D

    Single Responsibility Principle
    Open/Closed Principle

    View Slide

  14. Open/Closed Principle
    A class should be open for
    extension but closed for
    modification.


    View Slide

  15. S.O.L.I.D

    Single Responsibility Principle
    Open/Closed Principle
    Liskov Substitution Principle

    View Slide

  16. Liskov Substitution Principle
    Every subclass/derived class
    should be substitutable for their
    base/parent class.


    View Slide

  17. S.O.L.I.D

    Single Responsibility Principle
    Open/Closed Principle
    Liskov Substitution Principle
    Interface Segregation Principle

    View Slide

  18. Interface Segregation Principle
    No client should be forced to
    depend on methods it does not
    use.

    View Slide

  19. S.O.L.I.D

    Single Responsibility Principle
    Open/Closed Principle
    Liskov Substitution Principle
    Interface Segregation Principle
    Dependency Inversion Principle

    View Slide

  20. Dependency Inversion Principle
    Entities must depend on
    abstractions, not concretions.

    View Slide

  21. Easier to understand
    Easier to change.
    SOLID code is:

    View Slide

  22. We’re done!

    View Slide

  23. … not quite.
    We’re done!

    View Slide

  24. View Slide

  25. View Slide

  26. View Slide

  27. View Slide

  28. View Slide

  29. You can’t recognize
    design patterns in
    isolation, you need
    context.

    View Slide

  30. View Slide

  31. S.O.L.I.D

    principles

    View Slide

  32. Single
    Responsibility
    Principle

    View Slide

  33. Single Responsibility Principle
    A class should have only one
    reason to change.


    View Slide

  34. View Slide

  35. Why has my class changed recently?

    View Slide

  36. View Slide

  37. git log app/models/engine.rb

    View Slide

  38. View Slide

  39. View Slide

  40. View Slide

  41. View Slide

  42. View Slide

  43. View Slide

  44. View Slide

  45. git log app/models/engine.rb

    View Slide

  46. git log app/models/engine.rb

    View Slide

  47. Power Remote Start

    View Slide

  48. git log app/models/engine.rb

    View Slide

  49. View Slide

  50. Git as documentation

    View Slide

  51. Git as documentation

    View Slide

  52. git log app/models/engine.rb

    View Slide

  53. Open/Closed

    Principle

    View Slide

  54. Open/Closed Principle
    A class should be open for
    extension but closed for
    modification.


    View Slide

  55. How do you extend something
    without modifying it?

    View Slide

  56. View Slide

  57. You’re doing amazing sweetie

    View Slide

  58. View Slide

  59. View Slide

  60. You shouldn’t have to change
    existing code to add new
    functionality

    View Slide

  61. When adding features,
    there should be no red in
    the diffs

    View Slide

  62. View Slide

  63. Consistent style matters

    View Slide

  64. View Slide

  65. Liskov

    Substitution

    Principle

    View Slide

  66. Liskov Substitution Principle
    Every subclass/derived class
    should be substitutable for their
    base/parent class.


    View Slide

  67. You should be able to call the
    same method on a subclass as
    you could on a parent and get a
    compatible result

    View Slide

  68. View Slide

  69. View Slide

  70. is_a?
    respond_to?

    View Slide

  71. View Slide

  72. Let bots do the nagging
    for you.

    View Slide

  73. View Slide

  74. Interface

    Segregation

    Principle

    View Slide

  75. Interface Segregation Principle
    No client should be forced to
    depend on methods it does not
    use.

    View Slide

  76. View Slide

  77. View Slide

  78. View Slide

  79. View Slide

  80. Interface Segregation Principle
    Many small client-specific
    interfaces are better than one
    large general purpose interface

    View Slide

  81. Can you violate
    Interface segregation in
    Ruby?

    View Slide

  82. View Slide

  83. View Slide

  84. Java
    Fake Typed
    Ruby

    View Slide

  85. View Slide

  86. View Slide

  87. View Slide

  88. View Slide

  89. View Slide

  90. View Slide

  91. View Slide

  92. View Slide

  93. View Slide

  94. You CAN violate
    ISP in Ruby

    View Slide

  95. You CAN violate
    the spirit of
    ISP in Ruby

    View Slide

  96. Small
    Client-specific interfaces
    >
    Large
    general-purpose interfaces

    View Slide

  97. https://freephotos.cc/image/5a1d48dc4bf957c95a7e32ac30c60f3e

    View Slide

  98. git log --grep “CsvAircraft”

    View Slide

  99. Dependency 

    Inversion

    Principle

    View Slide

  100. Dependency Inversion Principle
    Entities must depend on
    abstractions, not concretions.

    View Slide

  101. View Slide

  102. View Slide

  103. View Slide

  104. View Slide

  105. Recap

    View Slide

  106. How can Git help
    you refactor?

    View Slide

  107. Use the git log to group commits into topics
    and recognize when a class is doing more
    than one thing

    View Slide

  108. Keep an eye out for red in the diff when
    you're adding functionality, this could
    indicate a violation of the Open/Closed
    principle

    View Slide

  109. Integrate tools like automatic style linters
    with your GitHub account to make code
    cleaner and easier to recognize problems

    View Slide

  110. Use git log and git blame to find how often
    classes or methods have had to change. This
    tells you where your worst offenders most in
    need of refactor are.

    View Slide

  111. Git can help you achieve
    SOLID code

    View Slide

  112. Thank You!

    View Slide

  113. Ashley Ellis Pierce

    Application Engineer @ GitHub
    @aellispierce

    View Slide