Code Reuse

A84ff6526157fd1d165bfde743367382?s=47 Apokrupto
September 21, 2015

Code Reuse

Using separation by behaviour to reduce view controller responsibilities, code size and repetition.

Unfortunately the presentation has embedded video as well as three breaks for demos in Xcode, so the full effect isn't transmitted very well.

A84ff6526157fd1d165bfde743367382?s=128

Apokrupto

September 21, 2015
Tweet

Transcript

  1. Code reuse © Apokrupto 2015

  2. Code reuse Code complexity © Apokrupto 2015

  3. Cyclomatic Complexity • Number of independent paths through a •

    function • class • module © Apokrupto 2015
  4. Cyclomatic Complexity • Good < 10-12 • Review < 20

    • Refactor >20 • Unmaintainable ~30-40 • Fatally unmaintainable > 50 © Apokrupto 2015
  5. Cyclomatic Complexity © Apokrupto 2015

  6. Cyclomatic Complexity © Apokrupto 2015

  7. Cyclomatic Complexity © Apokrupto 2015

  8. Code reuse Using separation by behaviour to reduce view controller

    responsibilities, code size and repetition © Apokrupto 2015
  9. Principles • DRY - Don’t repeat yourself • Worth repeating

    © Apokrupto 2015
  10. Principles • DRY - Don’t repeat yourself • Worth repeating

    © Apokrupto 2015
  11. Principles • Single responsibility • Separation of concerns • Promotes

    reuse • What do ‘rate my app’ & ‘call our helpdesk’ features have to do with each other? • And what do they have to do with the model? © Apokrupto 2015
  12. Principles • Single responsibility • Separation of concerns • Promotes

    reuse • What do ‘rate my app’ & ‘call our helpdesk’ features have to do with each other? • And what do they have to do with the model? © Apokrupto 2015
  13. Principles • Single responsibility • Separation of concerns • Promotes

    reuse • What do ‘rate my app’ & ‘call our helpdesk’ features have to do with each other? • And what do they have to do with the model? © Apokrupto 2015
  14. Principles • Single responsibility • Separation of concerns • Promotes

    reuse • What do ‘rate my app’ & ‘call our helpdesk’ features have to do with each other? • And what do they have to do with the model? © Apokrupto 2015
  15. Principles • Single responsibility • Separation of concerns • Promotes

    reuse • What do ‘rate my app’ & ‘call our helpdesk’ features have to do with each other? • And what do they have to do with the model? © Apokrupto 2015
  16. MVC • The ‘Massive View Controller’ problem • Unrelated functionality

    implemented in the same class • What if we have a “Call the helpdesk” button on multiple screens? • DRY • Base class? © Apokrupto 2015
  17. MVC • The ‘Massive View Controller’ problem • Unrelated functionality

    implemented in the same class • What if we have a “Call the helpdesk” button on multiple screens? • DRY • Base class? © Apokrupto 2015
  18. MVC • The ‘Massive View Controller’ problem • Unrelated functionality

    implemented in the same class • What if we have a “Call the helpdesk” button on multiple screens? • DRY • Base class? © Apokrupto 2015
  19. MVC • The ‘Massive View Controller’ problem • Unrelated functionality

    implemented in the same class • What if we have a “Call the helpdesk” button on multiple screens? • DRY • Base class? © Apokrupto 2015
  20. MVC • The ‘Massive View Controller’ problem • Unrelated functionality

    implemented in the same class • What if we have a “Call the helpdesk” button on multiple screens? • DRY • Base class? © Apokrupto 2015
  21. MVC • The ‘Massive View Controller’ problem • Unrelated functionality

    implemented in the same class • What if we have a “Call the helpdesk” button on multiple screens? • DRY • Base class? © Apokrupto 2015
  22. MVC • The ‘Massive View Controller’ problem • Unrelated functionality

    implemented in the same class • What if we have a “Call the helpdesk” button on multiple screens? • DRY • Base class? © Apokrupto 2015 Behaviours
  23. © Apokrupto 2015

  24. What do we get? • Animating the button’s arrival •

    Animating the background • Dismissing the button • Rating the app • Calling the helpdesk © Apokrupto 2015
  25. What do we get? • MySlidingInAndOutBackgroundAnimatingAppRat eAndHelpDeskViewController.h • 700 lines

    of code • Change requests • if-else/switch hell © Apokrupto 2015
  26. What do we get? • MySlidingInAndOutBackgroundAnimatingAppRat eAndHelpDeskViewController.h • 700 lines

    of code • Change requests • if-else/switch hell © Apokrupto 2015
  27. What do we get? • MySlidingInAndOutBackgroundAnimatingAppRat eAndHelpDeskViewController.h • 700 lines

    of (unrelated) code • Change requests • if-else/switch hell © Apokrupto 2015
  28. What do we get? • MySlidingInAndOutBackgroundAnimatingAppRat eAndHelpDeskViewController.h • 700 lines

    of (unrelated) code • Change requests • if-else/switch hell © Apokrupto 2015
  29. What do we get? • MySlidingInAndOutBackgroundAnimatingAppRat eAndHelpDeskViewController.h • 700 lines

    of (unrelated) code • Change requests • if-else/switch hell © Apokrupto 2015
  30. What do we get? • Animating the button’s arrival •

    Animating the background • Dismissing the button • Rating the app • Calling the helpdesk © Apokrupto 2015
  31. Separating the behaviours • Animating the button’s arrival • Animating

    the background • Dismissing the button • Rating the app • Calling the helpdesk © Apokrupto 2015
  32. Separating the behaviours • Take them all out of the

    View Controller • Use composition to put them back • Make them configurable • Without explicitly adding them to the VC © Apokrupto 2015
  33. Separating the behaviours • Take them all out of the

    View Controller • Use composition to put them back • Make them configurable • Without explicitly adding them to the VC © Apokrupto 2015
  34. Separating the behaviours • Take them all out of the

    View Controller • Use composition to put them back • Make them configurable • Without explicitly adding them to the VC © Apokrupto 2015
  35. Separating the behaviours • Take them all out of the

    View Controller • Use composition to put them back • Make them configurable • Without explicitly adding them to the VC © Apokrupto 2015
  36. Demo • Setting behaviours © Apokrupto 2015

  37. Behaviour Ownership • The behaviour may be destroyed at any

    moment, because there are no strong references to it • We fix this by making it an associated object of the view controller • giving us the necessary ownership • and making the composition © Apokrupto 2015
  38. Behaviour Ownership © Apokrupto 2015

  39. Behaviour Ownership © Apokrupto 2015

  40. Demo • Re-use • Individual tweaks © Apokrupto 2015

  41. Facts & figures • Recent project • 115 separate behaviours

    • App level, library specific, generic • App level - highest coupling • Generic - lowest & most reusable © Apokrupto 2015
  42. Advanced What’s wrong with this picture? © Apokrupto 2015

  43. Advanced © Apokrupto 2015

  44. Advanced • Your behaviours can be the delegates and data

    sources for your view controllers • Implement scroll, table & other view’s delegates and data sources in behaviours © Apokrupto 2015
  45. Demo • Behaviours with data sources © Apokrupto 2015

  46. Advanced • Add delegates & data sources to your behaviours

    • localisation • can be another behaviour • or use the view controller © Apokrupto 2015
  47. Advanced • Add delegates & data sources to your behaviours

    • localisation • can be another behaviour • or use the view controller © Apokrupto 2015
  48. Advanced • Add delegates & data sources to your behaviours

    • localisation • can be another behaviour • or use the view controller © Apokrupto 2015
  49. Advanced • Add delegates & data sources to your behaviours

    • localisation • can be another behaviour • or use the view controller © Apokrupto 2015
  50. To sum up • Separating individual responsibilities results in smaller,

    more maintainable and reusable code • Greater flexibility with unit testing • Refactoring is a simple delete • Skinny is good © Apokrupto 2015
  51. To sum up • Separating individual responsibilities results in smaller,

    more maintainable and reusable code • Greater flexibility with unit testing • Refactoring is a simple delete • Skinny is good © Apokrupto 2015
  52. To sum up • Separating individual responsibilities results in smaller,

    more maintainable and reusable code • Greater flexibility with unit testing • Refactoring is a simple delete • Skinny is good © Apokrupto 2015
  53. To sum up • Separating individual responsibilities results in smaller,

    more maintainable and reusable code • Greater flexibility with unit testing • Refactoring is a simple delete • Skinny is good © Apokrupto 2015
  54. But you can get too skinny © Apokrupto 2015

  55. Big finish © Apokrupto 2015

  56. Core Data as a behaviour • Generally NSFetchedResultsController is used

    with a table view to populate a view controller • Much of this is generic • A Core Data behaviour can act as the UITableViewDelegate and UITableViewDataSource • But the behaviour does not know how to populate cells, or what to do if they are selected © Apokrupto 2015
  57. Core Data as a behaviour © Apokrupto 2015

  58. Core Data as a behaviour © Apokrupto 2015

  59. Core Data as a behaviour © Apokrupto 2015

  60. Core Data as a behaviour • Generic Core Data behaviour

    with table view outlet • Behaviour is UITableViewDataSource and UITableViewDelegate • Behaviour will proxy the results from a CD fetch request to the table view • Behaviour has a Core Data Data Source and Core Data Delegate • Data Source handles the specifics of populating a table view cell • Delegate handles the specifics of selecting a cell © Apokrupto 2015
  61. Core Data as a behaviour • Generic Core Data behaviour

    with table view outlet • Behaviour is UITableViewDataSource and UITableViewDelegate • Behaviour will proxy the results from a CD fetch request to the table view • Behaviour has a Core Data Data Source and Core Data Delegate • Data Source handles the specifics of populating a table view cell • Delegate handles the specifics of selecting a cell © Apokrupto 2015
  62. Core Data as a behaviour • Generic Core Data behaviour

    with table view outlet • Behaviour is UITableViewDataSource and UITableViewDelegate • Behaviour will proxy the results from a CD fetch request to the table view • Behaviour has a Core Data Data Source and Core Data Delegate • Data Source handles the specifics of populating a table view cell • Delegate handles the specifics of selecting a cell © Apokrupto 2015
  63. Core Data as a behaviour • Generic Core Data behaviour

    with table view outlet • Behaviour is UITableViewDataSource and UITableViewDelegate • Behaviour will proxy the results from a CD fetch request to the table view • Behaviour has a Core Data Data Source and Core Data Delegate • Data Source handles the specifics of populating a table view cell • Delegate handles the specifics of selecting a cell © Apokrupto 2015
  64. Core Data as a behaviour • Generic Core Data behaviour

    with table view outlet • Behaviour is UITableViewDataSource and UITableViewDelegate • Behaviour will proxy the results from a CD fetch request to the table view • Behaviour has a Core Data Data Source and Core Data Delegate • Data Source handles the specifics of populating a table view cell • Delegate handles the specifics of selecting a cell © Apokrupto 2015
  65. Core Data as a behaviour • Generic Core Data behaviour

    with table view outlet • Behaviour is UITableViewDataSource and UITableViewDelegate • Behaviour will proxy the results from a CD fetch request to the table view • Behaviour has a Core Data Data Source and Core Data Delegate • Data Source handles the specifics of populating a table view cell • Delegate handles the specifics of selecting a cell © Apokrupto 2015
  66. Core Data Data Source © Apokrupto 2015

  67. Core Data Data Source © Apokrupto 2015

  68. Big finish demo © Apokrupto 2015

  69. Big finish stats • Adding a golf course • Core

    Data table population • Customising the table • Background animation • Sliding animation 813 © Apokrupto 2015
  70. Big finish stats • Adding a golf course • Core

    Data table population • Customising the table • Background animation • Sliding animation 767 LOC © Apokrupto 2015
  71. Big finish stats • Adding a golf course • Core

    Data table population • Customising the table • Background animation • Sliding animation 767 LOC © Apokrupto 2015
  72. Big finish stats • Adding a golf course • Core

    Data table population • Customising the table • Background animation • Sliding animation 767 LOC 94 © Apokrupto 2015
  73. Big finish stats • Very low complexity • Highest complexity

    method: 6 • Average complexity: 1.6 • Average NLOC: 6 © Apokrupto 2015
  74. It doesn’t end there • It doesn’t have to be

    a table view • Collection views • Page views • Hand crafted views representing any collection © Apokrupto 2015
  75. It doesn’t end there • It doesn’t have to be

    a table view • Collection views • Page views • Hand crafted views representing any collection © Apokrupto 2015
  76. It doesn’t end there • It doesn’t have to be

    a table view • Collection views • Page views • Hand crafted views representing any collection © Apokrupto 2015
  77. It doesn’t end there • It doesn’t have to be

    a table view • Collection views • Page views • Hand crafted views representing any collection © Apokrupto 2015
  78. It doesn’t end there • It doesn’t have to be

    a table view • Collection views • Page views • Hand crafted views representing any collection © Apokrupto 2015
  79. Lessons Learned • Write generic code • Write low complexity

    code • Write code that is designed to be extended • Keep that code available somewhere • git, cocoapod, library, github, carthage © Apokrupto 2015
  80. Thank you © Apokrupto 2015 mail: warren@apokrupto.com twitter: @apokrupto