$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

    View Slide

  2. View Slide

  3. Francisco Díaz
    @fco_diaz

    View Slide

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

    View Slide

  5. What do we want?
    → Minimize duplication of code.
    → Develop independently without stepping on each
    other's toes.

    View Slide

  6. Feature verticals:
    → Big Panic button
    → Today widget
    → Knock

    View Slide

  7. Big Panic button:

    View Slide

  8. What needs to be done?
    → Create the button.
    → We need a way to create reports.
    → Make a backend call to save this information.

    View Slide

  9. Today widget:

    View Slide

  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.

    View Slide

  11. What was it that we wanted?
    → Minimize duplication of code.
    → Develop independently without stepping on each
    other's toes.

    View Slide

  12. View Slide

  13. Let's try
    again!

    View Slide

  14. → Create the button.
    → We need a way to create reports.
    → Make a backend call to save this information.

    View Slide

  15. UI / Presentation
    Create the button.

    View Slide

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

    View Slide

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

    View Slide

  18. View Slide

  19. To recap:
    → Minimize duplication of code.
    → Develop independently without stepping on each
    other's toes.

    View Slide

  20. We can solve any problem
    by introducing an extra
    level of indirection
    — David Wheeler

    View Slide

  21. Dependency inversion

    View Slide

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

    View Slide

  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)
    }
    }
    }

    View Slide

  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)
    }
    }
    }

    View Slide

  25. Benefits
    → Testable.
    → Decoupled.
    → Easy to fake our networking layer.

    View Slide

  26. View Slide

  27. struct FakeAPI: APIType {
    func createReport(completion: JSONDictionary? -> Void) {
    let dictionary = ["id": 12345]
    completion(dictionary)
    }
    }

    View Slide

  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)
    }
    }

    View Slide

  29. Questions?
    Slides are available at:
    https://github.com/fdiaz/settings-boundaries-talk
    References:
    Architecture: The Lost Years
    The Clean Architecture

    View Slide