Android
antipatterns
mobile guild
#cododajnia
Bartosz Kosarzycki
@bkosarzycki
Anti-pattern
a common response to a recurring problem that is usually
ineffective [and] usually counter-productive.
Premature optimisation
Donald Knuth
Author 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 be
a better idea...
@IntDef({NAVIGATION_MODE_STANDARD,
NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
Which leaves us
with...
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 {}
}
PROGUARD
DOES IT
FOR 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 RxJava
Maybe Android bindings are enough?
Don’t use reactive:
- button clicks
@Click is probably more concise
- Simple “lookups” from db
Category 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 overcome
this?
@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 coding
Coding 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 Development
Removing 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 flow
Retaining 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!
QUESTIONS
Bartosz Kosarzycki
@bkosarzycki

Android antipatterns