5 steps to clean your android code
DESCRIPTION
Most Android apps follow the same pattern: a RESTful third-party service provides information represented as JSON and XML, and your task is to present that information and to communicate user actions to the service. Designing and understanding the way data flows into your architecture usually result in a much cleaner codebase. Here you'll be presented 5 useful insights that will help you write code that is a pleasure to read, easy to test and fun to change.TRANSCRIPT
5 Steps To Clean Your Android Code
+Frankie Sardo
Enchant me.Simplify my life.
Make me amazing.
Android UI Design Principles
Android Software Design Principles
?
Clean Code is UX for Software
#1
Model Objects
Automatic mapping is tempting
Keep you objects in shapeclass Event { private final String name; private final Location where; private final DateRange duration; private final Type type;
public Event(String name, Location where, DateRange when, Type type) { this.name = name; this.where = where; this.duration = when; this.type = type; if (name.isEmpty()) { throw new IllegalArgumentException("Event name is empty"); } if (type == WORKSHOP && when.includes(27TH_MARCH )) { throw new IllegalArgumentException("Workshops are scheduled after 27th of March"); } }
public boolean clashesWith(Event otherEvent) { return duration.overlaps(otherEvent.duration) && where.equals(otherEvent.where); }}
#2
External Services
Responses are unpredictable
Abstract over external APIs
#3
Business Logic
Concurrency is hard
Define your user storiesclass SearchRepositoriesScenario implements Scenario {
final SearchRepositoriesPresentation presentation; final GithubApi githubApi; final SearchRepositoriesRequest request; final Database database;
public SearchRepositoriesScenario(...) { ... }
public void run() { presentation.showLoading(); String keyword = request.getKeyword(); Repositories repositories = githubApi.searchRepositories(keyword); SearchRepositoriesResponse response = from(repositories); database.persist(response); presentation.updateList(response); presentation.hideLoading(); }
}
Keep modules loosely coupled
#4
Boilerplate code
Android code is verbose
Say what you meanclass SearchRepositoriesActivity extends ListActivity {
@Inject SearchRepositoriesController controller; @Icicle String query; // github.com/frankiesardo/icepick
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); handleIntent(getIntent()); controller.displaySearch(query); }
protected void onNewIntent(Intent intent) { super.onNewIntent(intent); handleIntent(intent); }
private void handleIntent(Intent intent) { if (Intent.ACTION_SEARCH.equals(intent.getAction())) { query = intent.getStringExtra(SearchManager.QUERY); controller.startSearch(query); } } public boolean onCreateOptionsMenu(Menu menu) { return MenuHelper.inflate(getMenuInflater()).search() .up(ParentActivity.class).help().into(menu); }}
#5
Unit test
Tests constrain your design
Practice makes perfect
Q&A Time
#gaagbtgithub/frankiesardo
novoda/blog