SlideShare une entreprise Scribd logo
1  sur  41
Télécharger pour lire hors ligne
My way to clean Android v2
Christian Panadero
http://panavtec.me
@PaNaVTEC
Github - PaNaVTEC
My Way to clean Android
V2
My way to clean Android v2
Acknowledgements
Fernando Cejas
Jorge Barroso
Pedro Gomez
Sergio Rodrigo
@fernando_cejas
@flipper83
@pedro_g_s
@srodrigoDev
Android developer @ Sound CloudAndroid developer @ Karumi
Cofounder & Android expert @ Karumi
Android developer @ Develapps
Alberto Moraga
Carlos Morera
@albertomoraga
@CarlosMChica
iOS Developer @ Selltag
Android Developer @ Viagogo
My way to clean Android v2
“My way to clean Android”
My way to clean Android v2
• Independent of Frameworks
• Testable
• Independent of UI
• Independent of Database
• Independent of any external agency
Why clean architecture?
My way to clean Android v2
• Command pattern (Invoker, command, receiver)
• Decorator Pattern
• Interactors / Use cases
• Abstractions
• Data Source
• Repository
• Annotation Processor
Concepts
My way to clean Android v2
Abstraction levels
Presenters
Interactors
Entities
Repository
Data sources
UI
Abstractions
My way to clean Android v2
The dependency rule
Presenters
Interactors
Entities
Repository
Data sources
UI
Abstractions
My way to clean Android v2
• App (UI, DI and implementation details)
• Presentation
• Domain y Entities
• Repository
• Data Sources
Thinking in projects
My way to clean Android v2
Project dependencies
App
Presenters Domain Data
Entities
Repository
My way to clean Android v2
Flow
View
Presenter
Presenter
Interactor
Interactor
Interactor
Interactor
Repository
Repository
DataSource
DataSource
DataSource
My way to clean Android v2
UI: MVP
ViewPresenter(s)
Model
Events
Fill the view
Actions Actions output
My way to clean Android v2
UI: MVP - View
public class MainActivity extends BaseActivity implements MainView {


@Inject MainPresenter presenter;

@Override protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

presenter.attachView(this);

}


@Override protected void onResume() {

super.onResume();

presenter.onResume();

}



@Override public void onRefresh() {

presenter.onRefresh();

}



}
My way to clean Android v2
UI: MVP - Presenter
public class MainPresenter extends Presenter<MainView> {
public void onResume() {

refreshContactList();

}



public void onRefresh() {

getView().refreshUi();

refreshContactList();

}
}
My way to clean Android v2
UI: MVP - Presenter
@ThreadDecoratedView

