Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Intro Five Android Architecture

Intro Five Android Architecture

Introduction to the modification of the Clean Architecture that we use at Five Agency during our Android development

tomislavhoman

September 29, 2016
Tweet

More Decks by tomislavhoman

Other Decks in Programming

Transcript

  1. Overview • Earlier fails • General Clean Architecture • Clean

    Adjusted for Android • Is it better? • No code, just philosophy
  2. Software Architecture • “Intellectually graspable” abstraction of a complex system

    (wiki) • (which helps us plan, design and construct software)
  3. Software Architecture • “Intellectually graspable” abstraction of a complex system

    (wiki) • Multitude of stakeholders • Separation of concerns - one reason to change • Run away from the real world (Android, DB, Internet) • Testability • SRP + Testability + … = Maintainability, Scalability, etc...
  4. The olden times - God activity public final class UsersActivity

    extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //... new ListUsers().execute(); } private final class ListUsers extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... voids) { // final SQLiteOpenHelper sqLiteOpenHelper = ... // JsonObjectRequest jsObjRequest = new JsonObjectRequest // (Request.Method.GET, url, null, new Response.Listener<JSONObject>() { // MySingleton.getInstance(this).addToRequestQueue(jsObjRequest); // showData(user); return null; } } }
  5. The olden times - God activity public final class UsersActivity

    extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //... new ListUsers().execute(); } private final class ListUsers extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... voids) { // final SQLiteOpenHelper sqLiteOpenHelper = ... // JsonObjectRequest jsObjRequest = new JsonObjectRequest // (Request.Method.GET, url, null, new Response.Listener<JSONObject>() { // MySingleton.getInstance(this).addToRequestQueue(jsObjRequest); // showData(user); return null; } } }
  6. The olden times - God activity public final class UsersActivity

    extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //... new ListUsers().execute(); } private final class ListUsers extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... voids) { // final SQLiteOpenHelper sqLiteOpenHelper = ... // JsonObjectRequest jsObjRequest = new JsonObjectRequest // (Request.Method.GET, url, null, new Response.Listener<JSONObject>() { // MySingleton.getInstance(this).addToRequestQueue(jsObjRequest); // showData(user); return null; } } } NOT testable
  7. The olden times - God activity public final class UsersActivity

    extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //... new ListUsers().execute(); } private final class ListUsers extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... voids) { // final SQLiteOpenHelper sqLiteOpenHelper = ... // JsonObjectRequest jsObjRequest = new JsonObjectRequest // (Request.Method.GET, url, null, new Response.Listener<JSONObject>() { // MySingleton.getInstance(this).addToRequestQueue(jsObjRequest); // showData(user); return null; } } } NOT testable Stakeholders?
  8. The olden times - God activity public final class UsersActivity

    extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //... new ListUsers().execute(); } private final class ListUsers extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... voids) { // final SQLiteOpenHelper sqLiteOpenHelper = ... // JsonObjectRequest jsObjRequest = new JsonObjectRequest // (Request.Method.GET, url, null, new Response.Listener<JSONObject>() { // MySingleton.getInstance(this).addToRequestQueue(jsObjRequest); // showData(user); return null; } } } NOT testable Stakeholders? SRP?
  9. The olden times - God activity public final class UsersActivity

    extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //... new ListUsers().execute(); } private final class ListUsers extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... voids) { // final SQLiteOpenHelper sqLiteOpenHelper = ... // JsonObjectRequest jsObjRequest = new JsonObjectRequest // (Request.Method.GET, url, null, new Response.Listener<JSONObject>() { // MySingleton.getInstance(this).addToRequestQueue(jsObjRequest); // showData(user); return null; } } } NOT testable Stakeholders? SRP? Mixed with Android!
  10. The olden times - MVP + Managers • Sorta OK

    Manager this Manager that SRP - meh ok
  11. The olden times - MVP + Managers • Sorta OK

    Manager this Manager that SRP - meh ok Stakeholders
  12. The olden times - MVP + Managers • Sorta OK

    Manager this Manager that SRP - meh ok Stakeholders Mixed with Android!
  13. The olden times - MVP + Managers • Sorta OK

    Manager this Manager that SRP - meh ok Stakeholders Mixed with Android! Testable-ish Tend to be HUGE!!!
  14. All dependencies go to the database Core of the app

    3 tier Clean All dependencies go to the business layer Abstraction Business is the core of the app
  15. Entities • AKA Domain Objects, Business Objects • No interaction

    with the gritty details, no database, no Internet • Simple business logic constrained to itself or its children • Immutable • No persistence methods (stay tuned)
  16. Entities Example: News app with user subscriptions • Category •

    Article • Commercial • User • Subscription
  17. Use Cases • AKA Interactors, Business Services • Small piece

    of business logic acting on one or more entities • Must be able to describe its job by using common language (no details) • Don’t skip use cases
  18. Use Cases Example: Transfer money to account use case •

    Load two accounts • Do some validation • If OK transfer money • Save the changes Note the simple common language
  19. Repositories • Perform CRUD operations on entities • Additionally: filtering,

    aggregate operations, etc… • Repository is abstract (output port) • Concrete implementation in outer layers (DAO, API, Cache, Combination) • Can handle entity’s whole object tree
  20. Presenters • Always have accompanied view • Gather info and

    send them to view • Don’t know concrete view implementation (view as output port) • But tied to its lifecycle • User input delegated to presenters • Usually map entities to viewmodels
  21. Presenters Example: Screen showing details of an account - abstraction

    View • onTransactionButtonClicked • onUserItemSelected • setUserListPanelVisible • setGenderBoxEnabled Presenter • doTransaction • selectUser • showUsers • activateGenderView
  22. Device • Gritty Android stuff • NOT Db, Internet or

    UI - separate component • Sensors, alarms, notifications, players, etc… • Define wrappers around Android objects in Device component • Define interface that wrapper will be implementing in domain component to serve as an output port
  23. DB & API • Also access to the real world

    • This time real world are a database and the Internet • Classes such as SQLiteOpenHelper, DbModels, DAOs, Retrofit interfaces and services, API models, JSON parsers… • If you are using database only, DAO can implement a repository • Inner layers use entities, so you should also return entities -> mappers
  24. UI

  25. UI • Android classes used for interacting with user via

    display • Fragments, Activities, Adapters, Views, Animations, etc… • Display logic only
  26. Is it better? Manager this Manager that SRP - meh

    ok Stakeholders Mixed with Android! Testable-ish
  27. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ...
  28. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ... UI
  29. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ... UI Domain
  30. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ... UI Data Domain
  31. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ... UI Device Data Domain
  32. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ... UI Device Outer world Data Domain
  33. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ... UI Device Outer world Data Domain SRP
  34. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ... SRP
  35. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ... SRP
  36. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ... SRP Not mixed with Android!
  37. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ... SRP Not mixed with Android!
  38. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ... SRP Not mixed with Android!
  39. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ... SRP Testable Not mixed with Android!
  40. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ... SRP Testable Not mixed with Android!
  41. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ... SRP Testable Not mixed with Android! UI designer cares about this
  42. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ... SRP Testable Not mixed with Android! UI designer cares about this UX designer cares about this
  43. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ... SRP Testable Not mixed with Android! UI designer cares about this UX designer cares about this BA, QA, PM care about this
  44. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ... SRP Testable Not mixed with Android! UI designer cares about this UX designer cares about this BA, QA, PM care about this Nobody cares about this
  45. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ... SRP Testable Not mixed with Android! UI designer cares about this UX designer cares about this BA, QA, PM care about this Backend guys care about this Nobody cares about this
  46. Is it better? Use case 1 Use case 2 Use

    case 3 ... Repository Location Notifications ... SRP Testable Not mixed with Android! Stakeholders are satisfied