$30 off During Our Annual Pro Sale. View Details »

Setting Boundaries

Setting Boundaries

Presented at ViDIA meetup.

Francisco Díaz

March 10, 2016
Tweet

More Decks by Francisco Díaz

Other Decks in Programming

Transcript

  1. Setting Boundaries

  2. None
  3. Francisco Díaz @fco_diaz

  4. 3 iOS Devs 28 hours 1 project == Merge Conflicts

  5. What do we want? → Minimize duplication of code. →

    Develop independently without stepping on each other's toes.
  6. Feature verticals: → Big Panic button → Today widget →

    Knock
  7. Big Panic button:

  8. What needs to be done? → Create the button. →

    We need a way to create reports. → Make a backend call to save this information.
  9. Today widget:

  10. What needs to be done? → Create the extension button.

    → We need a way to create reports. → Make a backend call to save this information.
  11. What was it that we wanted? → Minimize duplication of

    code. → Develop independently without stepping on each other's toes.
  12. None
  13. Let's try again!

  14. → Create the button. → We need a way to

    create reports. → Make a backend call to save this information.
  15. UI / Presentation Create the button.

  16. Business logic We need a way to create reports.

  17. Backend connection Make a backend call to save this information.

  18. None
  19. To recap: → Minimize duplication of code. → Develop independently

    without stepping on each other's toes.
  20. We can solve any problem by introducing an extra level

    of indirection — David Wheeler
  21. Dependency inversion

  22. struct ModelDataManager { let APIClient: APIType init(APIClient: APIType) { self.APIClient

    = APIClient } }
  23. protocol APIType { func createReport(completion: JSONDictionary? -> Void) } struct

    API { private let manager: Alamofire.Manager init() { manager = Alamofire.Manager() } } extension API: APIType { func createReport(completion: JSONDictionary? -> Void) { manager.request(.POST, "https://some.com/api/report") .responseJSON { response in completion(response) } } }
  24. struct ModelDataManager { let APIClient: APIType init(API: APIType) { self.APIClient

    = API } static func defaultManager() -> ModelDataManager { let APIClient = API() return ModelDataManager(API: APIClient) } func createReport(completionHandler completion: Report? -> Void) { APIClient.createReport() { jsonDictionary in let report = ... // Parse jsonDictionary into Report completion(report) } } }
  25. Benefits → Testable. → Decoupled. → Easy to fake our

    networking layer.
  26. None
  27. struct FakeAPI: APIType { func createReport(completion: JSONDictionary? -> Void) {

    let dictionary = ["id": 12345] completion(dictionary) } }
  28. struct ModelDataManager { let APIClient: APIType init(API: APIType) { self.APIClient

    = API } static func defaultManager() -> ModelDataManager { // let APIClient = API() let APIClient = FakeAPI() return ModelDataManager(API: APIClient) } }
  29. Questions? Slides are available at: https://github.com/fdiaz/settings-boundaries-talk References: Architecture: The Lost

    Years The Clean Architecture