public interface MainView extends PresenterView {

void showGetContactsError();



void refreshContactsList(List<PresentationContact> contacts);



void refreshUi();

}
public interface PresenterView {

void initUi();

}
prevents spoiler :D
My way to clean Android v2
• The configuration change is located in UI module, so
solve it in this module
• configurationChange create a new Activity instance
• onRetainCustomNonConfigurationInstance to the rescue!
• Retain the DI graph
onConfigurationChange Hell
My way to clean Android v2
onConfigurationChange Hell
public abstract class BaseActivity extends ActionBarActivity {

@Override protected void onCreate(Bundle savedInstanceState) {

createActivityModule();

}


private void createActivityModule() {

activityInjector = (ActivityInjector)
getLastCustomNonConfigurationInstance();

if (activityInjector == null) {

activityInjector = new ActivityInjector();

activityInjector.createGraph(this, newDiModule());

}

activityInjector.inject(this);

}



@Override public Object onRetainCustomNonConfigurationInstance() {

return activityInjector;

}



protected abstract Object newDiModule();

}
My way to clean Android v2
Presentation - Domain
(ASYNC)
Presenter Invoker
Interactor
Output
Invoker IMP
Interactor
My way to clean Android v2
Presentation - Domain
(SYNC)
Presenter Invoker
Future
Invoker IMP
Interactor
.get();.cancel();
My way to clean Android v2
Presentation - Domain
public class MainPresenter extends Presenter<MainView> {
@Output InteractorOutput<List<Contact>, RetrieveContactsException> output;

public MainPresenter(…) {

InteractorOutputInjector.inject(this);

}
public void onResume() {

interactorInvoker.execute(getContactsInteractor, output);

}
@OnError void onContactsInteractorError(RetrieveContactsException data) {

getView().showGetContactsError();

}
@OnResult void onContactsInteractor(List<Contact> result) {

List<PresentationContact> presentationContacts =
listMapper.modelToData(result);

getView().refreshContactsList(presentationContacts);

}
}
My way to clean Android v2
Domain - Interactor
public class GetContactInteractor implements Interactor<Contact,
ObtainContactException> {



private ContactsRepository repository;

private String contactMd5;



public GetContactInteractor(ContactsRepository repository) {

this.repository = repository;

}



public void setData(String contactMd5) {

this.contactMd5 = contactMd5;

}



@Override public Contact call() throws ObtainContactException {

return repository.obtain(contactMd5);

}

}
My way to clean Android v2
Bye bye thread Hell!
public class DecoratedMainView implements MainView {
@Override public void showGetContactsError() {

this.threadSpec.execute(new Runnable() {

@Override public void run() {

undecoratedView.showGetContactsError();

}

});

}
}
My way to clean Android v2
Bye bye thread Hell!
public abstract class Presenter<V extends PresenterView> {

private V view;

private ThreadSpec mainThreadSpec;



public Presenter(ThreadSpec mainThreadSpec) {

this.mainThreadSpec = mainThreadSpec;

}



public void attachView(V view) {

this.view = ViewInjector.inject(view, mainThreadSpec);

}



public void detachView() {

view = null;

}



public V getView() {

return view;

}

}
My way to clean Android v2
Bye bye thread Hell!
public class MainThreadSpec implements ThreadSpec {



Handler handler = new Handler();



@Override public void execute(Runnable action) {

handler.post(action);

}

}
public abstract class Presenter<V extends PresenterView> {
public void attachView(V view) {

this.view = ViewInjector.inject(view, mainThreadSpec);

}
}
@ThreadDecoratedView

public interface MainView extends PresenterView { … }
My way to clean Android v2
Repository
Network
Data Source
BDD
Data Source
Repository
Model
Data
My way to clean Android v2
Repository Interface
public interface ContactsRepository {


List<Contact> obtainContacts() throws RetrieveContactsException;



Contact obtain(String md5) throws ObtainContactException;


}
My way to clean Android v2
Repository imp
@Override public List<Contact> obtainContacts() throws
RetrieveContactsException {

List<Contact> contacts = null;

try {

contacts = bddDataSource.obtainContacts();

} catch (ObtainContactsBddException … ce) {

try {

contacts = networkDataSource.obtainContacts();

bddDataSource.persist(contacts);

} catch (UnknownObtainContactsException … ue) {

throw new RetrieveContactsException();

} catch (PersistContactsBddException … pe) {

pe.printStackTrace();

}

}

return contacts;

}
My way to clean Android v2
Data source
Model
Data source Imp
Data source
Mapper
My way to clean Android v2
Data source Interface
public interface ContactsNetworkDataSource {



public List<Contact> obtainContacts() throws ContactsNetworkException …;


}
My way to clean Android v2
Data source imp
private ContactsApiService apiService;

private static final Transformer transformer = new
Transformer.Builder().build(ApiContact.class);
@Override public List<Contact> obtainContacts() throws
ContactsNetworkException {

try {

ApiContactsResponse response = apiService.obtainUsers(100);

List<ApiContactResult> results = response.getResults();

List<Contact> contacts = new ArrayList<>();



for (ApiContactResult apiContact : results) {

contacts.add(transform(apiContact.getUser(), Contact.class));

}



return contacts;

} catch (Throwable e) {

throw new ContactsNetworkException();

}

}
My way to clean Android v2
Caching Strategy
public interface CachingStrategy<T> {

boolean isValid(T data);

}
public class TtlCachingStrategy<T extends TtlCachingObject> implements
CachingStrategy<T> {



private final long ttlMillis;



@Override public boolean isValid(T data) {

return (data.getPersistedTime() + ttlMillis) > System.currentTimeMillis();

}



}
My way to clean Android v2
Caching Strategy
@Override public List<Contact> obtainContacts()

