SlideShare uma empresa Scribd logo
1 de 87
Baixar para ler offline
From Legacy to Hexagonal 
(An Unexpected Android Journey) 
Rubén Serrano @Akelael 
Lead Android Developer @RedboothHQ 
José Manuel Pereira @JMPergar 
Android Software Engineer @RedboothHQ
Agenda 
1. From Legacy Code 
2. Towards Hexagonal Architecture 
3. To infinity, and beyond!
1. From Le gacy Code
Meet the team
One dev from a contractor
One dev from a contractor 
+ one senior iOS dev
One dev from a contractor 
+ one senior iOS dev
One dev from a contractor 
+ one senior iOS dev 
+ one junior iOS dev
One dev from a contractor 
+ one senior iOS dev 
+ one junior iOS dev
A different Android dev 
One dev from a contractor 
+ one senior iOS dev 
+ one junior iOS dev
A different Android dev 
One dev from a contractor 
+ one senior iOS dev 
+ one junior iOS dev 
+ one confused Android team
Meet the code
Meet the problem
1. We have a huge technical debt
1. We have a huge technical debt
HUGE
1. We have huge technical debt 
2. We can’t stop developing new features
1. We have huge technical debt 
2. We can’t stop developing new features 
3. We can’t remove debt at this point and we 
shouldn’t add any more
2. Towards Hexagonal
Working with 
legacy code
Read this book
What have we 
learnt from pizza?
You just don’t 
eat the whole 
pizza at once
1. Slice the big methods into small 
meaningful methods
1. Slice the big methods into small 
meaningful methods 
2. Identify different responsibilities and move 
them to other classes
1. Slice the big methods into small 
meaningful methods 
2. Identify different responsibilities and move 
them to other classes 
3. Use less coupled framework components 
(or no components at all)
Model View Presenter
In theory
View 
Presenter 
Model
Notifies 
events 
View 
Presenter 
Model
Requests 
data 
View 
Presenter 
Model
Serves data 
View 
Presenter 
Model
Change data 
representation 
View 
Presenter 
Model
View 
Tells how to draw 
Presenter 
Model
Layout 
+ 
Activity/ 
Fragment 
Presenter 
Data 
+ 
Business logic
In code 
(Original code…) 
http://goo.gl/z5Xn2J
listAdapter = 
MainFragment 
new SimpleCursorAdapter(getActivity(), 
android.R.layout.simple_list_item_1, 
null, 
new String[]{FakeDatabase.COLUMN_NAME}, 
new int[]{android.R.id.text1}, 
0); 
listView.setAdapter(listAdapter);
getLoaderManager().initLoader(0, null, new LoaderManager.LoaderCallbacks<Cursor>() { 
@Override 
public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
return new CursorLoader(getActivity(), MainContentProvider.URI, 
null, null, null, null); 
} 
@Override 
public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
listAdapter.swapCursor(data); 
} 
@Override 
public void onLoaderReset(Loader<Cursor> loader) { 
listAdapter.swapCursor(null); 
} 
}); 
MainFragment
In Code 
(… to MVP) 
http://goo.gl/Retvli
MainView & MainModel 
public interface MainView { 
public void swaplListData(Cursor cursor); 
} 
public interface MainModel { 
public void setPresenter(MainPresenter presenter); 
public void startLoadingData(Context context); 
}
MainFragment 
public class MainFragment extends Fragment implements MainView { 
//... 
@Override 
public void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
presenter = PresenterFactory.getMainPresenter(this); 
} 
@Override 
public void onActivityCreated(Bundle savedInstanceState) { 
//... 
presenter.notifyOnCreate(getActivity()); 
} 
@Override 
public void swaplListData(Cursor cursor) { 
listAdapter.swapCursor(cursor); 
}
MainPresenter 
public class MainPresenter { 
private MainView mainView; 
private MainModel mainModel; 
//... 
public void notifyOnCreate(Context context) { 
mainModel.startLoadingData(context); 
} 
public void notifiyLoadedDataAvailable(Cursor cursor) { 
mainView.swaplListData(cursor); 
} 
}
PresenterFactory 
public class PresenterFactory { 
public static MainPresenter getMainPresenter(MainView view) { 
MainModel model = new MainCursorModel(); 
return MainPresenter.newInstance(view, model); 
} 
}
MainCursorModel 
public class MainCursorModel implements MainModel { 
//... 
@Override 
public void startLoadingData(Context context) { 
new LoadDataAsyncTask().execute(context); 
} 
private class LoadDataAsyncTask extends AsyncTask<Context, Void, Cursor > { 
//... 
@Override 
protected void onPostExecute(Cursor result) { 
super.onPostExecute(result); 
presenter.notifiyLoadedDataAvailable(result); 
} 
} 
}
Pros & Cons 
View decoupled from model 
Cleaner code and smaller fragment/activities 
View and model not really decoupled (cursor) 
All the components use the framework
Hexagonal Architecture
In theory
Layout 
+ 
Activity/ 
Fragment 
Presenter 
Data 
+ 
Business logic
Layout 
+ 
Activity/ 
Fragment 
Data domain 
Business 
logic
Layout 
+ 
Activity/ 
Fragment 
Database 
Business 
logic 
Network 
Sensors
Database 
Network 
Sensors 
Layout 
+ 
Activity/ 
Fragment 
Business 
logic
Business 
logic 
Sensors 
Network 
Database 
Layout 
+ 
Activity/ 
Fragment
Port 
Business 
logic Port Port 
Port 
Sensors 
Network 
Database 
Layout 
+ 
Activity/ 
Fragment
Adapter 
Port 
Business 
logic Port Port 
Sensors 
Network 
Database 
Layout 
+ 
Activity/ 
Fragment 
Adapter Adapter 
Port 
Adapter
Adapter 
Port 
Business 
logic Port Port 
Sensors 
Network 
Database 
Layout 
+ 
Activity/ 
Fragment 
Adapter Adapter 
Port 
Adapter
Boundary 
Port 
Business 
logic Port Port 
Sensors 
Network 
Database 
Layout 
+ 
Activity/ 
Fragment 
Boundary Boundary 
Port 
Boundary
App 
Core 
App App 
Module Core 
Module 
App 
Module 
App 
Module 
App 
Module 
App 
Core Core 
Core 
App
In code 
(Hexagonal) 
http://goo.gl/lIyH0o
MainFragment 
public class MainFragment extends Fragment { 
//... 
private MainFragmentBoundary viewBoundary; 
@Override 
public void onCreate(Bundle savedInstanceState) { 
//... 
viewBoundary = MainFragmentBoundary.newInstance(this); 
} 
@Override 
public void onActivityCreated(Bundle savedInstanceState) { 
//... 
viewBoundary.notifyOnCreate(); 
}
MainFragment 
public void setListAdapter() { 
listAdapter = new ArrayAdapter<String>(getActivity(), 
android.R.layout.simple_list_item_1, 
android.R.id.text1, 
new ArrayList<String>(0)); 
listView.setAdapter(listAdapter); 
} 
public void swapList(List<String> names) { 
listAdapter.clear(); 
listAdapter.addAll(names); 
}
MainFragmentBoundary 
public class MainFragmentBoundary implements MainViewPort { 
private MainFragment mainFragment; 
private MainLogic logic; 
//... 
public void notifyOnCreate() { 
logic.notifyOnCreate(); 
} 
@Override 
public void swaplListData(List<String> names) { 
mainFragment.swapList(names); 
}
MainModelBoundary 
public class MainModelBoundary implements MainModelPort { 
private MainLogic logic; 
private MainRepository repository; 
//... 
@Override 
public void startLoadingData() { 
repository.startLoadingData(new MainRepository.OnDataLoadedListener() { 
@Override 
public void onDataLodaded(Cursor cursor) { 
notifyDataLoaded(cursor); 
} 
}); 
} 
private void notifyDataLoaded(Cursor cursor) { 
List<String> names = mapCursorToList(cursor); 
logic.notifiyLoadedDataAvailable(names); 
}
MainModelBoundary 
private List<String> mapCursorToList(Cursor cursor) { 
List<String> names = new ArrayList<String>(); 
int nameColumnIndex = cursor.getColumnIndex(FakeDatabase.COLUMN_NAME); 
while (cursor.moveToNext()) { 
String name = cursor.getString(nameColumnIndex); 
names.add(name); 
} 
return names; 
}
Pros & Cons 
Logic is not going to be affected by framework changes 
Logic is pure Java: easier to test 
Less changes when replacing a plugin 
Easier for 2 devs to work on the same feature 
More complex architecture 
Need to map each POJO for each layer 
What happens when the plugins need to cooperate?
3. To infinity, and beyond!
One plugin, 
N commands
Boundary 
Port 
Business 
logic Port Port 
Sensors 
Network 
Database 
Layout 
+ 
Activity/ 
Fragment 
Boundary Boundary 
Port 
Boundary
Model 
Plugin 
Layout 
+ 
Activity/ 
Fragment 
Boundary Business Boundary 
logic Port Port
Create task 
Send chat message 
Update note 
Request projects 
Business 
logic 
Port Model 
Plugin 
Boundary
Asynchrony?
Create task 
Send chat message 
Update note 
Request projects 
Business 
logic 
Port Model 
Plugin 
Boundary
We don’t like: 
callback’s hell + AsyncTasks
We don’t like: 
callback’s hell + AsyncTasks 
We don’t mind (but could be a problem): 
only commands in separate threads
We don’t like: 
callback’s hell + AsyncTasks 
We don’t mind (but could be a problem): 
only commands in separate threads 
We would love: 
RxJava
Use cases
Model 
Plugin 
Layout 
+ 
Activity/ 
Fragment 
Boundary Business Boundary 
logic Port Port
Model 
Plugin 
Layout 
+ 
Activity/ 
Fragment 
Presenter 
Use 
Case 
Model 
Plugin 
Use 
Case Repository 
Model 
Plugin 
Use 
Case
Conclusions 
photo by Daniel Sancho
When? 
• If you expect 2+ devs working on the same 
feature 
• Unless you are sure the app is going to die 
in a near future 
• You know for sure you will change your 
plugins
How? 
1. Simple refactors 
2. Model View Presenter 
3. Hexagonal
How? 
1. Simple refactors 
2. Model View Presenter 
3. Hexagonal 
4. Clean Architecture
Thank you!
Questions?

Mais conteúdo relacionado

Mais procurados

Dove sono i tuoi vertici e di cosa stanno parlando?
Dove sono i tuoi vertici e di cosa stanno parlando?Dove sono i tuoi vertici e di cosa stanno parlando?
Dove sono i tuoi vertici e di cosa stanno parlando?Codemotion
 
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's GuideEvolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's GuideVictor Rentea
 
The framework as an implementation detail
The framework as an implementation detailThe framework as an implementation detail
The framework as an implementation detailMarcello Duarte
 
API-first development
API-first developmentAPI-first development
API-first developmentVasco Veloso
 
Architecture | Busy Java Developers Guide to NoSQL | Ted Neward
Architecture | Busy Java Developers Guide to NoSQL | Ted NewardArchitecture | Busy Java Developers Guide to NoSQL | Ted Neward
Architecture | Busy Java Developers Guide to NoSQL | Ted NewardJAX London
 
Flutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdfFlutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdfKaty Slemon
 
Spring @Transactional Explained
Spring @Transactional ExplainedSpring @Transactional Explained
Spring @Transactional ExplainedVictor Rentea
 
Clean Lambdas & Streams in Java8
Clean Lambdas & Streams in Java8Clean Lambdas & Streams in Java8
Clean Lambdas & Streams in Java8Victor Rentea
 
Zend Studio Tips and Tricks
Zend Studio Tips and TricksZend Studio Tips and Tricks
Zend Studio Tips and TricksRoy Ganor
 
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLEAN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLEGavin Pickin
 
Smoothing Your Java with DSLs
Smoothing Your Java with DSLsSmoothing Your Java with DSLs
Smoothing Your Java with DSLsintelliyole
 
Android | Busy Java Developers Guide to Android: UI | Ted Neward
Android | Busy Java Developers Guide to Android: UI | Ted NewardAndroid | Busy Java Developers Guide to Android: UI | Ted Neward
Android | Busy Java Developers Guide to Android: UI | Ted NewardJAX London
 
[CB19] API-induced SSRF: How Apple Pay Scattered Vulnerabilities Across the W...
[CB19] API-induced SSRF: How Apple Pay Scattered Vulnerabilities Across the W...[CB19] API-induced SSRF: How Apple Pay Scattered Vulnerabilities Across the W...
[CB19] API-induced SSRF: How Apple Pay Scattered Vulnerabilities Across the W...CODE BLUE
 
Porting VisualWorks code to Pharo
Porting VisualWorks code to PharoPorting VisualWorks code to Pharo
Porting VisualWorks code to PharoESUG
 
Professional JavaScript: AntiPatterns
Professional JavaScript: AntiPatternsProfessional JavaScript: AntiPatterns
Professional JavaScript: AntiPatternsMike Wilcox
 
DEF CON 27 - JOSHUA MADDUX - api induced ssrf
DEF CON 27 - JOSHUA MADDUX - api induced ssrfDEF CON 27 - JOSHUA MADDUX - api induced ssrf
DEF CON 27 - JOSHUA MADDUX - api induced ssrfFelipe Prado
 
Tools and Virtualization to Manage our Operations at Puppet Labs - PuppetConf...
Tools and Virtualization to Manage our Operations at Puppet Labs - PuppetConf...Tools and Virtualization to Manage our Operations at Puppet Labs - PuppetConf...
Tools and Virtualization to Manage our Operations at Puppet Labs - PuppetConf...Puppet
 
Prairie DevCon 2015 - Crafting Evolvable API Responses
Prairie DevCon 2015 - Crafting Evolvable API ResponsesPrairie DevCon 2015 - Crafting Evolvable API Responses
Prairie DevCon 2015 - Crafting Evolvable API Responsesdarrelmiller71
 
[제3회 스포카콘] [안드로이드] 클린 아키텍처 적용하기
[제3회 스포카콘] [안드로이드] 클린 아키텍처 적용하기[제3회 스포카콘] [안드로이드] 클린 아키텍처 적용하기
[제3회 스포카콘] [안드로이드] 클린 아키텍처 적용하기RyanHKang
 

Mais procurados (20)

Dove sono i tuoi vertici e di cosa stanno parlando?
Dove sono i tuoi vertici e di cosa stanno parlando?Dove sono i tuoi vertici e di cosa stanno parlando?
Dove sono i tuoi vertici e di cosa stanno parlando?
 
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's GuideEvolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
 
The framework as an implementation detail
The framework as an implementation detailThe framework as an implementation detail
The framework as an implementation detail
 
API-first development
API-first developmentAPI-first development
API-first development
 
Architecture | Busy Java Developers Guide to NoSQL | Ted Neward
Architecture | Busy Java Developers Guide to NoSQL | Ted NewardArchitecture | Busy Java Developers Guide to NoSQL | Ted Neward
Architecture | Busy Java Developers Guide to NoSQL | Ted Neward
 
Flutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdfFlutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdf
 
Spring @Transactional Explained
Spring @Transactional ExplainedSpring @Transactional Explained
Spring @Transactional Explained
 
Clean Lambdas & Streams in Java8
Clean Lambdas & Streams in Java8Clean Lambdas & Streams in Java8
Clean Lambdas & Streams in Java8
 
Zend Studio Tips and Tricks
Zend Studio Tips and TricksZend Studio Tips and Tricks
Zend Studio Tips and Tricks
 
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLEAN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE
 
Smoothing Your Java with DSLs
Smoothing Your Java with DSLsSmoothing Your Java with DSLs
Smoothing Your Java with DSLs
 
Android | Busy Java Developers Guide to Android: UI | Ted Neward
Android | Busy Java Developers Guide to Android: UI | Ted NewardAndroid | Busy Java Developers Guide to Android: UI | Ted Neward
Android | Busy Java Developers Guide to Android: UI | Ted Neward
 
[CB19] API-induced SSRF: How Apple Pay Scattered Vulnerabilities Across the W...
[CB19] API-induced SSRF: How Apple Pay Scattered Vulnerabilities Across the W...[CB19] API-induced SSRF: How Apple Pay Scattered Vulnerabilities Across the W...
[CB19] API-induced SSRF: How Apple Pay Scattered Vulnerabilities Across the W...
 
Porting VisualWorks code to Pharo
Porting VisualWorks code to PharoPorting VisualWorks code to Pharo
Porting VisualWorks code to Pharo
 
Professional JavaScript: AntiPatterns
Professional JavaScript: AntiPatternsProfessional JavaScript: AntiPatterns
Professional JavaScript: AntiPatterns
 
Article laravel 8
Article laravel 8Article laravel 8
Article laravel 8
 
DEF CON 27 - JOSHUA MADDUX - api induced ssrf
DEF CON 27 - JOSHUA MADDUX - api induced ssrfDEF CON 27 - JOSHUA MADDUX - api induced ssrf
DEF CON 27 - JOSHUA MADDUX - api induced ssrf
 
Tools and Virtualization to Manage our Operations at Puppet Labs - PuppetConf...
Tools and Virtualization to Manage our Operations at Puppet Labs - PuppetConf...Tools and Virtualization to Manage our Operations at Puppet Labs - PuppetConf...
Tools and Virtualization to Manage our Operations at Puppet Labs - PuppetConf...
 
Prairie DevCon 2015 - Crafting Evolvable API Responses
Prairie DevCon 2015 - Crafting Evolvable API ResponsesPrairie DevCon 2015 - Crafting Evolvable API Responses
Prairie DevCon 2015 - Crafting Evolvable API Responses
 
[제3회 스포카콘] [안드로이드] 클린 아키텍처 적용하기
[제3회 스포카콘] [안드로이드] 클린 아키텍처 적용하기[제3회 스포카콘] [안드로이드] 클린 아키텍처 적용하기
[제3회 스포카콘] [안드로이드] 클린 아키텍처 적용하기
 

Destaque

Mikadomethod tad2011
Mikadomethod tad2011Mikadomethod tad2011
Mikadomethod tad2011danielbrolund
 
Hexagonal architecture for java applications
Hexagonal architecture for java applicationsHexagonal architecture for java applications
Hexagonal architecture for java applicationsFabricio Epaminondas
 
Kata: Hexagonal Architecture / Ports and Adapters
Kata: Hexagonal Architecture / Ports and AdaptersKata: Hexagonal Architecture / Ports and Adapters
Kata: Hexagonal Architecture / Ports and Adaptersholsky
 

Destaque (6)

Mikado method
Mikado methodMikado method
Mikado method
 
Mikadomethod tad2011
Mikadomethod tad2011Mikadomethod tad2011
Mikadomethod tad2011
 
Axiomas de peano
Axiomas de peanoAxiomas de peano
Axiomas de peano
 
Developing for Android (The movie)
Developing for Android (The movie)Developing for Android (The movie)
Developing for Android (The movie)
 
Hexagonal architecture for java applications
Hexagonal architecture for java applicationsHexagonal architecture for java applications
Hexagonal architecture for java applications
 
Kata: Hexagonal Architecture / Ports and Adapters
Kata: Hexagonal Architecture / Ports and AdaptersKata: Hexagonal Architecture / Ports and Adapters
Kata: Hexagonal Architecture / Ports and Adapters
 

Semelhante a From Legacy to Hexagonal (An Unexpected Android Journey)

Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsJeff Durta
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsJeff Durta
 
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
 
TWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonTWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonCodemotion
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...Fabio Franzini
 
How to code to code less
How to code to code lessHow to code to code less
How to code to code lessAnton Novikau
 
10 ways to make your code rock
10 ways to make your code rock10 ways to make your code rock
10 ways to make your code rockmartincronje
 
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
 
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
 
Refactoring Wunderlist. UA Mobile 2016.
Refactoring Wunderlist. UA Mobile 2016.Refactoring Wunderlist. UA Mobile 2016.
Refactoring Wunderlist. UA Mobile 2016.UA Mobile
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best PracticesYekmer Simsek
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to javaciklum_ods
 
Jaoo - Open Social A Standard For The Social Web
Jaoo - Open Social A Standard For The Social WebJaoo - Open Social A Standard For The Social Web
Jaoo - Open Social A Standard For The Social WebPatrick Chanezon
 
Googleappengineintro 110410190620-phpapp01
Googleappengineintro 110410190620-phpapp01Googleappengineintro 110410190620-phpapp01
Googleappengineintro 110410190620-phpapp01Tony Frame
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy CodeNaresh Jain
 
Five android architecture
Five android architectureFive android architecture
Five android architectureTomislav Homan
 
2. Design patterns. part #2
2. Design patterns. part #22. Design patterns. part #2
2. Design patterns. part #2Leonid Maslov
 
Developer Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for BeginnersDeveloper Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for BeginnersJiaxuan Lin
 
Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)Gabor Varadi
 

Semelhante a From Legacy to Hexagonal (An Unexpected Android Journey) (20)

Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applications
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applications
 
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
 
TWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonTWINS: OOP and FP - Warburton
TWINS: OOP and FP - Warburton
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
How to code to code less
How to code to code lessHow to code to code less
How to code to code less
 
10 ways to make your code rock
10 ways to make your code rock10 ways to make your code rock
10 ways to make your code rock
 
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
 
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
 
Refactoring Wunderlist. UA Mobile 2016.
Refactoring Wunderlist. UA Mobile 2016.Refactoring Wunderlist. UA Mobile 2016.
Refactoring Wunderlist. UA Mobile 2016.
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
Jaoo - Open Social A Standard For The Social Web
Jaoo - Open Social A Standard For The Social WebJaoo - Open Social A Standard For The Social Web
Jaoo - Open Social A Standard For The Social Web
 
Googleappengineintro 110410190620-phpapp01
Googleappengineintro 110410190620-phpapp01Googleappengineintro 110410190620-phpapp01
Googleappengineintro 110410190620-phpapp01
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Code
 
Five android architecture
Five android architectureFive android architecture
Five android architecture
 
2. Design patterns. part #2
2. Design patterns. part #22. Design patterns. part #2
2. Design patterns. part #2
 
Developer Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for BeginnersDeveloper Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for Beginners
 
Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)
 

Último

Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLionel Briand
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfStefano Stabellini
 
Understanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM ArchitectureUnderstanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM Architecturerahul_net
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 

Último (20)

Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and Repair
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
 
Understanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM ArchitectureUnderstanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM Architecture
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 

From Legacy to Hexagonal (An Unexpected Android Journey)

