Post on 16-Jul-2015
transcript
Clean Code on Android!
DroidCon DubaiDanny Preussler
Groupon
The Living Room, Colin and Sarah Northway, CC by 2.0 h<ps://www.flickr.com/photos/apes_abroad/1479254938
Groupon is the global leader in local commerce,
making it easy for people around the world to search !and discover great businesses at unbeatable prices.
Source: Internal data,, March 2014
WORLDWIDE!
260M+ subscribers 53.9M active customers 500+ markets 900M+ deals sold
2
$5B+ in annual billings 12,000+ global employees
Leading the way in mobile commerce
Our mobile app is available in 43 countries.
Groupon’s vibrant mobile marketplace connects!consumers with their local economy
3 Sources: Internal Data; iTunes ranking for US stores available here - https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewFeature?id=500873243&mt=8&v0=www-itunes25Bcountdown-appstore
Nearly 110 million people worldwide have downloaded our mobile app at the end of Q4 2014.
One of the 25 most downloaded free apps of all time
More than 50% of our Global transactions were completed on a mobile device by the end of Q4 2014
SOLID FOUNDATION
Flughafen Berlin-Brandenburg, Blick in die Abflughalle by Muns CC BY 3.0 http://commons.wikimedia.org/wiki/File:120513-BER-innen.JPG
violating the most basics
principles of Software Engineering!
flickr.com/photos/cobblucas/4831501753, Stop by Lucas Cobb, CC by 2.0
Separation of concerns (1974)!
• Modularize, Encapsulate, Layer! Example: Don‘t do HTTP request in Activities/Fragments!
flickr.com/photos/ionics/6337522871, Black Sheep Meets White Sheep by Leon Riskin, CC by 2.0
Don‘t !repeat !ourself!!
Boris Bikes DLR, Les Haines, CC by 2.0 flickr.com/photos/leshaines123/8370292862
ViolaTons of DRY are typically referred to as WET soluTons, which is commonly taken to stand for either "write everything twice" or "we enjoy typing” (h<p://en.wikipedia.org/wiki/Don't_repeat_yourself)
Android Firewall by Uncalno, CC BY 2.0 flickr.com/photos/uncalno/8538679708
Clean Code!!
The Living Room, Colin and Sarah Northway, CC by 2.0 h<ps://www.flickr.com/photos/apes_abroad/1479254938
Clean Code by
Robert C. Mar0n
Robert C. Martin – Clean Code!
The Living Room, Colin and Sarah Northway, CC by 2.0 h<ps://www.flickr.com/photos/apes_abroad/1479254938
Uncle Bob says:
(Keep it) small!
Robert C. Martin – Clean Code!
The Living Room, Colin and Sarah Northway, CC by 2.0 h<ps://www.flickr.com/photos/apes_abroad/1479254938
Uncle Bob says:
Do One Thing!
Robert C. Martin – Clean Code!
The Living Room, Colin and Sarah Northway, CC by 2.0 h<ps://www.flickr.com/photos/apes_abroad/1479254938
Uncle Bob says:
One Level of Abstrac0on per Func0on!
Robert C. Martin – Clean Code!
The Living Room, Colin and Sarah Northway, CC by 2.0 h<ps://www.flickr.com/photos/apes_abroad/1479254938
Uncle Bob says:
Reading Code from Top to BoHom
Robert C. Martin – Clean Code!
The Living Room, Colin and Sarah Northway, CC by 2.0 h<ps://www.flickr.com/photos/apes_abroad/1479254938
Uncle Bob says:
Comments Do Not Make Up for Bad Code
Robert C. Martin – Clean Code!
The Living Room, Colin and Sarah Northway, CC by 2.0 h<ps://www.flickr.com/photos/apes_abroad/1479254938
Uncle Bob says:
Avoid switch It’s [..] hard to make a switch statement that does one thing.
By their nature, switch statements always do N things.
Much more...!
The Living Room, Colin and Sarah Northway, CC by 2.0 h<ps://www.flickr.com/photos/apes_abroad/1479254938
A must Read!
Code sm
ells....!
Sintra, Portugal, The smell of the portuguese wine, CC by 2.0, flickr.com/photos/pedrosimoes7/169983321
Si_ng in a Tree, Big Bend NaTonal Park by Adam Baker, CC by 2.0, flickr.com/photos/atbaker/5474766579
Watch out for !Primitive
Obsession!
Ban null !from !
your code!!
nothing is nothing by darwin Bell, CC by 2.0, flickr.com/photos/darwinbell/272818496
private MyParcelable myParceable;
... Bundle bundle = getArguments();
if (bundle != null) {
myParceable = bundle.getParcelable("ARGUMENT"); } ....
if (myParcaeable != null) { ...
} ...
if (myParcaeable != null) { ...
}
Don‘t:!
Red Stop Bu<on by Ben K Adams, CC by 2.0, flickr.com/photos/schtumple/5475697999
Cleaner by atomicjeep, CC by 2.0, flickr.com/photos/atomicjeep/144719649
Do: Inject Dependencies!
private MyParcelable myParceable = MyParceable.NONE;
... Bundle bundle = getArguments();
if (bundle != null && bundle.hasParceable(„ARGUMENT“) { myParceable = bundle.getParcelable("ARGUMENT");
} ....
if (myParcaeable != null) { ... }
... if (myParcaeable != null) { ...
}
The power of Dependency
Injection!
• Don‘t create dependencies
• Invert Control!
• Inject them!
I love the Light & I dig the Sun by fady habib, CC by 2.0, flickr.com/photos/unTtlism/2609684221
public class WetFragment extends Fragment {
MyController controller; ...
@Override public void onAttach(Activity activity) {
super.onAttach(activity); controller =
new MyController(activity.getApplicationContext());
Don‘t:!
Red Stop Bu<on by Ben K Adams, CC by 2.0, flickr.com/photos/schtumple/5475697999
Cleaner by atomicjeep, CC by 2.0, flickr.com/photos/atomicjeep/144719649
public class DryFragment extends Fragment {
@Inject MyController controller; ...
@Override public void onAttach(Activity activity) {
super.onAttach(activity); controller =
new MyController(activity.getApplicationContext());
Do: Inject Dependencies!
public class WetFragment extends Fragment {
EditText myEditField;
@Override
public View onCreateView(LayoutInflater inflater, ...) { View view = inflater.inflate(......
myEditField = (EditText)view.findViewById(R.id.edit1); ...
Don‘t:!
Red Stop Bu<on by Ben K Adams, CC by 2.0, flickr.com/photos/schtumple/5475697999
Cleaner by atomicjeep, CC by 2.0, flickr.com/photos/atomicjeep/144719649
public class DryFragment extends Fragment {
@Inject(R.id.edit1) EditText myEditField;
@Override
public View onCreateView(LayoutInflater inflater, ...) { View view = inflater.inflate(......
myEditField = (EditText)view.findViewById(R.id.edit1); ...
Do: Inject views!
public class WetFragment extends Fragment {
private MyParcelable myParceable;
@Override
public void onAttach(Activity activity) { super.onAttach(activity);
Bundle bundle = getArguments(); if (bundle != null) { myParceable = bundle.getParcelable("ARGUMENT"); if (myParceable == null) { myParceable = MyParcelable.NONE; } } }
Don‘t:!
Red Stop Bu<on by Ben K Adams, CC by 2.0, flickr.com/photos/schtumple/5475697999
Cleaner by atomicjeep, CC by 2.0, flickr.com/photos/atomicjeep/144719649
public class DryFragment extends Fragment {
@Inject(„ARGUMENT“) MyParcelable = myParceable.NONE;
@Override
public void onAttach(Activity activity) { super.onAttach(activity);
Bundle bundle = getArguments(); if (bundle != null) { myParceable = bundle.getParcelable("ARGUMENT"); if (myParceable == null) { myParceable = MyParcelable.NONE; } } }
Do: Inject arguments / extras!
public class WetFragment extends Fragment {
@Override public View onCreateView(LayoutInflater inflater, ...) {
return inflater.inflate( R.layout.main_layout, container, false);
}
Don‘t:!
Red Stop Bu<on by Ben K Adams, CC by 2.0, flickr.com/photos/schtumple/5475697999
Cleaner by atomicjeep, CC by 2.0, flickr.com/photos/atomicjeep/144719649
@InjectLayout(R.layout.main_layout) public class DryFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ...) {
return inflater.inflate( R.layout.main_layout, container, false);
}
Do: Inject layout!
Cleaner by atomicjeep, CC by 2.0, flickr.com/photos/atomicjeep/144719649
@InjectLayout(R.layout.main_layout) public class DryFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ...) {
return inflater.inflate( R.layout.main_layout, container, false);
}
Do: auto (find) layout!
Simply have dry_fragment.xml or dry.xml
© Biblioarchive, CC by 2.0, www.flickr.com/photos/lac-‐bac/4679195538
• Dagger github.com/square/dagger
• Butterknife github.com/JakeWharton/butterknife
• InjectExtra github.com/stephanenicolas/injectextra
• Autolayout github.com/dpreussler/android-autolayout
How to Do:!
© Biblioarchive, CC by 2.0, www.flickr.com/photos/lac-‐bac/4679195538
• RoboGuice github.com/roboguice/roboguice
• Android-Dart github.com/f2prateek/android-dart
• Spring Android github.com/spring-projects/spring-android
• Transfuse github.com/johncarl81/transfuse
• Android Annotations github.com/excilys/androidannotations
Alternative or more Do‘s!
Complicated, Rohit Ma<oo, CC by 2.0, flickr.com/photos/mar00ned/229903286
@Override public void onResume() { super.onResume();
getFragmentManager() .beginTransaction() .add(R.id.fragments, new WetFragment()) . commitAllowingStateLoss();
}
Dont: write untestable code:!
test (c) DaveBleasdale, CC by 2.0, www.flickr.com/photos/sidelong/246816211
Do: write testable code:!
@Inject MyTransactionUtil transactions; @Override
public void onResume() { super.onResume(); transactions.addAllowingStateLoss( R.id.fragments, new WetFragment()); }
• Split your Activities
• Alternative Mortar github.com/square/mortar
Do: use the Power of Fragments!
the icon (CC) by MarTn Fisch, CC by 2.0, flickr.com/photos/marfis75/7164769781
h<ps://w
iki.jen
kins-‐ci.org/disp
lay/JENKINS/Do
t+Jenkins+Ci+D
ot+O
rg
Continuous Code Checks...!
Clean = feel good!!The Living Room, Colin and Sarah Northway, CC by 2.0
h<ps://www.flickr.com/photos/apes_abroad/1479254938