throws ObtainContactsBddException … {

try {

List<BddContact> bddContacts = daoContacts.queryForAll();

if (!cachingStrategy.isValid(bddContacts)) {

deleteBddContacts(bddContacts);

throw new InvalidCacheException();

}

ArrayList<Contact> contacts = new ArrayList<>();

for (BddContact bddContact : bddContacts) {

contacts.add(transform(bddContact, Contact.class));

}

return contacts;

} catch (java.sql.SQLException e) {

throw new ObtainContactsBddException();

} catch (Throwable e) {

throw new UnknownObtainContactsException();

}

}
My way to clean Android v2
• Bussines logic doesn’t know where the
data came from
• It’s easy to change data source
implementation
• If you change the data sources
implementation the business logic is not
altered
Repository adavantages
My way to clean Android v2
– Uncle Bob
“Make implementation details
swappable”
My way to clean Android v2
Picasso
public interface ImageLoader {

public void load(String url, ImageView imageView);

public void loadCircular(String url, ImageView imageView);

}
public class PicassoImageLoader implements ImageLoader {

private Picasso picasso;



@Override public void load(String url, ImageView imageView) {

picasso.load(url).into(imageView);

}



@Override public void loadCircular(String url, ImageView imageView) {

picasso.load(url).transform(new CircleTransform()).into(imageView);

}

}
My way to clean Android v2
ErrorManager
public interface ErrorManager {

public void showError(String error);

}
public class SnackbarErrorManagerImp implements ErrorManager {
@Override public void showError(String error) {

SnackbarManager.show(Snackbar.with(activity).text(error));

}
}
public class ToastErrorManagerImp implements ErrorManager {

@Override public void showError(String error) {

Toast.makeText(activity, error, Toast.LENGTH_LONG).show();

}

}
My way to clean Android v2
• ALWAYS Depend upon abstractions, NEVER
depend upon concretions
• Use a good naming, if there's a class you've
created and the naming does not feel right, most
probably it is wrong modeled.
• Create new shapes using the initial dartboard to
ensure that it's placed on the corresponding layer
Tips
My way to clean Android v2
– Uncle Bob
“Clean code. The last programming
language”
My way to clean Android v2
In Uncle Bob we trust
My way to clean Android v2
https://github.com/PaNaVTEC/Clean-Contacts
Show me the
code!
My way to clean Android v2
• Fernando Cejas - Clean way
• Jorge Barroso - Arquitectura Tuenti
• Pedro Gomez - Dependency Injection
• Pedro Gomez - Desing patterns
• Uncle Bob - The clean architecture
• PaNaVTEC - Clean without bus
References
My way to clean Android v2
¿Questions?
Christian Panadero
http://panavtec.me
@PaNaVTEC
Github - PaNaVTEC

Contenu connexe

Tendances

Under the Hood: Using Spring in Grails
Under the Hood: Using Spring in GrailsUnder the Hood: Using Spring in Grails
Under the Hood: Using Spring in GrailsGR8Conf
 
Under the Hood: Using Spring in Grails
Under the Hood: Using Spring in GrailsUnder the Hood: Using Spring in Grails
Under the Hood: Using Spring in GrailsBurt Beckwith
 
Sharper Better Faster Dagger ‡ - Droidcon SF
Sharper Better Faster Dagger ‡ - Droidcon SFSharper Better Faster Dagger ‡ - Droidcon SF
Sharper Better Faster Dagger ‡ - Droidcon SFPierre-Yves Ricau
 
A friend in need - A JS indeed
A friend in need - A JS indeedA friend in need - A JS indeed
A friend in need - A JS indeedYonatan Levin
 
Advanced Dagger talk from 360andev
Advanced Dagger talk from 360andevAdvanced Dagger talk from 360andev
Advanced Dagger talk from 360andevMike Nakhimovich
 
Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Fabio Collini
 
Refactor to Reactive With Spring 5 and Project Reactor
Refactor to Reactive With Spring 5 and Project ReactorRefactor to Reactive With Spring 5 and Project Reactor
Refactor to Reactive With Spring 5 and Project ReactorEatDog
 
Android Unit Testing With Robolectric
Android Unit Testing With RobolectricAndroid Unit Testing With Robolectric
Android Unit Testing With RobolectricDanny Preussler
 
