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

ADDC 2018 - Ty Smith: Building for Developers

ADDC 2018 - Ty Smith: Building for Developers

Many teams are designed so that engineers can take an abstract view of the customer and focus on implementation. But when the customers are other engineers, that entire dynamic is thrown on it's head.

In this talk, Ty will walk you through the best practices of building great products for developers, from team processes to the technical delivery.

Topics covered will include: Building customer personas and product strategies, Developer Experience research and analytics, customer empathy and support structures, API Design and usability, testing, code distribution, and creating great documentation.

Watch the video: https://www.youtube.com/watch?v=1cuhWSZqDCM
More about the talk, authors & slides: https://addconf.com/2018/schedule/building-for-developers/
Read about the conference: https://addconf.com

Ty Smith

July 04, 2018
Tweet

More Decks by Ty Smith

Other Decks in Programming

Transcript

  1. DESIGNING FOR
    DEVELOPERS
    Ty Smith
    uber.github.io
    @tsmith

    View Slide

  2. Building for
    Developers
    Ty Smith
    uber.github.io
    @tsmith

    View Slide

  3. Overview
    — Developer Product Research
    — Developer Usability Focuses
    — Library Quality Standards
    — Best Practices for Releases
    — Managing Communities
    @tsmith

    View Slide

  4. Product Research
    @tsmith

    View Slide

  5. Standard product workflow
    @tsmith

    View Slide

  6. Developer Tool workflow
    @tsmith

    View Slide

  7. People Need Focus
    @tsmith | https://twitter.com/marcos_placona/status/882487720597237760

    View Slide

  8. Expertise Bias
    @tsmith

    View Slide

  9. Product's role in a developer world
    @tsmith

    View Slide

  10. Finding the right job for your product
    @tsmith | https://hbr.org/2016/09/know-your-customers-jobs-to-be-done

    View Slide

  11. Finding the right job for
    your product
    @tsmith | https://hbr.org/2016/09/know-your-customers-jobs-to-be-done

    View Slide

  12. Finding the right job for your product
    Crash Reporting
    -Stability
    -Time to build features
    -Insight into instability
    @tsmith | CC-BY-2.0 - Bill Ward | https://hbr.org/2016/09/know-your-customers-jobs-to-be-done

    View Slide

  13. Developer Customers
    @tsmith

    View Slide

  14. Developer Demographics
    @tsmith | Search Engine Guide

    View Slide

  15. Developer Personas
    Name Role Company
    Frank CS Student University
    Betty Founder Seed Startup
    João Engineer Emerging Market Series A
    Paul Product Manager Hypergrowth Series C
    Sharon Staff Engineer Public SV Company
    Hannah Consultant Enterprise Company
    @tsmith | https://wiki.mozilla.org/DeveloperExperience/Personas

    View Slide

  16. Developer Research
    — Watch them integrate
    — Dig into expectations
    — Survey
    @tsmith

    View Slide

  17. Success Objectives
    — Developer Productivity
    — Developer Happiness
    — Developer Trust
    @tsmith

    View Slide

  18. @tsmith

    View Slide

  19. Usability
    @tsmith | CC-BY-2.0 - Sherman Paggi

    View Slide

  20. Autodispose
    Automatic binding+disposal of
    RxJava 2 streams.
    @tsmith | https://github.com/uber/AutoDispose

    View Slide

  21. Easy to Integrate
    dependencies {
    implementation 'com.uber.autodispose:autodispose:x.y.z'
    }
    observable
    .doStuff()
    .as(autoDisposable(this)) //<--Here's the magic.
    .subscribe(s -> ...)
    @tsmith | https://github.com/uber/AutoDispose

    View Slide

  22. Concise
    observable
    .doStuff()
    .as(autoDisposable(this))
    .subscribe(s -> ...)
    @tsmith | https://github.com/uber/AutoDispose

    View Slide

  23. Intuitive
    //-------------------Vanilla RXJava----------------
    fun doStuff() {
    subcription = observable.doStuff().subscribe(s -> ...)
    }
    override fun onDestroy() = subscription.unsubscribe()
    //-------------------Autodispose-------------------
    observable.doStuff()
    .as(autoDisposable(this))
    .subscribe(s -> ...)
    @tsmith | https://github.com/uber/AutoDispose

    View Slide

  24. Consistency
    public interface ScopeHandler {
    @CheckReturnValue
    Function, FlowableSubscribeProxy> forFlowable();
    @CheckReturnValue
    Function, ObservableSubscribeProxy> forObservable();
    @CheckReturnValue
    Function, MaybeSubscribeProxy> forMaybe();
    @CheckReturnValue
    Function, SingleSubscribeProxy> forSingle();
    @CheckReturnValue
    Function forCompletable();
    }
    @tsmith | https://github.com/uber/AutoDispose

    View Slide

  25. Composition
    public interface ObservableSubscribeProxy {
    Disposable subscribe();
    Disposable subscribe(Consumer super T> onNext);
    ...
    TestObserver test();
    ...
    }
    @tsmith | https://github.com/uber/AutoDispose

    View Slide

  26. Resilient and Defensive
    @Override public ObservableSubscribeProxy apply(final Observable upstream) {
    return new ObservableSubscribeProxy() {
    @Override public Disposable subscribe() {
    return new AutoDisposeObservable<>(upstream, scope).subscribe();
    }
    ...
    };
    }
    @tsmith | https://github.com/uber/AutoDispose

    View Slide

  27. Flexibility
    public interface LifecycleScopeProvider {
    Observable lifecycle();
    Function correspondingEvents();
    E peekLifecycle();
    }
    @tsmith | https://github.com/uber/AutoDispose

    View Slide

  28. Flexibility
    dependencies {
    implementation 'com.uber.autodispose:autodispose-android:x.y.z'
    implementation 'com.uber.autodispose:autodispose-android-archcomponents:x.y.z'
    implementation 'com.uber.autodispose:autodispose-kotlin:x.y.z'
    implementation 'com.uber.autodispose:autodispose-rxlifecycle:x.y.z'
    }
    @tsmith | https://github.com/uber/AutoDispose

    View Slide

  29. Testability
    dependencies {
    implementation 'com.uber.autodispose:autodispose-android-archcomponents:x.y.z'
    testImplementation 'com.uber.autodispose:autodispose-android-archcomponents-test:x.y.z'
    }
    TestLifecycleOwner lifecycle = TestLifecycleOwner.create();
    subject.as(autoDisposable(from(lifecycle))).subscribe(o);
    lifecycle.emit(Lifecycle.Event.ON_CREATE);
    ...
    lifecycle.emit(Lifecycle.Event.ON_DESTROY);
    subject.onNext(1);
    o.assertNoMoreEvents();
    @tsmith | https://github.com/uber/AutoDispose

    View Slide

  30. Debugability
    public final class AutoDisposePlugins {
    public static void lockdown() {
    lockdown = true;
    }
    public static void setOutsideLifecycleHandler(
    @Nullable Consumer super OutsideLifecycleException> handler) {
    if (lockdown) {
    throw new IllegalStateException("Plugins can't be changed anymore");
    }
    outsideLifecycleHandler = handler;
    }
    }
    @tsmith | https://github.com/uber/AutoDispose

    View Slide

  31. Documentation
    /**
    * Entry point for auto-disposing streams from a {@link ScopeProvider}.
    *
    * Example usage:
    *
    * Observable.just(1)
    * .as(AutoDispose.autoDisposable(scope))
    * .subscribe(...)
    *
    *
    * @param provider the target scope provider
    * @param the stream type.
    * @return an {@link AutoDisposeConverter} to transform with operators like
    * {@link Observable#as(ObservableConverter)}
    */
    public static AutoDisposeConverter autoDisposable(final ScopeProvider provider) {...}
    @tsmith | https://github.com/uber/AutoDispose

    View Slide

  32. Example Code
    @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // Using automatic disposal, this should determine that the correct time to
    // dispose is onDestroy (the opposite of onCreate).
    Observable.interval(1, TimeUnit.SECONDS)
    .doOnDispose((value) -> {
    Log.i(TAG, "Disposing subscription from onCreate()"))
    })
    .as(autoDisposable(from(this)))
    .subscribe((value) -> {
    Log.i(TAG, "Started in onCreate(), running until onDestroy(): " + num);
    });
    }
    @tsmith | https://github.com/uber/AutoDispose

    View Slide

  33. @tsmith

    View Slide

  34. Quality
    Primum non nocere
    @tsmith

    View Slide

  35. Quality
    Stability
    @tsmith

    View Slide

  36. Performance
    @tsmith

    View Slide

  37. Size
    @tsmith| source: https://www.youtube.com/watch?v=CVQ8cg_WIwY

    View Slide

  38. Data usage
    @tsmith

    View Slide

  39. Transitive Dependencies
    @tsmith

    View Slide

  40. @tsmith

    View Slide

  41. Releases
    @tsmith

    View Slide

  42. Semantic Versioning - X.Y.Z
    Decimal Use Example
    X - Major API Change Changed Public
    Method Name
    Y _ Minor Feature Added New
    Functionality
    Z - Patch Fix Fixed Crash
    @tsmith

    View Slide

  43. Changelogs
    @tsmith

    View Slide

  44. Deprecation
    — Be thoughtful about
    introducing new APIs
    — Respect semantic versioning
    — Mark methods as deprecated
    — Set expected timeline or
    version for removal
    — Incentivize updates
    @tsmith

    View Slide

  45. Deprecation
    /**
    * Extension that proxies to [Observable.as] + [AutoDispose.autoDisposable]
    */
    @Deprecated(
    level = ERROR,
    message = "Replaced with autoDisposable() to match top level APIs.",
    replaceWith = ReplaceWith("autoDisposable(scope)",
    "com.uber.autodispose.kotlin.autoDisposable")
    )
    @CheckReturnValue
    inline fun Observable.autoDisposeWith(scope: Maybe<*>): ObservableSubscribeProxy
    = this.`as`(AutoDispose.autoDisposable(scope))
    @tsmith | https://github.com/uber/AutoDispose

    View Slide

  46. Community
    @tsmith | CC-BY-4.0 - Billie Grace Ward | http://uk.droidcon.com/skillscasts/11019-open-source-and-building-communities

    View Slide

  47. Issues
    @tsmith

    View Slide

  48. Contributors
    @tsmith

    View Slide

  49. Wrap up
    — Developer Product Research
    — Developer Usability Focuses
    — Library Quality Standards
    — Best practices for Releases
    — Managing Communities
    @tsmith

    View Slide

  50. BUILDING FOR
    DEVELOPERS
    Ty Smith
    uber.github.io
    @tsmith

    View Slide