SlideShare una empresa de Scribd logo
1 de 35
Descargar para leer sin conexión
Christian Panadero
http://panavtec.me
@PaNaVTEC
Github - PaNaVTEC
My way to clean Android
Fernando Cejas Jorge Barroso
Pedro Gomez Sergio Rodrigo
@fernando_cejas @flipper83
@pedro_g_s @srodrigoDev
Android developer en Sound Cloud
Android developer en Tuenti
Cofounder & Android expert en Karumi
Android developer en Develapps
Alberto Moraga Carlos Morera
@albertomoraga @CarlosMChica
iOS Developer en Selltag Android Developer en Viagogo
Agradecimientos
“My way to clean Android”
¿Por qué Clean?
• Desacoplado de los frameworks
• Testable
• Desacoplado de la UI
• Desacoplado de BDD
• Desacoplado de cualquier detalle de
implementación
Conceptos
• Patrón command (Invoker, command, receiver)
• Interactors / Casos de uso
• Abstracciones
• Data Source
• Repository
Niveles de abstracción
Presenters
Interactors
Entidades
Repository
Data sources
UI
Abstractions
Regla de dependencias
Presenters
Interactors
Entidades
Repository
Data sources
UI
Abstractions
Modelando el proyecto
• App (UI, DI y detalles de implementación)
• Presentation
• Domain y Entities
• Repository
• Data Sources
Dependencias del proyecto
App
Presenters Domain Data
Entities
Repository
Flow
View
Presenter
Presenter
Interactor
Interactor
Interactor
Interactor
Repository
Repository
DataSource
DataSource
DataSource
UI: MVP
ViewPresenter(s)
Model
Eventos
Rellena la vista
Acciones
Resultados de
esas acciones
UI: MVP - View
public class MainActivity extends BaseActivity implements MainView {
@Inject MainPresenter presenter;
@Override protected void onResume() {
super.onResume();
presenter.onResume();
}
@Override public void onRefresh() {
presenter.onRefresh();
}
UI: MVP - Presenter
public class MainPresenter extends Presenter {
private MainView mainView;
private Bus bus;
public void onResume() {
bus.register(this);
}
public void onPause() {
bus.unregister(this);
}
public void onRefresh() {
mainView.clearData();
…
}
public interface MainView {
void showGetContactsError();
void clearData();
}
UI: MVP - Presenter
Presentation - Domain
Presenter InteractorInvoker
Bus
Bus IMP
Invoker IMP
Presentation - Domain
public class MainPresenter extends Presenter {
public void onCreate() {
interactorInvoker.execute(getContactsInteractor);
}
public void onEvent(GetContactsEvent event) {
if (event.getError() == null) {
List<PresentationContact> contacts = event.getContacts();
mainView.refreshContactsList(contacts);
} else {
mainView.showGetContactsError();
}
}
public class GetContactsInteractor implements Interactor {
private Bus bus;
private ContactsRepository repository;
@Override public void execute() {
GetContactsEvent event = new GetContactsEvent();
try {
List<Contact> contacts = repository.obtainContacts();
event.setContacts(contacts);
} catch (RetrieveContactsException e) {
event.setError(e);
}
bus.post(event);
}
}
Domain - Interactor
Repository
Network
Data Source
BDD
Data Source
Repository
Model
Data
Repository Interface
public interface ContactsRepository {
List<Contact> obtainContacts() throws
CantRetrieveContactsException;
Contact obtain(String md5) throws
CannotObtainContactException;
}
Repository imp
@Override public List<Contact> obtainContacts() throws
RetrieveContactsException {
List<Contact> contacts = null;
try {
contacts = bddDataSource.obtainContacts();
} catch (ObtainContactsBddException | InvalidCacheException e) {
try {
contacts = networkDataSource.obtainContacts();
bddDataSource.persist(contacts);
} catch (UnknownObtainContactsException | ContactsNetworkException) {
throw new RetrieveContactsException();
} catch (PersistContactsBddException) {
e.printStackTrace();
}
}
return contacts;
}
Data source
Model
Data source Imp
Data source
Mapper
Data source Interface
public interface ContactsNetworkDataSource {
public List<Contact> obtainContacts() throws
ContactsNetworkException, UnknownObtainContactsException;
}
private ContactsApiService apiService;
private static final ApiContactMapper mapper = new ApiContactMapper();
@Override public List<Contact> obtainContacts() throws ContactsNetworkException
{
try {
ApiContactsResponse apiContactsResponse = apiService.obtainUsers(100);
List<ApiContactResult> results = apiContactsResponse.getResults();
<MAP APICONTACTS TO CONTACTS>
return contacts;
} catch (Throwable e) {
throw new ContactsNetworkException();
}
}
Data source imp
Caching Strategy
public interface CachingStrategy<T> {
boolean isValid(T data);
}
public TtlCachingStrategy(int ttl, TimeUnit timeUnit) {
ttlMillis = timeUnit.toMillis(ttl);
}
@Override public boolean isValid(T data) {
return (data.getPersistedTime() + ttlMillis) >
System.currentTimeMillis();
}
Caching Strategy
@Override public List<Contact> obtainContacts()
throws ObtainContactsBddException, UnknownObtainContactsException,
InvalidCacheException {
try {
List<BddContact> bddContacts = daoContacts.queryForAll();
if (!cachingStrategy.isValid(bddContacts)) {
deleteBddContacts(cachingStrategy.candidatesToPurgue(bddContacts));
throw new InvalidCacheException();
}
ArrayList<Contact> contacts = new ArrayList<>();
for (BddContact bddContact : bddContacts) {
contacts.add(transformer.transform(bddContact, Contact.class));
}
return contacts;
} catch (java.sql.SQLException e) {
throw new ObtainContactsBddException();
} catch (Throwable e) {
throw new UnknownObtainContactsException();
}
}
Ventajas de Repository
• La lógica de negocio no sabe de donde vienen los
datos.
• Fácil de cambiar la implementación de los
orígenes de datos.
• En caso de cambio de orígenes de datos la lógica
de negocio no se ve alterada.
– Uncle Bob
“Make implementation details swappable”
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;
public PicassoImageLoader(Picasso picasso) {
this.picasso = picasso;
}
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);
}
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();
}
}
Consejos
• Trabaja siempre con abstracciones nunca con
concreciones.
• Usa un buen naming, si ves que hay alguna figura
que has creado que no sabes que nombre poner,
seguramente esté mal modelada.
• Si creas nuevas figuras usa la diana inicial para
asegurarte que las creas en la capa
correspondiente
– Uncle Bob
“Clean code. The last programming
language”
In Uncle Bob we trust
Show me the code!
https://github.com/PaNaVTEC/Clean-Contacts
Referencias
• Fernando Cejas - Clean way
• Jorge Barroso - Arquitectura Tuenti
• Pedro Gomez - Dependency Injection
• Pedro Gomez - Desing patterns
• Uncle Bob - The clean architecture
¿Preguntas?
Christian Panadero
http://panavtec.me
@PaNaVTEC
Github - PaNaVTEC

