Save 37% off PRO during our Black Friday Sale! »

How to Understand Other People's Code

How to Understand Other People's Code

A talk I gave at iOSoho on 11/9/2015. It was loads of fun. Repo for the markdown is at https://github.com/dbgrandi/brownfield-talk

D621347faa8273b41df78b62a6006374?s=128

David Grandinetti

November 12, 2015
Tweet

Transcript

  1. The beginning

  2. None
  3. Green field

  4. That’s not what this talk is about. Mostly.

  5. None
  6. None
  7. UNDERSTANDING OTHER PEOPLE’S CODE

  8. Right. Take a deep breath.

  9. What comes next?

  10. None
  11. tree -if | grep "\.m$" | xargs -n 1 wc

    -l | sort -n
  12. 600 ./Networking/API_Modules/ARUserManager.m 608 ./Models/API_Models/Partner_Metadata/Artwork.m 638 ./View_Controllers/Core/ARArtistViewController.m 871 ./View_Controllers/Contact/ARInquireForArtworkViewController.m 935 ./Networking/ARRouter.m

    1403 ./App/ARAppDelegate+Analytics.m 39643 total
  13. None
  14. DEPENEDENCIES SHOW THE TRUE FOOTPRINT OF YOUR PROJECT

  15. DEPENDENCIES ARE !

  16. BUILD A SMALL, BUT NON-TRIVIAL, RAILS APP. AN EMPTY APP

    HAS ~50 GEM DEPENDENCIES; YOURS WILL HAVE 75-100. GO AWAY FOR SIX MONTHS. COME BACK AND UPDATE ALL OF YOUR DEPENDENCIES. YOUR APP NO LONGER WORKS. - @GARYBURNHARDT
  17. is a dependency

  18. Try compiling a Three20 app in Xcode7

  19. Try compiling a Swift 1 app in Xcode7

  20. Try using an Xcode 7.1 playground in Xcode 7.0

  21. For adding a new button. Just stop here.

  22. None
  23. None
  24. None
  25. None
  26. So, let’s get more practical about how to work with

    legacy code.
  27. Read the tests. There are tests, right?

  28. Write new tests. Those are easy, right?

  29. The first test is the most important

  30. it(@"should be initializable", ^{ DGHomeViewController *controller = [[DGHomeViewController alloc] init];

    expect(controller).toNot.beNil(); });
  31. before(^{ // Setup in-memory CoreData }); it(@"should be initializable", ^{

    DGHomeViewController *controller = [[DGHomeViewController alloc] init]; expect(controller).toNot.beNil(); });
  32. it(@"should be initializable", ^{ UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen

    mainScreen].bounds]; DGBigViewController *controller = [[DGBigViewController alloc] init]; expect(controller).toNot.beNil(); window.rootViewController = controller; [window makeKeyAndVisible]; expect([controller isViewLoaded]).to.beTruthy(); });
  33. before(^{ // Setup in-memory CoreData // Stub News HTTP requests

    // Stub Image HTTP requests // Setup a fake User });
  34. Where are all these implicit dependencies coming from?

  35. + (instancetype)sharedDoodad { static DoodadManager *_sharedDoodad = nil; static dispatch_once_t

    onceToken; dispatch_once(&onceToken, ^{ _sharedDoodad = [[DoodadManager alloc] init]; }); return _sharedDoodad; }
  36. AT LEAST HAVE A WAY TO RESET IT. static DoodadManager

    *_sharedDoodad = nil; static dispatch_once_t onceToken; + (void)setSharedDoodad:(DoodadManager *)doodad { if (!doodad) { _sharedDoodad = nil; onceToken = 0; } else { _sharedDoodad = doodad; } } + (instancetype)sharedDoodad { dispatch_once(&onceToken, ^{ _sharedDoodad = [[DoodadManager alloc] init]; }); return _sharedDoodad; }
  37. BETTER: MOVE FROM STATIC SINGLETON TO ATTACHED TO APPDELEGATE

  38. BEST: MOVE FROM APPDELEGATE TO DEPENDENCY INJECTION

  39. USE A STYLE BASED MARKER FOR THINGS THAT YOU HAVE

    UPDATED E.G. BRACES ON METHODS OR MODERN LITERALS.
  40. I SAID LEGACY, BUT... THIS APPLIES TO UNDERSTANDING NEW DEPENDENCIES

    TOO
  41. UNDERSTANDING OTHER PEOPLE’S CODE

  42. None
  43. UNDERSTANDING OTHER PEOPLE

  44. NO CODE IS PERFECT.

  45. None
  46. ALL CODE HAS A STORY.

  47. None
  48. EVERYTHING YOU'VE EVER THOUGHT ABOUT OTHER PEOPLE'S CODE, IS SOMETHING

    THAT OTHER PEOPLE HAVE THOUGHT ABOUT YOUR CODE.
  49. None
  50. @dbgrandi -->

  51. Links https://www.reddit.com/r/programming/comments/2343yu/the_setup_gary_bernhardt_i_dont_want_more_or/