Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

MCE^3 - Adrian Catalan - Android Architecture for the Everyday Developer

148 views

Published on

MVC, MVP, MVVM, Clean and more keywords might sound familiar to you, these describes patterns that helps developers building high quality software by organizing things up. But why bother? why not stick to the classic 'don't fix what ain't broken'? A well planified architected app can speed up the development process and simplify the long term maintainability. It's not enough to keep functions smalls and not building a god-Activity, we need to level-up and design towards clean architecture. This talk will review and discuss MVP and Clean approaches, how to start, and tips on architecting our apps in a compelling way.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

MCE^3 - Adrian Catalan - Android Architecture for the Everyday Developer

  1. 1. Android architecture for the everyday developer Adrián Catalán @ykro
  2. 2. adrian@bitandik.com
  3. 3. RAISE YOUR HAND POLLS
  4. 4. How Andy & I used to do things or common workflow of an Android app ○ Activities & fragments ■ UI tasks :) ■ UI logic (¿?) ■ Database queries (¡!)
  5. 5. WAIT, BUT, WHY? https://www.flickr.com/photos/31997662@N00/10686813595
  6. 6. MAINTAINABILITY https://www.flickr.com/photos/57974696@N00/7993485910/
  7. 7. SCALABILITY https://www.flickr.com/photos/46425925@N00/438253751/
  8. 8. TESTBILITY https://www.flickr.com/photos/27703797@N06/13952482985
  9. 9. LONG-TERM RELIABILITY https://www.flickr.com/photos/92694860@N00/5751130432/
  10. 10. DECOUPLE https://www.flickr.com/photos/14113765@N00/2622333378
  11. 11. SOFTWARE IS ABOUT PEOPLE https://www.flickr.com/photos/53016579@N00/14579648177/
  12. 12. Controller Model View User actionManipulates Notify Update
  13. 13. MVP https://www.flickr.com/photos/53326337@N00/3108535629/
  14. 14. ModelPresenterView User Notify Request data DeliversUpdate UI
  15. 15. Model Presenter View Shows an interface (passive). Obtains data from the model and tells the View how to behave through a notification Handles business logic
  16. 16. View public interface LoginView { void enableInputs(); void disableInputs(); void showProgress(); void hideProgress(); void successLogin(); void failedLogin(String error); }
  17. 17. Implementation @Override public void enableInputs() { setInputs(true); } @Override public void disableInputs() { setInputs(false); } private void setInputs(boolean enabled){ inputEmail.setEnabled(enabled); inputPassword.setEnabled(enabled); buttonSubmit.setEnabled(enabled); } @Override public void showProgress() { progressBar.setVisibility( View.VISIBLE); }
  18. 18. Implementation @Override public void failedLogin( String error) { if (error != null && !error.isEmpty()) { inputEmail.setError(error); } } @Override public void hideProgress() { progressBar.setVisibility( View.GONE); } @Override public void successLogin() { startActivity( new Intent(this, ContentActivity.class )); }
  19. 19. Activity public class LoginActivity extends AppCompatActivity implements LoginView { LoginPresenter presenter; @Override protected void onCreate(Bundle savedInstanceState) { ... presenter = new LoginPresenterImpl(this); } @Override protected void onDestroy() { presenter.onDestroy(); super.onDestroy(); } }
  20. 20. Activity public class LoginActivity extends AppCompatActivity implements LoginView { ... @OnClick(R.id.email_sign_in_button) public void login(){ presenter.login(inputEmail.getText().toString(), inputPassword.getText().toString()); } }
  21. 21. Presenter public interface LoginPresenter { void onDestroy(); void login(String email, String password); }
  22. 22. http://fullhdpictures.com/pug-hq-photos.html/smiling-pug-wallpaper
  23. 23. Presenter public interface LoginPresenter { void onDestroy(); void login(String email, String password); }
  24. 24. Implementation public class LoginPresenterImpl implements LoginPresenter { LoginView view; LoginModel model; public LoginPresenterImpl(LoginView view) { this.view = view; this.model = new LoginModelImpl(this); } @Override public void onDestroy() { view = null; } }
  25. 25. Implementation public class LoginPresenterImpl implements LoginPresenter, LoginTaskListener { ... @Override public void login(String email, String password) { if (this.view != null) { view.disableInputs(); view.showProgress(); model.login(email, password); } }
  26. 26. Model-Presenter Interface public interface LoginTaskListener { void loginSuccess(); void loginError(String error); }
  27. 27. Presenter @Override public void loginSuccess(){ if (this.view != null) { view.enableInputs(); view.hideProgress(); view.successLogin(); } } @Override public void loginError(String error) { if (this.view != null) { view.enableInputs(); view.hideProgress(); view.failedLogin(error); } }
  28. 28. Model public interface LoginModel { void login(String user, String password); }
  29. 29. Implementation public class LoginModelImpl implements LoginModel { LoginTaskListener listener; public LoginModelImpl(LoginTaskListener listener) { this.listener = listener; } @Override public void login(String user, String password) { ... } }
  30. 30. EVENT BUS https://www.flickr.com/photos/92622665@N08/9193171612
  31. 31. Using the library public class LoginEvent { public final static int ERROR = 0; public final static int SUCCESS = 1; int type; String error; ... }
  32. 32. Presenter @Override public void onCreate() { eventBus.register(this); } @Override public void onDestroy() { view = null; eventBus.unregister(this); }
  33. 33. Presenter @Subscribe public void onEventMainThread(LoginEvent event){ if (this.view != null) { view.enableInputs(); view.hideProgress(); if (event.getType() == LoginEvent.SUCCESS) { view.successLogin(); } else if (event.getType() == LoginEvent.ERROR){ view.failedLogin(event.getErrror()); } } }
  34. 34. Model LoginEvent event = new LoginEvent(); if (...) { event.setType(LoginEvent.SUCCESS); } else { event.setType(LoginEvent.ERROR); event.setError("failed"); } eventBus.post(event);
  35. 35. CLEAN https://www.flickr.com/photos/24628543@N00/5523923392/
  36. 36. View Presenter Presenter Interactor Interactor Interactor Interactor Repository Repository Data Source Data Source Data Source
  37. 37. Data Source Interactor Database, APIs, etc Connects UI with data, regardless of source and rendering. Repository Connects with data sources and gets the data.
  38. 38. Interactor public interface NumbersInteractor { void getNumbers(); } public interface WordsInteractor { void getWords(); }
  39. 39. Numbers interactor public class NumbersInteractorImpl implements NumbersInteractor { ContentRepository contentRepository; public NumbersInteractorImpl() { contentRepository = ContentRepositoryImpl.getInstance(); } @Override public void getNumbers() { contentRepository.getNumbers(); } }
  40. 40. Words interactor public class WordsInteractorImpl implements WordsInteractor { ContentRepository contentRepository; public WordsInteractorImpl() { contentRepository = ContentRepositoryImpl.getInstance(); } @Override public void getWords() { contentRepository.getWords(); } }
  41. 41. Presenter @Override public void getWords() { WordsInteractor interactor = new WordsInteractorImpl(); interactor.getWords(); } @Override public void getNumbers() { NumbersInteractor interactor = new NumbersInteractorImpl(); interactor.getNumbers(); }
  42. 42. Repository public interface ContentRepository { void getNumbers(); void getWords(); }
  43. 43. Implementation public class ContentRepositoryImpl implements ContentRepository { … @Override public void getNumbers() { String[] data = {"1", "2", "3"}; ContentEvent event = new ContentEvent(); event.setData(Arrays.asList(data)); eventBus.post(event); } }
  44. 44. Implementation public class ContentRepositoryImpl implements ContentRepository { … @Override public void getWords() { String[] data = {"a", "b", "c"}; ContentEvent event = new ContentEvent(); event.setData(Arrays.asList(data)); eventBus.post(event); } }
  45. 45. Useful links https://blog.8thlight.com/uncle-bob/2012/08/13/the- clean-architecture.html https://github.com/googlesamples/android-architecture
  46. 46. Useful links https://github.com/Karumi/Rosie https://github.com/ykro/simplemvp
  47. 47. adrian@bitandik.com
  48. 48. Android architecture for the everyday developer Adrián Catalán @ykro

×