Android antipatterns

Post on 11-Jan-2017

56 views 6 download

transcript

Androidantipatterns

mobile guild#cododajnia

Bartosz Kosarzycki@bkosarzycki

Anti-patterna common response to a recurring problem that is usually ineffective [and] usually counter-productive.

Premature optimisation

Donald KnuthAuthor of “The Art of Computer Programming”

Sir Tony Hoare

Quick Sort, Null-reference,Hoare logic

Donald Knuth:

For those who don't work to strict memory or CPU cycle limits, PrematureOptimization is an AntiPattern, since there is only cost and no benefit. For those who do, it is often confused with poor coding, or with misguided attempts at writing optimal code.

Quotes original author is still questioned.

“We should forget about small efficiencies, say about 97% of the time”

LET’S REMOVE ALL ENUMS!

WHY?

Enums have obvious benefits:- make the code more self-documenting- the compiler can assign default values to

enumerator automatically- prevents the programmer from writing illogical

code - e.g. multiplying enums?- IDEs, type checking, correctness etc.

Change it to integers?

public class View {public static final int VISIBLE = 0x00000000;public static final int INVISIBLE = 0x00000004;public static final int GONE = 0x00000008;

}

https://developer.android.com/reference/android/support/annotation/IntDef.html

@IntDef would bea better idea...

@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})

Which leaves uswith...public class View {

public static final int VISIBLE = 0x00000000;public static final int INVISIBLE = 0x00000004;public static final int GONE = 0x00000008;

@IntDef({VISIBLE, INVISIBLE, GONE})@Retention(RetentionPolicy.SOURCE)public @interface Visibility {}

}

PROGUARDDOES ITFOR US!

-keep public enum

android-how-to-keep-enum-from-proguard [link]

proguard-wont-keep-a-class-members-enums [link]

Proguard config

#keep enum classes-keep public enum com.intive.nearbyplaces.model.ApiProviderType** { **[] $VALUES; public *;}

You can also keep the enums...

Silver-bullet

LET’S DO EVERYTHING REACTIVE

If you don’t need it - don’t use it!

Library Method count

Butterknife 119

Retrofit2 402

Realm 2343

com.google.android 9651

Glide 2364

Kotlin 5090

RxJava + RxBinding + RxPref + RxLoc + RxTuples

5319 + 758 + 90 + 176 + 137 = 6480

Hawk 121

RxJava is heavy on android

*without proguard

Use reactive:

- Constant flow of data - “Instant” search cases

Debounce(), throttleFirst()

- Reflecting settings in UI ?

It’s NOT only RxJavaMaybe Android bindings are enough?

Don’t use reactive:

- button clicks @Click is probably more concise

- Simple “lookups” from dbCategory category = Category.forId(263);

- Large, expensive, cached objects

Duplication

RxJava

Duplication of reactive approaches

EventBus

EventBus

Don’t use a separate library - both approaches are reactive!

/*** Rx-style Event bus. Each event type implements its own subscription methods.*/public class RxEventBus { private static RxEventBus instance;

private PublishSubject<Location> mGpsLocationEvents = PublishSubject.create();

public static RxEventBus instanceOf() { if (instance == null) { instance = new RxEventBus(); } return instance; }

/** * Pass events of LOCATION type down to event listeners. */ public void newLocationEvent(Location location) { mGpsLocationEvents.onNext(location); }

/** * Subscribe to this LOCATION type Observable. On event Action will be called. */ public Observable<Location> getLocationEvents() { return mGpsLocationEvents; }}

Nullpointer hell

@NonNull

Java is not null-safe

@NonNull

How can we overcomethis?

@NonNull

- We could use a higher order language like Kotlin/Scala/Dart

- Optional<Type>- Annotations @NonNull @Nullable

@NonNull

funtion add(@NonNull Square s1, @NonNull Square s2) {

}

@NonNull

funtion add(@NonNull Square s1, @NonNull Square s2) {

}

TEDIOUS!

@NonNull

Let’s assume parameters and return values are NonNull by default

@NonNull

file: package-info.java

@ParametersAreNonnullByDefault@ReturnValuesAreNonnullByDefault

package com.intive.nearbyplaces;

Gradle tasks for generating these files:download, download

Antipatterns summary

- Premature optimization- Silver bullet - Duplication- Nullpointer hell

Other Antipatterns Superstitious codingCoding to handle error conditions which are already known to be impossible.

Reinventing the square wheel/ Not Invented Here (NIH)Failing to adopt an existing solution and instead adopting a custom solution which performs much worse than the existing one Tester Driven DevelopmentRemoving the determination of requirements and letting the testers (or the QA team) drive what they think the software should be through the testing (or QA) process.

Lava flowRetaining undesirable (redundant or low-quality) code because removing it is too expensive

Links

- Premature optimization is the root of all evil - Donald Knuth link- The antipattern catalogue Donald Knuth - link- The price of enums Android Developers - link- AntiPatterns: Refactoring Software, Architectures, and Projects in

Crisis link- When not to use reactive - link- NonNull gradle task generator - link, link

Thank you!

QUESTIONSBartosz Kosarzycki@bkosarzycki