Más contenido relacionado

La actualidad más candente

Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)Ontico
 
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
 
Testing Java Code Effectively
Testing Java Code EffectivelyTesting Java Code Effectively
Testing Java Code EffectivelyAndres Almiray
 
Automated%20testing%20with%20Espresso2.x
Automated%20testing%20with%20Espresso2.xAutomated%20testing%20with%20Espresso2.x
Automated%20testing%20with%20Espresso2.xTatsuya Maki
 
Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017Andres Almiray
 
Making the most of your gradle build - Gr8Conf 2017
Making the most of your gradle build - Gr8Conf 2017Making the most of your gradle build - Gr8Conf 2017
Making the most of your gradle build - Gr8Conf 2017Andres Almiray
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleThierry Wasylczenko
 
Padroes Projeto
Padroes ProjetoPadroes Projeto
Padroes Projetolcbj
 
A (very) opinionated guide to MSBuild and Project Files
A (very) opinionated guide to MSBuild and Project FilesA (very) opinionated guide to MSBuild and Project Files
A (very) opinionated guide to MSBuild and Project FilesDavid Wengier
 
Testing Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UKTesting Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UKFabio Collini
 
Lowering in C#: What really happens with your code?, from NDC Oslo 2019
Lowering in C#: What really happens with your code?, from NDC Oslo 2019Lowering in C#: What really happens with your code?, from NDC Oslo 2019
Lowering in C#: What really happens with your code?, from NDC Oslo 2019David Wengier
 
Scala & sling
Scala & slingScala & sling
Scala & slingmichid
 
ReactJS for Programmers
ReactJS for ProgrammersReactJS for Programmers
ReactJS for ProgrammersDavid Rodenas
 
Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Fabio Collini
 