Qt & Webkit
Qt & WebkitQt & Webkit
Qt & WebkitQT-day
 
Dagger 2. Right way to do Dependency Injection
Dagger 2. Right way to do Dependency InjectionDagger 2. Right way to do Dependency Injection
Dagger 2. Right way to do Dependency InjectionStfalcon Meetups
 
Dagger 2. The Right Way to Dependency Injections
Dagger 2. The Right Way to Dependency InjectionsDagger 2. The Right Way to Dependency Injections
Dagger 2. The Right Way to Dependency InjectionsGlobalLogic Ukraine
 
Contextual communications and why you should care - Droidcon DE
Contextual communications and why you should care - Droidcon DEContextual communications and why you should care - Droidcon DE
Contextual communications and why you should care - Droidcon DEMarcos Placona
 
Testable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMTestable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMFabio Collini
 
Going native with less coupling: Dependency Injection in C++
Going native with less coupling: Dependency Injection in C++Going native with less coupling: Dependency Injection in C++
Going native with less coupling: Dependency Injection in C++Daniele Pallastrelli
 
Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6Ray Ploski
 
Thomas braun dependency-injection_with_robo_guice-presentation-final
Thomas braun dependency-injection_with_robo_guice-presentation-finalThomas braun dependency-injection_with_robo_guice-presentation-final
Thomas braun dependency-injection_with_robo_guice-presentation-finalDroidcon Berlin
 
Scala & sling
Scala & slingScala & sling
Scala & slingmichid
 

Tendances (20)

Under the Hood: Using Spring in Grails
Under the Hood: Using Spring in GrailsUnder the Hood: Using Spring in Grails
Under the Hood: Using Spring in Grails
 
Under the Hood: Using Spring in Grails
Under the Hood: Using Spring in GrailsUnder the Hood: Using Spring in Grails
Under the Hood: Using Spring in Grails
 
JS and patterns
JS and patternsJS and patterns
JS and patterns
 
Sharper Better Faster Dagger ‡ - Droidcon SF
Sharper Better Faster Dagger ‡ - Droidcon SFSharper Better Faster Dagger ‡ - Droidcon SF
Sharper Better Faster Dagger ‡ - Droidcon SF
 
A friend in need - A JS indeed
A friend in need - A JS indeedA friend in need - A JS indeed
A friend in need - A JS indeed
 
Advanced Dagger talk from 360andev
Advanced Dagger talk from 360andevAdvanced Dagger talk from 360andev
Advanced Dagger talk from 360andev
 
Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2
 
Refactor to Reactive With Spring 5 and Project Reactor
Refactor to Reactive With Spring 5 and Project ReactorRefactor to Reactive With Spring 5 and Project Reactor
Refactor to Reactive With Spring 5 and Project Reactor
 
Android Unit Testing With Robolectric
Android Unit Testing With RobolectricAndroid Unit Testing With Robolectric
Android Unit Testing With Robolectric
 
Qt & Webkit
Qt & WebkitQt & Webkit
Qt & Webkit
 
Dagger 2. Right way to do Dependency Injection
Dagger 2. Right way to do Dependency InjectionDagger 2. Right way to do Dependency Injection
Dagger 2. Right way to do Dependency Injection
 
Dagger 2. The Right Way to Dependency Injections
Dagger 2. The Right Way to Dependency InjectionsDagger 2. The Right Way to Dependency Injections
Dagger 2. The Right Way to Dependency Injections
 
Google Web Toolkit
Google Web ToolkitGoogle Web Toolkit
Google Web Toolkit
 
Contextual communications and why you should care - Droidcon DE
Contextual communications and why you should care - Droidcon DEContextual communications and why you should care - Droidcon DE
Contextual communications and why you should care - Droidcon DE
 
Testable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMTestable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVM
 
Going native with less coupling: Dependency Injection in C++
Going native with less coupling: Dependency Injection in C++Going native with less coupling: Dependency Injection in C++
Going native with less coupling: Dependency Injection in C++
 
Dagger for dummies
Dagger for dummiesDagger for dummies
Dagger for dummies
 
Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6
 
Thomas braun dependency-injection_with_robo_guice-presentation-final
Thomas braun dependency-injection_with_robo_guice-presentation-finalThomas braun dependency-injection_with_robo_guice-presentation-final
Thomas braun dependency-injection_with_robo_guice-presentation-final
 
