SlideShare a Scribd company logo
1 of 78
Download to read offline
Write once, ship multiple
times
ŽELJKO PLESAC
Independent design & development agency
108 people in 3 offices
18 Android engineers
WHITE LABEL SYSTEMS
A white label product is a product or
service produced by one company
(the producer) that other companies
(the marketers) rebrand to make it
appear as if they had made it.
- WIKIPEDIA
Provides your brand with a refined product.
Outsourcing the development to a trusted thirty-party company.
Saving time and money.
Lack of control.
Lack of customisation.
Unified product vision.
HOW TO BUILD WHITE LABEL APPS?
NO.
Carefully
designing the
system.
PREREQUISITES
THOU SHALL NOT USE FAT CLIENTS.
Fat clients
• not customisable on the fly
• new app version for each new
feature
• prone to errors
• hard to maintain
MOST OF THE SYSTEMS FAIL ON THIS
POINT.
SYSTEM ARCHITECTURE
Flavours.
Modules.
FLAVOUR ARCHITECTURE
Main flavour.
Product flavours.
MAIN FLAVOUR
• default product
• used only for demo purposes
• contains shared code
• uses default set of resources
• can be customised by configuration file
FLAVOURS
• each flavour is an application
• holds product specific resources
• contains only product specific code
• should be as minimal as possible
ADVANTAGES
Easy to maintain and develop.
Easy to configure.
Resource and code sharing between main flavour and product flavour.
DISADVANTAGES
Customisation is extremely hard.
Exponential increase of files and resources.
MODULE ARCHITECTURE
Main module.
Product module.
MAIN MODULE
• set of core functionalities
• default resources
• can be configured by configuration file
PRODUCT MODULES
• each module is one app
• product specific code and resources
ADVANTAGES
Easy to customise.
Apps are isolated.
Business logic can be product specific.
DISADVANTAGES
Hard to maintain.
Losing focus.
CUSTOMIZE APP BEHAVIOUR
BUILD CONFIG FILE
Customise constant values between the apps.
productFlavors {
white {
dimension ‘product’
applicationId ‘com.infinum.white’
buildConfigField STRING, GOOGLE_ANALYTICS_ID, ‘”analyticsIdForWhite”’
buildConfigField STRING, API_URL, ‘”www.api.co/white/v1”’
manifestPlaceholders = [urlScheme: “white”]
}
blue {
dimension ‘product’
applicationId ‘com.infinum.blue’
buildConfigField STRING, GOOGLE_ANALYTICS_ID, ‘”analyticsIdForBlue”’
buildConfigField STRING, API_URL, ‘”www.api.co/blue/v1”’
manifestPlaceholders = [urlScheme: “blue”]
}
}
HostModule.setEndpoint(BuildConfig.API_URL);
AnalyticsModule.setGoogleAnalyticsId(BuildConfig.
GOOGLE_ANALYTICS_ID);
BONUS - CUSTOMISE RESOURCES
applicationVariants.all {

resValue XML_STRING, SEARCH_AUTHORITY, applicationId + '.providers.SearchSuggestionsProvider'

}
CONFIGURATION FILE
Locally cached or obtained from the API.
More flexible that BuildConfig file.
Descriptive method naming.
CUSTOMISE APPLICATION ON THE FLY
• enable/disable features
• data flow
• screen flow
public interface AppConfig {
boolean isSocialLoginEnabled();
List<MenuItem> getLoggedInUserNavigationMenu();
}
public class WhiteConfiguration implements AppConfig {
private static final List<MenuItem> LOGGED_IN_USER_NAVIGATION_MENU = Collections.unmodifiableList(Arrays.asList(
new MenuItem(R.drawable.ic_gamepad, R.string.home),
new MenuItem(R.drawable.ic_settings, R.string.settings),
new MenuItem(R.drawable.ic_settings, R.string.info)
));
@Override
public boolean isSocialLoginEnabled() {
return !BuildConfig.DEBUG || BuildConfig.APPLICATION_ID.endsWith(STAGING_APP_ID);
}
@Override
public List<MenuItem> getLoggedInUserNavigationMenu() {
return LOGGED_IN_USER_NAVIGATION_MENU;
}
}
DESCRIPTIVE METHODS
Method names should be descriptive and should not contain product names.
public interface AppConfig {
boolean isWhite();
boolean isBlue();
}
PROGRAM TO INTERFACES
INTERFACES
Extract functionalities.
Integrate with external dependencies.
Default or product specific implementation.
public interface ImageLoader {
void displayImage(ImageView imageView, @NonNull String imageUrl);
void displayImage(ImageView imageView, @NonNull File imageFile);
}
@Module
public class ProvidersModule {
@Provides
public ImageLoader provideImageLoader(ImageLoaderType type) {
switch(type){
case GLIDE:
return new GlideImageLoader();
default:
return new PicassoImageLoader();
}
}
provided with
configuration file
Include external dependencies only for specific product types.
whiteCompile 'com.github.bumptech.glide:glide:3.6.1'
blueCompile 'com.github.bumptech.glide:glide:3.5.0’
GROUP FUNCTIONALITIES IN
FEATURES
Features
Each functionality is a feature.
Can be enabled/disabled.
Can be customised.
Feature
Contains everything what’s needed
for their integration.
Opened or closed.
CUSTOMISATION EXAMPLES
Default resources + product specific resources.
Default resources + product specific resources.
Same key is needed.
Provide presenter implementation per product.
Provide presenter implementation per product.
DI has to be handled per product (no default option).
Default and product specific behaviour.
Default and product specific behaviour.
Interfaces, features and configuration.
WHAT?
Feature has a default navigation flow, but it has to be customised only for one
or two products.
public interface Navigation {
<T> void createTrip(FragmentActivity activity, int
createTripRequestCode, Map<String, T> params);
}
public interface NavigationBehaviour {
<T> void startCreateTripScreen(FragmentActivity activity, int createTripRequestCode, Map<String, T>
params);
}
public class NavigationManager implements Navigation {
private NavigationBehaviour navigationBehaviour;
public NavigationManager(NavigationBehaviour navigationBehaviour) {
this.navigationBehaviour = navigationBehaviour;
}
@Override
public <T> void createTrip(FragmentActivity activity, int createTripRequestCode, Map<String, T>
params) {
navigationBehaviour.startCreateTripScreen(activity, createTripRequestCode, params);
}
}
public class DefaultNavigationBehaviour implements NavigationBehaviour {
@Override
public <Parcelable> void startCreateTripScreen(FragmentActivity activity, int createTripRequestCode,
Map<String, Parcelable> params) {
Intent intent = CreateTripActivity.newIntent(activity, TripType.WALKING, recentStops);
activity.startActivityForResult(intent, createTripRequestCode);
}
}
public class BlueNavigationBehaviour implements NavigationBehaviour {
@Override
public <Parcelable> void startCreateTripScreen(FragmentActivity activity, int createTripRequestCode,
Map<String, Parcelable> params) {
Intent intent = GoogleMapsUtils.newIntent(activity, TripType.CAR, recentStops);
activity.startActivityForResult(intent, createTripRequestCode);
}
}
public class RedNavigationBehaviour implements NavigationBehaviour {
@Override
public <Parcelable> void startCreateTripScreen(FragmentActivity activity, int createTripRequestCode,
Map<String, Parcelable> params) {
Intent intent = ChromeCustomTabsUtils.newIntent(activity, TripType.CAR, recentStops);
activity.startActivityForResult(intent, createTripRequestCode);
}
}
CUSTOMIZE EVERYTHING?
When too much customisation is needed.
Different product vision.
FLAVOUR MODULE
STAND ALONE
APPLICATION
VERSIONING
SEMANTIC VERSIONING 2.0.0
PATCH UPDATES
Product specific.
MINOR UPDATES
Product or system specific.
MAJOR UPDATES
Always system specific.
APP UPDATES
Mechanism for forcing app updates - PrinceOfVersion.
ROUNDUP
Thin clients.
Architecture planning.
Offer limited customisation.
Leave the system.
Visit infinum.co or find us on social networks:
infinum.co infinumco infinumco infinum
Thank you!
ZELJKO.PLESAC@INFINUM.CO
@ZELJKOPLESAC

More Related Content

Similar to Write once, ship multiple times

Modeveast Appcelerator Presentation
Modeveast Appcelerator PresentationModeveast Appcelerator Presentation
Modeveast Appcelerator Presentation
Aaron Saunders
 
Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development
Mahmoud Hamed Mahmoud
 

Similar to Write once, ship multiple times (20)

Better User Experience with .NET
Better User Experience with .NETBetter User Experience with .NET
Better User Experience with .NET
 
Use AppDynamics SDK to Integrate with your Applications - AppSphere16
Use AppDynamics SDK to Integrate with your Applications - AppSphere16Use AppDynamics SDK to Integrate with your Applications - AppSphere16
Use AppDynamics SDK to Integrate with your Applications - AppSphere16
 
04 objective-c session 4
04  objective-c session 404  objective-c session 4
04 objective-c session 4
 
MOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentMOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app development
 
When Smalltalk Meets the Web
When Smalltalk Meets the WebWhen Smalltalk Meets the Web
When Smalltalk Meets the Web
 
Code Generation in Magento 2
Code Generation in Magento 2Code Generation in Magento 2
Code Generation in Magento 2
 
Android 103 - Firebase and Architecture Components
Android 103 - Firebase and Architecture ComponentsAndroid 103 - Firebase and Architecture Components
Android 103 - Firebase and Architecture Components
 
James Turner (Caplin) - Enterprise HTML5 Patterns
James Turner (Caplin) - Enterprise HTML5 PatternsJames Turner (Caplin) - Enterprise HTML5 Patterns
James Turner (Caplin) - Enterprise HTML5 Patterns
 
Modeveast Appcelerator Presentation
Modeveast Appcelerator PresentationModeveast Appcelerator Presentation
Modeveast Appcelerator Presentation
 
Introduction to Palm's Mojo SDK
Introduction to Palm's Mojo SDKIntroduction to Palm's Mojo SDK
Introduction to Palm's Mojo SDK
 
Telerik Kendo UI Overview
Telerik Kendo UI OverviewTelerik Kendo UI Overview
Telerik Kendo UI Overview
 
VS Code and Modern Development Environment Preview
VS Code and Modern Development Environment PreviewVS Code and Modern Development Environment Preview
VS Code and Modern Development Environment Preview
 
Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development
 
Lean Development: Design Through Iterative Experiments
Lean Development: Design Through Iterative ExperimentsLean Development: Design Through Iterative Experiments
Lean Development: Design Through Iterative Experiments
 
MongoDB.local Atlanta: Introduction to Serverless MongoDB
MongoDB.local Atlanta: Introduction to Serverless MongoDBMongoDB.local Atlanta: Introduction to Serverless MongoDB
MongoDB.local Atlanta: Introduction to Serverless MongoDB
 
EVOLVE'13 | Enhance | Ecommerce Framework | Paolo Mottadelli
EVOLVE'13 | Enhance | Ecommerce Framework | Paolo MottadelliEVOLVE'13 | Enhance | Ecommerce Framework | Paolo Mottadelli
EVOLVE'13 | Enhance | Ecommerce Framework | Paolo Mottadelli
 
Evolve13 cq-commerce-framework
Evolve13 cq-commerce-frameworkEvolve13 cq-commerce-framework
Evolve13 cq-commerce-framework
 
SharePoint Saturday Atlanta 2015
SharePoint Saturday Atlanta 2015SharePoint Saturday Atlanta 2015
SharePoint Saturday Atlanta 2015
 
Opticon 2015 - Getting Started with the Optimizely Developer Platform
Opticon 2015 - Getting Started with the Optimizely Developer PlatformOpticon 2015 - Getting Started with the Optimizely Developer Platform
Opticon 2015 - Getting Started with the Optimizely Developer Platform
 
Android Development : (Android Studio, PHP, XML, MySQL)
Android Development : (Android Studio, PHP, XML, MySQL)Android Development : (Android Studio, PHP, XML, MySQL)
Android Development : (Android Studio, PHP, XML, MySQL)
 

More from Željko Plesac (7)

What the hype
What the hypeWhat the hype
What the hype
 
Crash wars - The handling awakens v3.0
Crash wars - The handling awakens v3.0Crash wars - The handling awakens v3.0
Crash wars - The handling awakens v3.0
 
Crash wars - The handling awakens
Crash wars - The handling awakensCrash wars - The handling awakens
Crash wars - The handling awakens
 
Crash Wars - The handling awakens
Crash Wars  - The handling awakensCrash Wars  - The handling awakens
Crash Wars - The handling awakens
 
Android Lollipop
Android LollipopAndroid Lollipop
Android Lollipop
 
Android tips and tricks
Android tips and tricksAndroid tips and tricks
Android tips and tricks
 
Android studio
Android studioAndroid studio
Android studio
 

Recently uploaded

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Recently uploaded (20)

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 

Write once, ship multiple times