Advanced Dagger talk from 360andev
Advanced Dagger talk from 360andevAdvanced Dagger talk from 360andev
Advanced Dagger talk from 360andevMike Nakhimovich
 

La actualidad más candente (20)

Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
 
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
 
Testing Java Code Effectively
Testing Java Code EffectivelyTesting Java Code Effectively
Testing Java Code Effectively
 
JS and patterns
JS and patternsJS and patterns
JS and patterns
 
JavaZone 2014 - goto java;
JavaZone 2014 - goto java;JavaZone 2014 - goto java;
JavaZone 2014 - goto java;
 
Automated%20testing%20with%20Espresso2.x
Automated%20testing%20with%20Espresso2.xAutomated%20testing%20with%20Espresso2.x
Automated%20testing%20with%20Espresso2.x
 
Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017
 
Making the most of your gradle build - Gr8Conf 2017
Making the most of your gradle build - Gr8Conf 2017Making the most of your gradle build - Gr8Conf 2017
Making the most of your gradle build - Gr8Conf 2017
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 
#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG
 
Padroes Projeto
Padroes ProjetoPadroes Projeto
Padroes Projeto
 
A (very) opinionated guide to MSBuild and Project Files
A (very) opinionated guide to MSBuild and Project FilesA (very) opinionated guide to MSBuild and Project Files
A (very) opinionated guide to MSBuild and Project Files
 
Testing Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UKTesting Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UK
 
Lowering in C#: What really happens with your code?, from NDC Oslo 2019
Lowering in C#: What really happens with your code?, from NDC Oslo 2019Lowering in C#: What really happens with your code?, from NDC Oslo 2019
Lowering in C#: What really happens with your code?, from NDC Oslo 2019
 
Scala & sling
Scala & slingScala & sling
Scala & sling
 
Agile Android
Agile AndroidAgile Android
Agile Android
 
ReactJS for Programmers
ReactJS for ProgrammersReactJS for Programmers
ReactJS for Programmers
 
Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2
 
Advanced Dagger talk from 360andev
Advanced Dagger talk from 360andevAdvanced Dagger talk from 360andev
Advanced Dagger talk from 360andev
 

Similar a My way to clean android - Android day salamanca edition

The Best Way to Become an Android Developer Expert with Android Jetpack
The Best Way to Become an Android Developer Expert  with Android JetpackThe Best Way to Become an Android Developer Expert  with Android Jetpack
The Best Way to Become an Android Developer Expert with Android JetpackAhmad Arif Faizin
 
Droidcon ES '16 - How to fail going offline
Droidcon ES '16 - How to fail going offlineDroidcon ES '16 - How to fail going offline
Droidcon ES '16 - How to fail going offlineJavier de Pedro López
 
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...Fons Sonnemans
 
The use case of a scalable architecture
The use case of a scalable architectureThe use case of a scalable architecture
The use case of a scalable architectureToru Wonyoung Choi
 
Advanced #2 networking
Advanced #2   networkingAdvanced #2   networking
Advanced #2 networkingVitali Pekelis
 
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
 
softshake 2014 - Java EE
softshake 2014 - Java EEsoftshake 2014 - Java EE
softshake 2014 - Java EEAlexis Hassler
 
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
 
Implement Service Broker with Spring Boot #cf_tokyo
Implement Service Broker with Spring Boot #cf_tokyoImplement Service Broker with Spring Boot #cf_tokyo
Implement Service Broker with Spring Boot #cf_tokyoToshiaki Maki
 
Appcelerator droidcon15 TLV
Appcelerator droidcon15 TLVAppcelerator droidcon15 TLV
Appcelerator droidcon15 TLVYishaiBrown
 
Clean Architecture on Android
Clean Architecture on AndroidClean Architecture on Android
Clean Architecture on AndroidTianming Xu
 
MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know Norberto Leite
 
Mongo+java (1)
Mongo+java (1)Mongo+java (1)
Mongo+java (1)MongoDB
 
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
 
Présentation et bonnes pratiques du pattern MVVM - MIC Belgique
Présentation et bonnes pratiques du pattern MVVM - MIC BelgiquePrésentation et bonnes pratiques du pattern MVVM - MIC Belgique
Présentation et bonnes pratiques du pattern MVVM - MIC BelgiqueDenis Voituron
 
