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.

B9723dc81eafa0294ce0a5e33a1fc584?s=128

Ashley Ellis Pierce

November 15, 2017
Tweet

Transcript

  1. Git Driven Refactoring

  2. Ashley Ellis Pierce
 Application Engineer @ GitHub @aellispierce

  3. Refactoring?

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

  5. We make mistakes

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

  7. Design problem -> Refactoring technique

  8. Design problem -> Refactoring technique

  9. None
  10. S.O.L.I.D
 principles

  11. S.O.L.I.D
 Single Responsibility Principle

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

    to change.

  13. S.O.L.I.D
 Single Responsibility Principle Open/Closed Principle

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

    closed for modification.

  15. S.O.L.I.D
 Single Responsibility Principle Open/Closed Principle Liskov Substitution Principle

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

    their base/parent class.

  17. S.O.L.I.D
 Single Responsibility Principle Open/Closed Principle Liskov Substitution Principle Interface

    Segregation Principle
  18. Interface Segregation Principle No client should be forced to depend

    on methods it does not use.
  19. S.O.L.I.D
 Single Responsibility Principle Open/Closed Principle Liskov Substitution Principle Interface

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

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

  22. We’re done!

  23. … not quite. We’re done!

  24. None
  25. None
  26. None
  27. None
  28. None
  29. You can’t recognize design patterns in isolation, you need context.

  30. None
  31. S.O.L.I.D
 principles

  32. Single Responsibility Principle

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

    to change.

  34. None
  35. Why has my class changed recently?

  36. None
  37. git log app/models/engine.rb

  38. None
  39. None
  40. None
  41. None
  42. None
  43. None
  44. None
  45. git log app/models/engine.rb

  46. git log app/models/engine.rb

  47. Power Remote Start

  48. git log app/models/engine.rb

  49. None
  50. Git as documentation

  51. Git as documentation

  52. git log app/models/engine.rb

  53. Open/Closed
 Principle

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

    closed for modification.

  55. How do you extend something without modifying it?

  56. None
  57. You’re doing amazing sweetie

  58. None
  59. None
  60. You shouldn’t have to change existing code to add new

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

    diffs
  62. None
  63. Consistent style matters

  64. None
  65. Liskov
 Substitution
 Principle

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

    their base/parent class.

  67. You should be able to call the same method on

    a subclass as you could on a parent and get a compatible result
  68. None
  69. None
  70. is_a? respond_to?

  71. None
  72. Let bots do the nagging for you.

  73. None
  74. Interface
 Segregation
 Principle

  75. Interface Segregation Principle No client should be forced to depend

    on methods it does not use.
  76. None
  77. None
  78. None
  79. None
  80. Interface Segregation Principle Many small client-specific interfaces are better than

    one large general purpose interface
  81. Can you violate Interface segregation in Ruby?

  82. None
  83. None
  84. Java Fake Typed Ruby

  85. None
  86. None
  87. None
  88. None
  89. None
  90. None
  91. None
  92. None
  93. None
  94. You CAN violate ISP in Ruby

  95. You CAN violate the spirit of ISP in Ruby

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

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

  98. git log --grep “CsvAircraft”

  99. Dependency 
 Inversion
 Principle

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

  101. None
  102. None
  103. None
  104. None
  105. Recap

  106. How can Git help you refactor?

  107. Use the git log to group commits into topics and

    recognize when a class is doing more than one thing
  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
  109. Integrate tools like automatic style linters with your GitHub account

    to make code cleaner and easier to recognize problems
  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.
  111. Git can help you achieve SOLID code

  112. Thank You!

  113. Ashley Ellis Pierce
 Application Engineer @ GitHub @aellispierce