Scala & sling
Scala & slingScala & sling
Scala & sling
 

Similaire à My way to clean android v2 English DroidCon Spain

Android dev toolbox
Android dev toolboxAndroid dev toolbox
Android dev toolboxShem Magnezi
 
From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)Jose Manuel Pereira Garcia
 
How to code to code less
How to code to code lessHow to code to code less
How to code to code lessAnton Novikau
 
Net conf BG xamarin lecture
Net conf BG xamarin lectureNet conf BG xamarin lecture
Net conf BG xamarin lectureTsvyatko Konov
 
Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsHassan Abid
 
Binding business data to vaadin components
Binding business data to vaadin componentsBinding business data to vaadin components
Binding business data to vaadin componentsPeter Lehto
 
Droidcon Berlin Barcamp 2016
Droidcon Berlin Barcamp 2016Droidcon Berlin Barcamp 2016
Droidcon Berlin Barcamp 2016Przemek Jakubczyk
 
Introduction To Google Android (Ft Rohan Bomle)
Introduction To Google Android (Ft Rohan Bomle)Introduction To Google Android (Ft Rohan Bomle)
Introduction To Google Android (Ft Rohan Bomle)Fafadia Tech
 
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo Ali Parmaksiz
 
Android architecture blueprints overview
Android architecture blueprints overviewAndroid architecture blueprints overview
Android architecture blueprints overviewChih-Chung Lee
 
Cleaning your architecture with android architecture components
Cleaning your architecture with android architecture componentsCleaning your architecture with android architecture components
Cleaning your architecture with android architecture componentsDebora Gomez Bertoli
 
Service Oriented Architecture in Magento 2
Service Oriented Architecture in Magento 2Service Oriented Architecture in Magento 2
Service Oriented Architecture in Magento 2Max Pronko
 
ASP.NET MVC Internals
ASP.NET MVC InternalsASP.NET MVC Internals
ASP.NET MVC InternalsVitaly Baum
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureAlexey Buzdin
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureC.T.Co
 
The real beginner's guide to android testing
The real beginner's guide to android testingThe real beginner's guide to android testing
The real beginner's guide to android testingEric (Trung Dung) Nguyen
 
Petcube epic battle: architecture vs product. UA Mobile 2017.
Petcube epic battle: architecture vs product. UA Mobile 2017.Petcube epic battle: architecture vs product. UA Mobile 2017.
Petcube epic battle: architecture vs product. UA Mobile 2017.UA Mobile
 
Ruby on Rails vs ASP.NET MVC
Ruby on Rails vs ASP.NET MVCRuby on Rails vs ASP.NET MVC
Ruby on Rails vs ASP.NET MVCSimone Chiaretta
 

Similaire à My way to clean android v2 English DroidCon Spain (20)

Android dev toolbox
Android dev toolboxAndroid dev toolbox
Android dev toolbox
 
From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)
 
How to code to code less
How to code to code lessHow to code to code less
How to code to code less
 
Devoxx 2012 (v2)
Devoxx 2012 (v2)Devoxx 2012 (v2)
Devoxx 2012 (v2)
 
Net conf BG xamarin lecture
Net conf BG xamarin lectureNet conf BG xamarin lecture
Net conf BG xamarin lecture
 
Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture Components
 
Binding business data to vaadin components
Binding business data to vaadin componentsBinding business data to vaadin components
Binding business data to vaadin components
 
Droidcon Berlin Barcamp 2016
Droidcon Berlin Barcamp 2016Droidcon Berlin Barcamp 2016
Droidcon Berlin Barcamp 2016
 
Introduction To Google Android (Ft Rohan Bomle)
Introduction To Google Android (Ft Rohan Bomle)Introduction To Google Android (Ft Rohan Bomle)
Introduction To Google Android (Ft Rohan Bomle)
 
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
 
Android architecture blueprints overview
Android architecture blueprints overviewAndroid architecture blueprints overview
Android architecture blueprints overview
 
Cleaning your architecture with android architecture components
Cleaning your architecture with android architecture componentsCleaning your architecture with android architecture components
Cleaning your architecture with android architecture components
 