Application Continuity with Oracle DB 12c
Application Continuity with Oracle DB 12c Application Continuity with Oracle DB 12c
Application Continuity with Oracle DB 12c Léopold Gault
 

Similar a My way to clean android - Android day salamanca edition (20)

The Best Way to Become an Android Developer Expert with Android Jetpack
The Best Way to Become an Android Developer Expert  with Android JetpackThe Best Way to Become an Android Developer Expert  with Android Jetpack
The Best Way to Become an Android Developer Expert with Android Jetpack
 
Droidcon ES '16 - How to fail going offline
Droidcon ES '16 - How to fail going offlineDroidcon ES '16 - How to fail going offline
Droidcon ES '16 - How to fail going offline
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...
 
The use case of a scalable architecture
The use case of a scalable architectureThe use case of a scalable architecture
The use case of a scalable architecture
 
Advanced #2 networking
Advanced #2   networkingAdvanced #2   networking
Advanced #2 networking
 
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
 
softshake 2014 - Java EE
softshake 2014 - Java EEsoftshake 2014 - Java EE
softshake 2014 - Java EE
 
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)
 
Implement Service Broker with Spring Boot #cf_tokyo
Implement Service Broker with Spring Boot #cf_tokyoImplement Service Broker with Spring Boot #cf_tokyo
Implement Service Broker with Spring Boot #cf_tokyo
 
Appcelerator droidcon15 TLV
Appcelerator droidcon15 TLVAppcelerator droidcon15 TLV
Appcelerator droidcon15 TLV
 
Clean Architecture on Android
Clean Architecture on AndroidClean Architecture on Android
Clean Architecture on Android
 
MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know
 
Mongo+java (1)
Mongo+java (1)Mongo+java (1)
Mongo+java (1)
 
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
 
Having Fun with Play
Having Fun with PlayHaving Fun with Play
Having Fun with Play
 
Présentation et bonnes pratiques du pattern MVVM - MIC Belgique
Présentation et bonnes pratiques du pattern MVVM - MIC BelgiquePrésentation et bonnes pratiques du pattern MVVM - MIC Belgique
Présentation et bonnes pratiques du pattern MVVM - MIC Belgique
 
Hexagonal architecture in PHP
Hexagonal architecture in PHPHexagonal architecture in PHP
Hexagonal architecture in PHP
 
Application Continuity with Oracle DB 12c
Application Continuity with Oracle DB 12c Application Continuity with Oracle DB 12c
Application Continuity with Oracle DB 12c
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 

Último

DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 

Último (20)

DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 

