Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Establishing a SOLID Foundation

120 views

Published on

Presentation of "Establishing a SOLID Foundation" at KCDC 2019

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Establishing a SOLID Foundation

  1. 1. Cameron Presley @pcameronpresley Cameron@TheSoftwareMentor.com Establishing a SOLID Foundation An Intro to Software Design Slides can be found at: http://blog.TheSoftwareMentor.com/Presentations/#SOLID
  2. 2. @pcameronpresley 2
  3. 3. @pcameronpresley 3
  4. 4. @pcameronpresley Mnemonic for a set of principles that allows us to write easier to maintain code Concepts aren’t new (late 80’s) Introduced by Robert C. Martin in Agile Principles, Patterns, and Practices 4
  5. 5. @pcameronpresley Single Responsibility Open/Closed Liskov Substitution Interface Segregation Dependency Inversion 5
  6. 6. @pcameronpresley Doing Too Much! 6 Bad Abstractions
  7. 7. @pcameronpresley 7
  8. 8. @pcameronpresley 8
  9. 9. @pcameronpresley 9
  10. 10. @pcameronpresley 10
  11. 11. @pcameronpresley 11
  12. 12. @pcameronpresley 12
  13. 13. @pcameronpresley 13
  14. 14. @pcameronpresley 14
  15. 15. @pcameronpresley 15
  16. 16. @pcameronpresley 16
  17. 17. @pcameronpresley 17
  18. 18. @pcameronpresley A class should have one reason to change 18
  19. 19. @pcameronpresley 19
  20. 20. @pcameronpresley Classes can be measured in hundreds (or thousands) of LOCs 20
  21. 21. @pcameronpresley 27 public methods 21
  22. 22. @pcameronpresley Single public method with 54 private methods 22
  23. 23. @pcameronpresley 23
  24. 24. @pcameronpresley 24
  25. 25. @pcameronpresley 25 1. Break large methods down to smaller methods 2. Move private methods to new classes 3. Instantiate/use new classes
  26. 26. @pcameronpresley 26
  27. 27. @pcameronpresley Classes should depend upon abstractions Classes shouldn’t be responsible for creating their own dependencies 27
  28. 28. @pcameronpresley 28
  29. 29. @pcameronpresley Only way to change dependencies is to change the class Impossible to write unit tests that cross system boundaries Provides another way to determine if a class is doing too much (32 dependencies) 29
  30. 30. @pcameronpresley 30
  31. 31. @pcameronpresley 31
  32. 32. @pcameronpresley 32
  33. 33. @pcameronpresley Two Goals 33 1. Make sure the dependency can be passed 2. Make sure the dependency has an abstraction
  34. 34. @pcameronpresley First Steps 34 1. If the class is static, make it not static 2. If the class doesn’t have an abstraction, define one
  35. 35. @pcameronpresley Final Step 35 1. Inject the dependency using constructor injection or method injection
  36. 36. @pcameronpresley 36
  37. 37. @pcameronpresley Problem with Static Classes 37 Can’t pass them as parameters Can’t implement an interface or base class
  38. 38. @pcameronpresley Removing Static Cling 38 Removing the static attribute is ideal, but not always possible Using the Wrapper pattern, we can define another class that is not static to wrap around the static and then pass that around
  39. 39. @pcameronpresley 39
  40. 40. @pcameronpresley 40
  41. 41. @pcameronpresley Passing Dependencies 41 Constructor vs Method Injection “Will this dependency need to change during the object’s lifetime?”
  42. 42. @pcameronpresley 42
  43. 43. @pcameronpresley 43
  44. 44. @pcameronpresley 44
  45. 45. @pcameronpresley 45
  46. 46. @pcameronpresley 80% of issues come from these two principles Remaining principles cover the additional 20% 46
  47. 47. @pcameronpresley 47
  48. 48. @pcameronpresley 48
  49. 49. @pcameronpresley 49
  50. 50. @pcameronpresley Classes should be open for extension, closed for modification 50
  51. 51. @pcameronpresley Add new functionality by adding new classes, not modifying existing ones 51
  52. 52. @pcameronpresley 52
  53. 53. @pcameronpresley Modifying a class to add functionality can break something downstream OCP forces us to add functionality by creating new classes and then using an abstraction Safer to create a new class and inject the behavior 53
  54. 54. @pcameronpresley Modifying a class to add functionality can break something downstream OCP forces us to add functionality by creating new classes and then using an abstraction Safer to create a new class and inject the behavior 54
  55. 55. @pcameronpresley Modifying a class to add functionality can break something downstream OCP forces us to add functionality by creating new classes and then using an abstraction Safer to create a new class and inject the behavior 55
  56. 56. @pcameronpresley 56
  57. 57. @pcameronpresley 57 1. Refactor to Factory Pattern 2. Original class becomes the Factory 3. Update clients to use the Factory instead
  58. 58. @pcameronpresley 58
  59. 59. @pcameronpresley 59
  60. 60. @pcameronpresley 60
  61. 61. @pcameronpresley 61
  62. 62. @pcameronpresley 62
  63. 63. @pcameronpresley Adding a New Calculator 63 1. Create the class 2. Implement IShippingCalculator interface 3. Implement business rules 4. Update the factory to return the correct calculator
  64. 64. @pcameronpresley 64
  65. 65. @pcameronpresley 65
  66. 66. @pcameronpresley New Requirement! 66
  67. 67. @pcameronpresley 67
  68. 68. @pcameronpresley 68
  69. 69. @pcameronpresley 69
  70. 70. @pcameronpresley 70
  71. 71. @pcameronpresley Type casting to perform logic is a bad abstraction “Leaky Abstractions” Can’t lean on the compiler for error finding 71
  72. 72. @pcameronpresley 72
  73. 73. @pcameronpresley Not all Books are created equally What if we changed our abstraction? 73
  74. 74. @pcameronpresley 74
  75. 75. @pcameronpresley 75
  76. 76. @pcameronpresley If two classes are derived from the same abstraction, then they should be interchangeable Should not depend upon the class of the abstraction to do work 76
  77. 77. @pcameronpresley 77
  78. 78. @pcameronpresley 78
  79. 79. @pcameronpresley 79
  80. 80. @pcameronpresley 80
  81. 81. @pcameronpresley 81
  82. 82. @pcameronpresley Can find out what “can” be done, not what “should” be done Header vs Role Interface Shape abstractions based on roles 82
  83. 83. @pcameronpresley 83
  84. 84. @pcameronpresley 84 1. One role to track inventory when an order is made 2. Define an interface with required methods 3. Update InventoryManager so that it implements the new interface 4. Update client code to use the new interface
  85. 85. @pcameronpresley 85
  86. 86. @pcameronpresley 86
  87. 87. @pcameronpresley 87
  88. 88. @pcameronpresley
  89. 89. @pcameronpresley 89 • What is SOLID? • Why should our code be SOLID? • What do the principles stand for? • How to spot issues? How to fix them? • Doing Too Much and Bad Abstractions
  90. 90. @pcameronpresley 90
  91. 91. @pcameronpresley Agile Principles, Patterns, and Practices by Robert C. Martin Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin Working Effectively With Legacy Code by Michael Feathers Refactoring by Martin Fowler SOLID Principles of Object Oriented Design by Steve Smith Role Interfaces by Martin Fowler https://blog.TheSoftwareMentor.com/presentations/#SOLID 91

×