Upgrade to Pro — share decks privately, control downloads, hide ads and more …

MVVM(DC): Taming your architecture

MVVM(DC): Taming your architecture

Everyone is well aware of most of the different architectures available out there and jump here and there trying to be on the «latest and trendiest architecture»; which is ok, sadly though, most of the time we are left with lots of gaps and wondering how exactly our apps fit into this architecture or the other with no clear answer.

This talk will try to help fill some of the gaps in between MVVM via introducing some concepts that even though they are not new; giving them a name and an explanation into how they fit and tie things together helps others understand better a simple yet very helpful architecture like MVVM.

Esteban Torres

February 16, 2017
Tweet

More Decks by Esteban Torres

Other Decks in Technology

Transcript

  1. MVVM(DC):
    Taming your architecture
    Esteban Torres - @esttorhe, MobOS, 2017 1

    View Slide

  2. Which architecture
    should I use?
    Esteban Torres - @esttorhe, MobOS, 2017 2

    View Slide

  3. What is the
    «Problem»?
    Esteban Torres - @esttorhe, MobOS, 2017 3

    View Slide

  4. Not only this but we also lack certain «pieces»
    along this architectures
    or lack a clear understanding of where things
    belong
    Esteban Torres - @esttorhe, MobOS, 2017 4

    View Slide

  5. What DO we have ?
    Esteban Torres - @esttorhe, MobOS, 2017 5

    View Slide

  6. What DO we have?
    (some of them at least)
    Esteban Torres - @esttorhe, MobOS, 2017 6

    View Slide

  7. MVC
    Esteban Torres - @esttorhe, MobOS, 2017 7

    View Slide

  8. Esteban Torres - @esttorhe, MobOS, 2017 8

    View Slide

  9. The «Problem» of MVC
    Esteban Torres - @esttorhe, MobOS, 2017 9

    View Slide

  10. MVC
    Verdict: By its basic definition not good enough
    for complex apps
    Esteban Torres - @esttorhe, MobOS, 2017 10

    View Slide

  11. VIPER
    Esteban Torres - @esttorhe, MobOS, 2017 11

    View Slide

  12. VIPER
    4 View
    4 Interactor (Use Cases)
    4 Presenter
    4 Entity
    4 Router
    Esteban Torres - @esttorhe, MobOS, 2017 12

    View Slide

  13. VIPER
    Verdict: «Chunky» projects, very testable, clear
    separation of concerns, sometimes «overly»
    complex
    Esteban Torres - @esttorhe, MobOS, 2017 13

    View Slide

  14. MVVM
    Esteban Torres - @esttorhe, MobOS, 2017 14

    View Slide

  15. Model
    Esteban Torres - @esttorhe, MobOS, 2017 15

    View Slide

  16. View
    Esteban Torres - @esttorhe, MobOS, 2017 16

    View Slide

  17. ViewModel
    Esteban Torres - @esttorhe, MobOS, 2017 17

    View Slide

  18. ViewModel
    class MyViewModel {
    // The model being «formatted»
    private var model: MyModel? = nil
    // A formatted property
    let amountDueText: String {
    var currencyFormatter = NSNumberFormatter()
    currencyFormatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
    currencyFormatter.locale = NSLocale.currentLocale()
    return currencyFormatter.stringFromNumber(model?.amount) ?? 0)
    }
    }
    Esteban Torres - @esttorhe, MobOS, 2017 18

    View Slide

  19. What do we have?
    Esteban Torres - @esttorhe, MobOS, 2017 19

    View Slide

  20. MVC
    Esteban Torres - @esttorhe, MobOS, 2017 20

    View Slide

  21. Esteban Torres - @esttorhe, MobOS, 2017 21

    View Slide

  22. VIPER
    Esteban Torres - @esttorhe, MobOS, 2017 22

    View Slide

  23. Esteban Torres - @esttorhe, MobOS, 2017 23

    View Slide

  24. MVVM
    Esteban Torres - @esttorhe, MobOS, 2017 24

    View Slide

  25. Esteban Torres - @esttorhe, MobOS, 2017 25

    View Slide

  26. We DON'T have
    a place
    Esteban Torres - @esttorhe, MobOS, 2017 26

    View Slide

  27. Esteban Torres - @esttorhe, MobOS, 2017 27

    View Slide

  28. ¯\_(ϑ)_/¯
    What does this mean?
    Esteban Torres - @esttorhe, MobOS, 2017 28

    View Slide

  29. Esteban Torres - @esttorhe, MobOS, 2017 29

    View Slide

  30. Let's figure it out using
    MVVM
    Esteban Torres - @esttorhe, MobOS, 2017 30

    View Slide

  31. Network layer
    Esteban Torres - @esttorhe, MobOS, 2017 31

    View Slide

  32. Esteban Torres - @esttorhe, MobOS, 2017 32

    View Slide

  33. !❓
    Esteban Torres - @esttorhe, MobOS, 2017 33

    View Slide

  34. !
    Esteban Torres - @esttorhe, MobOS, 2017 34

    View Slide

  35. Esteban Torres - @esttorhe, MobOS, 2017 35

    View Slide

  36. !
    Esteban Torres - @esttorhe, MobOS, 2017 36

    View Slide

  37. class ViewModelA {
    private let model: Model
    var formattedCurrency: String…
    var formattedProperty1: Double…
    var formattedProperty2: String…


    init(withModel model: Model) …
    func getModels(completion:([Model]) -> ()) -> Void {
    API.request(.GetModels) { jsonResponse in
    // Parse the JSON response here
    let models = …
    completion(models)
    }
    }
    }
    Esteban Torres - @esttorhe, MobOS, 2017 37

    View Slide

  38. !
    Esteban Torres - @esttorhe, MobOS, 2017 38

    View Slide

  39. MVVM
    …an abstraction of the view exposing public
    properties and commands… In the view
    model, the binder mediates communication
    between the view and the data binder.
    The view model has been described as a state
    of the data in the model.1
    1 http://wayback.archive.org/web/20080201101909/http://
    www.acceptedeclectic.com/2008/01/model-view-viewmodel-pattern-for-
    wpf.html
    Esteban Torres - @esttorhe, MobOS, 2017 39

    View Slide

  40. DataControllers
    Esteban Torres - @esttorhe, MobOS, 2017 40

    View Slide

  41. Esteban Torres - @esttorhe, MobOS, 2017 41

    View Slide

  42. It worked
    Esteban Torres - @esttorhe, MobOS, 2017 42

    View Slide

  43. Esteban Torres - @esttorhe, MobOS, 2017 43

    View Slide

  44. class ViewModel {
    // Hold a reference to our DataController
    private let dataController: DataController
    // Hold a reference to the model we will be getting
    private var model: Model?
    func getModel(id: Int) -> Observable {
    return Observable.create { observer in
    dataController.getModel(id)
    .subscribe(onNext: { [unowned self] model in
    self.model = model
    // If we need to format something else we should do it here
    observer.onNext(self.model)
    }, onError: { error in
    // Maybe properly format the error to the user here as well
    observer.onError(error)
    }
    ).addDisposableTo(disposeBag)
    }
    }
    }
    Esteban Torres - @esttorhe, MobOS, 2017 44

    View Slide

  45. class ViewController: UIViewController {
    // Retain a reference to our ViewModel
    private let viewModel: ViewModel
    func loadData() -> Void {
    self.viewModel.loadModel()
    .subscribeOn(MainScheduler.instance)
    .subscribe(onNext: { [unonwed self] viewModel in
    // Update your `UI` accordingly
    self.nameLabel.text = viewModel.formattedName
    self.amountLabel.tet = viewModel.hopsAmount
    }, onError: { error in … }
    })
    .addDisposableTo(disposeBag)
    }
    }
    Esteban Torres - @esttorhe, MobOS, 2017 45

    View Slide

  46. So… what did we do? !
    Esteban Torres - @esttorhe, MobOS, 2017 46

    View Slide

  47. Conclusion
    Esteban Torres - @esttorhe, MobOS, 2017 47

    View Slide

  48. «That was the worst idea EVER…
    BUT seeing how badly they tackled that
    problem gave me an idea about how to
    actually make it work.»
    Esteban Torres - @esttorhe, MobOS, 2017 48

    View Slide

  49. Questions?
    Esteban Torres - @esttorhe, MobOS, 2017 49

    View Slide

  50. Thanks
    Esteban Torres - @esttorhe, MobOS, 2017 50

    View Slide