My way to clean android - Android day salamanca edition

  • 2. Fernando Cejas Jorge Barroso Pedro Gomez Sergio Rodrigo @fernando_cejas @flipper83 @pedro_g_s @srodrigoDev Android developer en Sound Cloud Android developer en Tuenti Cofounder & Android expert en Karumi Android developer en Develapps Alberto Moraga Carlos Morera @albertomoraga @CarlosMChica iOS Developer en Selltag Android Developer en Viagogo Agradecimientos
  • 3. “My way to clean Android”
  • 4. ¿Por qué Clean? • Desacoplado de los frameworks • Testable • Desacoplado de la UI • Desacoplado de BDD • Desacoplado de cualquier detalle de implementación
  • 5. Conceptos • Patrón command (Invoker, command, receiver) • Interactors / Casos de uso • Abstracciones • Data Source • Repository
  • 8. Modelando el proyecto • App (UI, DI y detalles de implementación) • Presentation • Domain y Entities • Repository • Data Sources
  • 9. Dependencias del proyecto App Presenters Domain Data Entities Repository
  • 11. UI: MVP ViewPresenter(s) Model Eventos Rellena la vista Acciones Resultados de esas acciones
  • 12. UI: MVP - View public class MainActivity extends BaseActivity implements MainView { @Inject MainPresenter presenter; @Override protected void onResume() { super.onResume(); presenter.onResume(); } @Override public void onRefresh() { presenter.onRefresh(); }
  • 13. UI: MVP - Presenter public class MainPresenter extends Presenter { private MainView mainView; private Bus bus; public void onResume() { bus.register(this); } public void onPause() { bus.unregister(this); } public void onRefresh() { mainView.clearData(); … }
  • 14. public interface MainView { void showGetContactsError(); void clearData(); } UI: MVP - Presenter
  • 15. Presentation - Domain Presenter InteractorInvoker Bus Bus IMP Invoker IMP
  • 16. Presentation - Domain public class MainPresenter extends Presenter { public void onCreate() { interactorInvoker.execute(getContactsInteractor); } public void onEvent(GetContactsEvent event) { if (event.getError() == null) { List<PresentationContact> contacts = event.getContacts(); mainView.refreshContactsList(contacts); } else { mainView.showGetContactsError(); } }
  • 17. public class GetContactsInteractor implements Interactor { private Bus bus; private ContactsRepository repository; @Override public void execute() { GetContactsEvent event = new GetContactsEvent(); try { List<Contact> contacts = repository.obtainContacts(); event.setContacts(contacts); } catch (RetrieveContactsException e) { event.setError(e); } bus.post(event); } } Domain - Interactor
  • 19. Repository Interface public interface ContactsRepository { List<Contact> obtainContacts() throws CantRetrieveContactsException; Contact obtain(String md5) throws CannotObtainContactException; }
  • 20. Repository imp @Override public List<Contact> obtainContacts() throws RetrieveContactsException { List<Contact> contacts = null; try { contacts = bddDataSource.obtainContacts(); } catch (ObtainContactsBddException | InvalidCacheException e) { try { contacts = networkDataSource.obtainContacts(); bddDataSource.persist(contacts); } catch (UnknownObtainContactsException | ContactsNetworkException) { throw new RetrieveContactsException(); } catch (PersistContactsBddException) { e.printStackTrace(); } } return contacts; }
  • 21. Data source Model Data source Imp Data source Mapper
  • 22. Data source Interface public interface ContactsNetworkDataSource { public List<Contact> obtainContacts() throws ContactsNetworkException, UnknownObtainContactsException; }
  • 23. private ContactsApiService apiService; private static final ApiContactMapper mapper = new ApiContactMapper(); @Override public List<Contact> obtainContacts() throws ContactsNetworkException { try { ApiContactsResponse apiContactsResponse = apiService.obtainUsers(100); List<ApiContactResult> results = apiContactsResponse.getResults(); <MAP APICONTACTS TO CONTACTS> return contacts; } catch (Throwable e) { throw new ContactsNetworkException(); } } Data source imp
  • 24. Caching Strategy public interface CachingStrategy<T> { boolean isValid(T data); } public TtlCachingStrategy(int ttl, TimeUnit timeUnit) { ttlMillis = timeUnit.toMillis(ttl); } @Override public boolean isValid(T data) { return (data.getPersistedTime() + ttlMillis) > System.currentTimeMillis(); }
  • 25. Caching Strategy @Override public List<Contact> obtainContacts() throws ObtainContactsBddException, UnknownObtainContactsException, InvalidCacheException { try { List<BddContact> bddContacts = daoContacts.queryForAll(); if (!cachingStrategy.isValid(bddContacts)) { deleteBddContacts(cachingStrategy.candidatesToPurgue(bddContacts)); throw new InvalidCacheException(); } ArrayList<Contact> contacts = new ArrayList<>(); for (BddContact bddContact : bddContacts) { contacts.add(transformer.transform(bddContact, Contact.class)); } return contacts; } catch (java.sql.SQLException e) { throw new ObtainContactsBddException(); } catch (Throwable e) { throw new UnknownObtainContactsException(); } }
  • 26. Ventajas de Repository • La lógica de negocio no sabe de donde vienen los datos. • Fácil de cambiar la implementación de los orígenes de datos. • En caso de cambio de orígenes de datos la lógica de negocio no se ve alterada.
  • 27. – Uncle Bob “Make implementation details swappable”
  • 28. 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; public PicassoImageLoader(Picasso picasso) { this.picasso = picasso; } 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); }
  • 29. 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(); } }
  • 30. Consejos • Trabaja siempre con abstracciones nunca con concreciones. • Usa un buen naming, si ves que hay alguna figura que has creado que no sabes que nombre poner, seguramente esté mal modelada. • Si creas nuevas figuras usa la diana inicial para asegurarte que las creas en la capa correspondiente
  • 31. – Uncle Bob “Clean code. The last programming language”
  • 32. In Uncle Bob we trust
  • 33. Show me the code! https://github.com/PaNaVTEC/Clean-Contacts
  • 34. Referencias • Fernando Cejas - Clean way • Jorge Barroso - Arquitectura Tuenti • Pedro Gomez - Dependency Injection • Pedro Gomez - Desing patterns • Uncle Bob - The clean architecture