Service Oriented Architecture in Magento 2
Service Oriented Architecture in Magento 2Service Oriented Architecture in Magento 2
Service Oriented Architecture in Magento 2
 
ASP.NET MVC Internals
ASP.NET MVC InternalsASP.NET MVC Internals
ASP.NET MVC Internals
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
The real beginner's guide to android testing
The real beginner's guide to android testingThe real beginner's guide to android testing
The real beginner's guide to android testing
 
Modern android development
Modern android developmentModern android development
Modern android development
 
Petcube epic battle: architecture vs product. UA Mobile 2017.
Petcube epic battle: architecture vs product. UA Mobile 2017.Petcube epic battle: architecture vs product. UA Mobile 2017.
Petcube epic battle: architecture vs product. UA Mobile 2017.
 
Ruby on Rails vs ASP.NET MVC
Ruby on Rails vs ASP.NET MVCRuby on Rails vs ASP.NET MVC
Ruby on Rails vs ASP.NET MVC
 

Dernier

Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 

Dernier (20)

Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 

My way to clean android v2 English DroidCon Spain

  • 1. My way to clean Android v2 Christian Panadero http://panavtec.me @PaNaVTEC Github - PaNaVTEC My Way to clean Android V2
  • 2. My way to clean Android v2 Acknowledgements Fernando Cejas Jorge Barroso Pedro Gomez Sergio Rodrigo @fernando_cejas @flipper83 @pedro_g_s @srodrigoDev Android developer @ Sound CloudAndroid developer @ Karumi Cofounder & Android expert @ Karumi Android developer @ Develapps Alberto Moraga Carlos Morera @albertomoraga @CarlosMChica iOS Developer @ Selltag Android Developer @ Viagogo
  • 3. My way to clean Android v2 “My way to clean Android”
  • 4. My way to clean Android v2 • Independent of Frameworks • Testable • Independent of UI • Independent of Database • Independent of any external agency Why clean architecture?
  • 5. My way to clean Android v2 • Command pattern (Invoker, command, receiver) • Decorator Pattern • Interactors / Use cases • Abstractions • Data Source • Repository • Annotation Processor Concepts
  • 6. My way to clean Android v2 Abstraction levels Presenters Interactors Entities Repository Data sources UI Abstractions
  • 7. My way to clean Android v2 The dependency rule Presenters Interactors Entities Repository Data sources UI Abstractions
  • 8. My way to clean Android v2 • App (UI, DI and implementation details) • Presentation • Domain y Entities • Repository • Data Sources Thinking in projects
  • 9. My way to clean Android v2 Project dependencies App Presenters Domain Data Entities Repository
  • 10. My way to clean Android v2 Flow View Presenter Presenter Interactor Interactor Interactor Interactor Repository Repository DataSource DataSource DataSource
  • 11. My way to clean Android v2 UI: MVP ViewPresenter(s) Model Events Fill the view Actions Actions output
  • 12. My way to clean Android v2 UI: MVP - View public class MainActivity extends BaseActivity implements MainView { 
 @Inject MainPresenter presenter;
 @Override protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 presenter.attachView(this);
 } 
 @Override protected void onResume() {
 super.onResume();
 presenter.onResume();
 }
 
 @Override public void onRefresh() {
 presenter.onRefresh();
 }
 
 }
  • 13. My way to clean Android v2 UI: MVP - Presenter public class MainPresenter extends Presenter<MainView> { public void onResume() {
 refreshContactList();
 }
 
 public void onRefresh() {
 getView().refreshUi();
 refreshContactList();
 } }
  • 14. My way to clean Android v2 UI: MVP - Presenter @ThreadDecoratedView
 public interface MainView extends PresenterView {
 void showGetContactsError();
 
 void refreshContactsList(List<PresentationContact> contacts);
 
 void refreshUi();
 } public interface PresenterView {
 void initUi();
 } prevents spoiler :D
  • 15. My way to clean Android v2 • The configuration change is located in UI module, so solve it in this module • configurationChange create a new Activity instance • onRetainCustomNonConfigurationInstance to the rescue! • Retain the DI graph onConfigurationChange Hell
  • 16. My way to clean Android v2 onConfigurationChange Hell public abstract class BaseActivity extends ActionBarActivity {
 @Override protected void onCreate(Bundle savedInstanceState) {
 createActivityModule();
 } 
 private void createActivityModule() {
 activityInjector = (ActivityInjector) getLastCustomNonConfigurationInstance();
 if (activityInjector == null) {
 activityInjector = new ActivityInjector();
 activityInjector.createGraph(this, newDiModule());
 }
 activityInjector.inject(this);
 }
 
 @Override public Object onRetainCustomNonConfigurationInstance() {
 return activityInjector;
 }
 
 protected abstract Object newDiModule();
 }
  • 17. My way to clean Android v2 Presentation - Domain (ASYNC) Presenter Invoker Interactor Output Invoker IMP Interactor
  • 18. My way to clean Android v2 Presentation - Domain (SYNC) Presenter Invoker Future Invoker IMP Interactor .get();.cancel();
  • 19. My way to clean Android v2 Presentation - Domain public class MainPresenter extends Presenter<MainView> { @Output InteractorOutput<List<Contact>, RetrieveContactsException> output;
 public MainPresenter(…) {
 InteractorOutputInjector.inject(this);
 } public void onResume() {
 interactorInvoker.execute(getContactsInteractor, output);
 } @OnError void onContactsInteractorError(RetrieveContactsException data) {
 getView().showGetContactsError();
 } @OnResult void onContactsInteractor(List<Contact> result) {
 List<PresentationContact> presentationContacts = listMapper.modelToData(result);
 getView().refreshContactsList(presentationContacts);
 } }
  • 20. My way to clean Android v2 Domain - Interactor public class GetContactInteractor implements Interactor<Contact, ObtainContactException> {
 
 private ContactsRepository repository;
 private String contactMd5;
 
 public GetContactInteractor(ContactsRepository repository) {
 this.repository = repository;
 }
 
 public void setData(String contactMd5) {
 this.contactMd5 = contactMd5;
 }
 
 @Override public Contact call() throws ObtainContactException {
 return repository.obtain(contactMd5);
 }
 }
  • 21. My way to clean Android v2 Bye bye thread Hell! public class DecoratedMainView implements MainView { @Override public void showGetContactsError() {
 this.threadSpec.execute(new Runnable() {
 @Override public void run() {
 undecoratedView.showGetContactsError();
 }
 });
 } }
  • 22. My way to clean Android v2 Bye bye thread Hell! public abstract class Presenter<V extends PresenterView> {
 private V view;
 private ThreadSpec mainThreadSpec;
 
 public Presenter(ThreadSpec mainThreadSpec) {
 this.mainThreadSpec = mainThreadSpec;
 }
 
 public void attachView(V view) {
 this.view = ViewInjector.inject(view, mainThreadSpec);
 }
 
 public void detachView() {
 view = null;
 }
 
 public V getView() {
 return view;
 }
 }
  • 23. My way to clean Android v2 Bye bye thread Hell! public class MainThreadSpec implements ThreadSpec {
 
 Handler handler = new Handler();
 
 @Override public void execute(Runnable action) {
 handler.post(action);
 }
 } public abstract class Presenter<V extends PresenterView> { public void attachView(V view) {
 this.view = ViewInjector.inject(view, mainThreadSpec);
 } } @ThreadDecoratedView
 public interface MainView extends PresenterView { … }
  • 24. My way to clean Android v2 Repository Network Data Source BDD Data Source Repository Model Data
  • 25. My way to clean Android v2 Repository Interface public interface ContactsRepository { 
 List<Contact> obtainContacts() throws RetrieveContactsException;
 
 Contact obtain(String md5) throws ObtainContactException; 
 }
  • 26. My way to clean Android v2 Repository imp @Override public List<Contact> obtainContacts() throws RetrieveContactsException {
 List<Contact> contacts = null;
 try {
 contacts = bddDataSource.obtainContacts();
 } catch (ObtainContactsBddException … ce) {
 try {
 contacts = networkDataSource.obtainContacts();
 bddDataSource.persist(contacts);
 } catch (UnknownObtainContactsException … ue) {
 throw new RetrieveContactsException();
 } catch (PersistContactsBddException … pe) {
 pe.printStackTrace();
 }
 }
 return contacts;
 }
  • 27. My way to clean Android v2 Data source Model Data source Imp Data source Mapper
  • 28. My way to clean Android v2 Data source Interface public interface ContactsNetworkDataSource {
 
 public List<Contact> obtainContacts() throws ContactsNetworkException …; 
 }
  • 29. My way to clean Android v2 Data source imp private ContactsApiService apiService;
 private static final Transformer transformer = new Transformer.Builder().build(ApiContact.class); @Override public List<Contact> obtainContacts() throws ContactsNetworkException {
 try {
 ApiContactsResponse response = apiService.obtainUsers(100);
 List<ApiContactResult> results = response.getResults();
 List<Contact> contacts = new ArrayList<>();
 
 for (ApiContactResult apiContact : results) {
 contacts.add(transform(apiContact.getUser(), Contact.class));
 }
 
 return contacts;
 } catch (Throwable e) {
 throw new ContactsNetworkException();
 }
 }
  • 30. My way to clean Android v2 Caching Strategy public interface CachingStrategy<T> {
 boolean isValid(T data);
 } public class TtlCachingStrategy<T extends TtlCachingObject> implements CachingStrategy<T> {
 
 private final long ttlMillis;
 
 @Override public boolean isValid(T data) {
 return (data.getPersistedTime() + ttlMillis) > System.currentTimeMillis();
 }
 
 }
  • 31. My way to clean Android v2 Caching Strategy @Override public List<Contact> obtainContacts()
 throws ObtainContactsBddException … {
 try {
 List<BddContact> bddContacts = daoContacts.queryForAll();
 if (!cachingStrategy.isValid(bddContacts)) {
 deleteBddContacts(bddContacts);
 throw new InvalidCacheException();
 }
 ArrayList<Contact> contacts = new ArrayList<>();
 for (BddContact bddContact : bddContacts) {
 contacts.add(transform(bddContact, Contact.class));
 }
 return contacts;
 } catch (java.sql.SQLException e) {
 throw new ObtainContactsBddException();
 } catch (Throwable e) {
 throw new UnknownObtainContactsException();
 }
 }
  • 32. My way to clean Android v2 • Bussines logic doesn’t know where the data came from • It’s easy to change data source implementation • If you change the data sources implementation the business logic is not altered Repository adavantages
  • 33. My way to clean Android v2 – Uncle Bob “Make implementation details swappable”
  • 34. My way to clean Android v2 Picasso public interface ImageLoader {
 public void load(String url, ImageView imageView);
 public void loadCircular(String url, ImageView imageView);
 } public class PicassoImageLoader implements ImageLoader {
 private Picasso picasso;
 
 @Override public void load(String url, ImageView imageView) {
 picasso.load(url).into(imageView);
 }
 
 @Override public void loadCircular(String url, ImageView imageView) {
 picasso.load(url).transform(new CircleTransform()).into(imageView);
 }
 }
  • 35. My way to clean Android v2 ErrorManager public interface ErrorManager {
 public void showError(String error);
 } public class SnackbarErrorManagerImp implements ErrorManager { @Override public void showError(String error) {
 SnackbarManager.show(Snackbar.with(activity).text(error));
 } } public class ToastErrorManagerImp implements ErrorManager {
 @Override public void showError(String error) {
 Toast.makeText(activity, error, Toast.LENGTH_LONG).show();
 }
 }
  • 36. My way to clean Android v2 • ALWAYS Depend upon abstractions, NEVER depend upon concretions • Use a good naming, if there's a class you've created and the naming does not feel right, most probably it is wrong modeled. • Create new shapes using the initial dartboard to ensure that it's placed on the corresponding layer Tips
  • 37. My way to clean Android v2 – Uncle Bob “Clean code. The last programming language”
  • 38. My way to clean Android v2 In Uncle Bob we trust
  • 39. My way to clean Android v2 https://github.com/PaNaVTEC/Clean-Contacts Show me the code!
  • 40. My way to clean Android v2 • Fernando Cejas - Clean way • Jorge Barroso - Arquitectura Tuenti • Pedro Gomez - Dependency Injection • Pedro Gomez - Desing patterns • Uncle Bob - The clean architecture • PaNaVTEC - Clean without bus References
  • 41. My way to clean Android v2 ¿Questions? Christian Panadero http://panavtec.me @PaNaVTEC Github - PaNaVTEC