  • 1. From Legacy to Hexagonal (An Unexpected Android Journey) Rubén Serrano @Akelael Lead Android Developer @RedboothHQ José Manuel Pereira @JMPergar Android Software Engineer @RedboothHQ
  • 2. Agenda 1. From Legacy Code 2. Towards Hexagonal Architecture 3. To infinity, and beyond!
  • 3. 1. From Le gacy Code
  • 5.
  • 6.
  • 7. One dev from a contractor
  • 8. One dev from a contractor + one senior iOS dev
  • 9. One dev from a contractor + one senior iOS dev
  • 10. One dev from a contractor + one senior iOS dev + one junior iOS dev
  • 11. One dev from a contractor + one senior iOS dev + one junior iOS dev
  • 12. A different Android dev One dev from a contractor + one senior iOS dev + one junior iOS dev
  • 13. A different Android dev One dev from a contractor + one senior iOS dev + one junior iOS dev + one confused Android team
  • 15.
  • 17. 1. We have a huge technical debt
  • 18. 1. We have a huge technical debt
  • 19. HUGE
  • 20.
  • 21. 1. We have huge technical debt 2. We can’t stop developing new features
  • 22. 1. We have huge technical debt 2. We can’t stop developing new features 3. We can’t remove debt at this point and we shouldn’t add any more
  • 26. What have we learnt from pizza?
  • 27. You just don’t eat the whole pizza at once
  • 28. 1. Slice the big methods into small meaningful methods
  • 29. 1. Slice the big methods into small meaningful methods 2. Identify different responsibilities and move them to other classes
  • 30. 1. Slice the big methods into small meaningful methods 2. Identify different responsibilities and move them to other classes 3. Use less coupled framework components (or no components at all)
  • 34. Notifies events View Presenter Model
  • 35. Requests data View Presenter Model
  • 36. Serves data View Presenter Model
  • 37. Change data representation View Presenter Model
  • 38. View Tells how to draw Presenter Model
  • 39. Layout + Activity/ Fragment Presenter Data + Business logic
  • 40. In code (Original code…) http://goo.gl/z5Xn2J
  • 41. listAdapter = MainFragment new SimpleCursorAdapter(getActivity(), android.R.layout.simple_list_item_1, null, new String[]{FakeDatabase.COLUMN_NAME}, new int[]{android.R.id.text1}, 0); listView.setAdapter(listAdapter);
  • 42. getLoaderManager().initLoader(0, null, new LoaderManager.LoaderCallbacks<Cursor>() { @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { return new CursorLoader(getActivity(), MainContentProvider.URI, null, null, null, null); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { listAdapter.swapCursor(data); } @Override public void onLoaderReset(Loader<Cursor> loader) { listAdapter.swapCursor(null); } }); MainFragment
  • 43. In Code (… to MVP) http://goo.gl/Retvli
  • 44. MainView & MainModel public interface MainView { public void swaplListData(Cursor cursor); } public interface MainModel { public void setPresenter(MainPresenter presenter); public void startLoadingData(Context context); }
  • 45. MainFragment public class MainFragment extends Fragment implements MainView { //... @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); presenter = PresenterFactory.getMainPresenter(this); } @Override public void onActivityCreated(Bundle savedInstanceState) { //... presenter.notifyOnCreate(getActivity()); } @Override public void swaplListData(Cursor cursor) { listAdapter.swapCursor(cursor); }
  • 46. MainPresenter public class MainPresenter { private MainView mainView; private MainModel mainModel; //... public void notifyOnCreate(Context context) { mainModel.startLoadingData(context); } public void notifiyLoadedDataAvailable(Cursor cursor) { mainView.swaplListData(cursor); } }
  • 47. PresenterFactory public class PresenterFactory { public static MainPresenter getMainPresenter(MainView view) { MainModel model = new MainCursorModel(); return MainPresenter.newInstance(view, model); } }
  • 48. MainCursorModel public class MainCursorModel implements MainModel { //... @Override public void startLoadingData(Context context) { new LoadDataAsyncTask().execute(context); } private class LoadDataAsyncTask extends AsyncTask<Context, Void, Cursor > { //... @Override protected void onPostExecute(Cursor result) { super.onPostExecute(result); presenter.notifiyLoadedDataAvailable(result); } } }
  • 49. Pros & Cons View decoupled from model Cleaner code and smaller fragment/activities View and model not really decoupled (cursor) All the components use the framework
  • 52. Layout + Activity/ Fragment Presenter Data + Business logic
  • 53. Layout + Activity/ Fragment Data domain Business logic
  • 54. Layout + Activity/ Fragment Database Business logic Network Sensors
  • 55. Database Network Sensors Layout + Activity/ Fragment Business logic
  • 56. Business logic Sensors Network Database Layout + Activity/ Fragment
  • 57. Port Business logic Port Port Port Sensors Network Database Layout + Activity/ Fragment
  • 58. Adapter Port Business logic Port Port Sensors Network Database Layout + Activity/ Fragment Adapter Adapter Port Adapter
  • 59. Adapter Port Business logic Port Port Sensors Network Database Layout + Activity/ Fragment Adapter Adapter Port Adapter
  • 60. Boundary Port Business logic Port Port Sensors Network Database Layout + Activity/ Fragment Boundary Boundary Port Boundary
  • 61. App Core App App Module Core Module App Module App Module App Module App Core Core Core App
  • 62. In code (Hexagonal) http://goo.gl/lIyH0o
  • 63. MainFragment public class MainFragment extends Fragment { //... private MainFragmentBoundary viewBoundary; @Override public void onCreate(Bundle savedInstanceState) { //... viewBoundary = MainFragmentBoundary.newInstance(this); } @Override public void onActivityCreated(Bundle savedInstanceState) { //... viewBoundary.notifyOnCreate(); }
  • 64. MainFragment public void setListAdapter() { listAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, android.R.id.text1, new ArrayList<String>(0)); listView.setAdapter(listAdapter); } public void swapList(List<String> names) { listAdapter.clear(); listAdapter.addAll(names); }
  • 65. MainFragmentBoundary public class MainFragmentBoundary implements MainViewPort { private MainFragment mainFragment; private MainLogic logic; //... public void notifyOnCreate() { logic.notifyOnCreate(); } @Override public void swaplListData(List<String> names) { mainFragment.swapList(names); }
  • 66. MainModelBoundary public class MainModelBoundary implements MainModelPort { private MainLogic logic; private MainRepository repository; //... @Override public void startLoadingData() { repository.startLoadingData(new MainRepository.OnDataLoadedListener() { @Override public void onDataLodaded(Cursor cursor) { notifyDataLoaded(cursor); } }); } private void notifyDataLoaded(Cursor cursor) { List<String> names = mapCursorToList(cursor); logic.notifiyLoadedDataAvailable(names); }
  • 67. MainModelBoundary private List<String> mapCursorToList(Cursor cursor) { List<String> names = new ArrayList<String>(); int nameColumnIndex = cursor.getColumnIndex(FakeDatabase.COLUMN_NAME); while (cursor.moveToNext()) { String name = cursor.getString(nameColumnIndex); names.add(name); } return names; }
  • 68. Pros & Cons Logic is not going to be affected by framework changes Logic is pure Java: easier to test Less changes when replacing a plugin Easier for 2 devs to work on the same feature More complex architecture Need to map each POJO for each layer What happens when the plugins need to cooperate?
  • 69. 3. To infinity, and beyond!
  • 70. One plugin, N commands
  • 71. Boundary Port Business logic Port Port Sensors Network Database Layout + Activity/ Fragment Boundary Boundary Port Boundary
  • 72. Model Plugin Layout + Activity/ Fragment Boundary Business Boundary logic Port Port
  • 73. Create task Send chat message Update note Request projects Business logic Port Model Plugin Boundary
  • 75. Create task Send chat message Update note Request projects Business logic Port Model Plugin Boundary
  • 76. We don’t like: callback’s hell + AsyncTasks
  • 77. We don’t like: callback’s hell + AsyncTasks We don’t mind (but could be a problem): only commands in separate threads
  • 78. We don’t like: callback’s hell + AsyncTasks We don’t mind (but could be a problem): only commands in separate threads We would love: RxJava
  • 80. Model Plugin Layout + Activity/ Fragment Boundary Business Boundary logic Port Port
  • 81. Model Plugin Layout + Activity/ Fragment Presenter Use Case Model Plugin Use Case Repository Model Plugin Use Case
  • 82. Conclusions photo by Daniel Sancho
  • 83. When? • If you expect 2+ devs working on the same feature • Unless you are sure the app is going to die in a near future • You know for sure you will change your plugins
  • 84. How? 1. Simple refactors 2. Model View Presenter 3. Hexagonal
  • 85. How? 1. Simple refactors 2. Model View Presenter 3. Hexagonal 4. Clean Architecture