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

What I learnt using the Presenter Pattern

What I learnt using the Presenter Pattern

Given at Oredev 2016: https://vimeo.com/191068122

Patterns of yore like MVP, MVVM etc. have taken the Android world by storm these days. These are not new concepts per say, but their application to the world of mobile development is new.

In this talk, I share some of the learnings from having adopted this pattern in an actual production application.

What are the common patterns used in mobile these days? What are the problems with adoption? What are the advantages of adoption? How do we adopt these patterns in a way that doesn't lead to death by abstraction?

We'll discuss the juicy learnings from war stories in this session.

Kaushik Gopal

November 10, 2016
Tweet

More Decks by Kaushik Gopal

Other Decks in Programming

Transcript

  1. What I learnt
    using the 

    Presenter Pattern

    View Slide

  2. Know thy pattern
    Primer on MVC, MVP, MVVM

    View Slide

  3. Know thy patterns
    View
    Controller
    Model
    user events
    modifies
    fire
    state change
    events
    MVC

    View Slide

  4. Know thy patterns
    MVP
    View
    Presenter
    Model
    User interaction
    user events
    modifies
    fire
    state change events
    updates

    View Slide

  5. View
    Presenter
    Model
    User interaction
    user events
    modifies
    fire
    state change events
    updates
    Know thy patterns
    MVP
    Passive

    View Slide

  6. View
    Model
    User interaction
    Know thy patterns
    MVP
    user events
    modifies
    updates
    Supervising

    Controller
    Data
    Binding

    View Slide

  7. View
    Model
    Know thy patterns
    MVVM
    Data
    Binding
    View Model
    update state
    fire state change
    (view queries VM again)
    (Presentation Model)

    View Slide

  8. MVVM
    MVC MVP
    View
    Controller
    Model
    user
    events
    modifies
    state
    change
    events
    View
    Presenter
    Model
    User
    interaction
    user events
    modifies state
    change events
    updates
    View
    Model
    View Model
    modifies state
    changes
    Know thy patterns
    Data
    Binding

    View Slide

  9. Evolve a Pattern
    "Architecture changes" are painful
    Introducing patterns is awesome

    View Slide

  10. Evolve a Pattern
    class Customer {

    String dateOfBirth;
    String fullName;
    }
    "Bruce Lee"
    "1940-11-27"
    Don't add to the Model!
    Create a ViewModel
    class CustomerViewModel {

    Customer user;


    CustomerViewModel(Customer user) {

    this.user = user;

    }


    boolean canPurchaseAlcohol() {

    // return age() > 18;

    }


    String getInitials() {

    // return strip(user.fullName);

    }

    }

    View Slide

  11. Don't use terms
    interchangeably !
    ViewModel != Presenter

    View Slide

  12. Don't use terms interchangeably
    Model
    Database structure
    or

    mirror of REST JSON
    Model
    decorates
    View Model

    View Slide

  13. Don't use terms interchangeably
    Activities
    Fragments
    Views
    decorates
    Presenters
    Model
    decorates
    View Model
    ! Model

    View Slide

  14. Where to put the
    Presenter?
    ¯\_(ϑ)_/¯

    View Slide

  15. Where to put the Presenter?
    Activity
    Fragment
    Fragment
    ListView
    Adapter
    ViewHolder
    ViewHolder
    View
    ActivityPresenter?
    FragmentPresenter?
    ListViewPresenter?
    AdapterPresenter?
    ViewHolderPresenter?
    ViewPresenter?

    View Slide

  16. Where to put the Presenter?
    Activity
    Fragment
    Fragment
    ListView
    Adapter
    ViewHolder
    ViewHolder
    View
    ActivityPresenter?
    FragmentPresenter?
    ListViewPresenter?
    AdapterPresenter?
    ViewHolderPresenter?
    ViewPresenter?

    View Slide

  17. Death by Boilerplate
    :(

    View Slide

  18. Use some form of DataBinding!
    Death by Boilerplate
    EventBus(es)
    So how does one combat the Boilerplate?
    Use some form of DataBinding!
    EventBus(es)

    View Slide

  19. CheckoutActivity CheckoutActivityPresenter
    CheckoutAPresenterView Interface
    cause Java!
    CheckoutAdapter
    PaymentCardViewHolder
    AdapterPresenter
    PaymentCardVHPresenter
    AdapterPresenterView
    VHPresenterView
    implements
    new (View activity) {
    mView = activity;
    }
    CheckoutActivityPresenter
    AdapterPresenter
    new (View adapter) {
    mView = adapter;
    }
    mCheckoutActivityPresenter
    mAdapterPresenter
    Death by Boilerplate

    View Slide

  20. CheckoutActivity CheckoutActivityPresenter
    CheckoutAPresenterView
    CheckoutAdapter
    PaymentCardViewHolder
    AdapterPresenter
    PaymentCardVHPresenter
    AdapterPresenterView
    VHPresenterView
    new (View activity) {
    mView = activity;
    }
    CheckoutActivityPresenter
    AdapterPresenter
    Button.onClick(event)
    new (View adapter) {
    mView = adapter;
    }
    mCheckoutActivityPresenter
    mAdapterPresenter
    launchPaymentActivity()
    Death by Boilerplate

    View Slide

  21. CheckoutActivity CheckoutActivityPresenter
    CheckoutAPresenterView
    CheckoutAdapter
    PaymentCardViewHolder
    AdapterPresenter
    PaymentCardVHPresenter
    AdapterPresenterView
    VHPresenterView
    new (View activity) {
    mView = activity;
    }
    CheckoutActivityPresenter
    AdapterPresenter
    Button.onClick(event)
    new (View adapter) {
    mView = adapter;
    }
    mCheckoutActivityPresenter
    mAdapterPresenter
    launchPaymentActivity()
    OR
    ......
    use an EventBus
    Death by Boilerplate

    View Slide

  22. CheckoutActivity CheckoutActivityPresenter
    CheckoutAPresenterView
    CheckoutAdapter
    PaymentCardViewHolder
    AdapterPresenter
    PaymentCardVHPresenter
    Death by Boilerplate (Event Bus)
    AdapterPresenterView
    VHPresenterView
    new (View activity) {
    mView = activity;
    }
    Button.onClick(event)
    new (View adapter) {
    mView = adapter;
    }
    mCheckoutActivityPresenter
    mAdapterPresenter
    launchPaymentActivity()
    bus.post(event)
    @Subscribe

    View Slide

  23. Compose Presenters
    ¯\_ + _/¯

    View Slide

  24. Compose Presenters

    View Slide

  25. Reinforce reasons
    for pattern

    View Slide

  26. (Unit) Testing is faster and easier*

    View Slide

  27. ...But UI testing exists

    View Slide


  28. fragmentedpodcast.com
    tech.instacart.com
    @kaushikgopal
    kaush.co
    My thanks to @cyrilmotier
    who graciously allowed me to rip-off his slide deck theme

    View Slide