• Stars
    star
    978
  • Rank 46,823 (Top 1.0 %)
  • Language
    Kotlin
  • License
    MIT License
  • Created almost 7 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A fork of our clean architecture boilerplate using the Model-View-Intent pattern

Build Status codecov Codacy Badge

Android Clean Architecture MVI Boilerplate

Note: This is a fork of our original Clean Architecture Boilerplate, except in this repo we have switched out the MVP approach found in the presentation layer to now use ViewModels from the Android Architecture Components Library. The caching layer now also uses Room.

Welcome πŸ‘‹ We hope this boilerplate is not only helpful to other developers, but also that it helps to educate in the area of architecture. We created this boilerplate for a few reasons:

  1. To experiment with modularisation
  2. To experiment with the Android Architecture Components
  3. To share some approaches to clean architecture, especially as we've been talking a lot about it
  4. To use as a starting point in future projects where clean architecture feels appropriate

It is written 100% in Kotlin with both UI and Unit tests - we will also be keeping this up-to-date as libraries change!

Disclaimer

Note: The use of clean architecture may seem over-complicated for this sample project. However, this allows us to keep the amount of boilerplate code to a minimum and also demonstrate the approach in a simpler form.

Clean Architecture will not be appropriate for every project, so it is down to you to decide whether or not it fits your needs πŸ™‚

Languages, libraries and tools used

Requirements

Architecture

The architecture of the project follows the principles of Clean Architecture. Here's how the sample project implements it:

architecture

The sample app when run will show you a simple list of all the Bufferoos (Buffer team members!).

Drawing

Let's look at each of the architecture layers and the role each one plays :)

architecture

User Interface

This layer makes use of the Android Framework and is used to create all of our UI components to display inside of the Browse Activity. The layer receives its data from the Presentation layer and when retrieved, the received models are mapped using the Bufferoo Mapper so that the model can be mapped to this layer's interpretation of the Bufferoo instance, which is the BufferooViewModel. The Activity makes use of the BrowseBufferoosViewModel to retrieve data.

Presentation

This layer's responsibility is to handle the presentation of the User Interface, but at the same time knows nothing about the user interface itself. This layer has no dependence on the Android Framework, it is a pure Kotlin module. Each ViewModel class that is created implements the ViewModel class found within the Architecture components library. This ViewModel can then be used by the UI layer to communicate with UseCases and retrieve data. The BrowseBufferoosViewModel returns an instance of a BrowseUiModel which contains data that can be used by the UI.

The ViewModels use an instance of a FlowableUseCase from the Domain layer to retrieve data. Note here that there is no direct name reference to the UseCase that we are using - we do inject an instance of the GetBufferoos UseCase, however.

The ViewModel receives data from the Domain layer in the form of a Bufferoo. These instances are mapped to instance of this layers model, which is a BufferooView using the BufferooMapper.

Domain

The domain layer responsibility is to simply contain the UseCase instance used to retrieve data from the Data layer and pass it onto the Presentation layer. In our case, we define a GetBufferoos - this use case handles the subscribing and observing of our request for data from the BufferooRepository interface. This UseCase extends the FlowableUseCase base class - therefore we can reference it from outer layers and avoid a direct reference to a specific implementation.

The layer defines the Bufferoo class but no mapper. This is because the Domain layer is our central layer, it knows nothing of the layers outside of it so has no need to map data to any other type of model.

The Domain layer defines the BufferooRepository interface which provides a set of methods for an external layer to implement as the UseCase classes use the interface when requesting data.

architecture

Data

The Data layer is our access point to external data layers and is used to fetch data from multiple sources (the cache and network in our case). It contains an implementation of the BufferooRepository, which is the BufferooDataRepository. To begin with, this class uses the BufferooDataStoreFactory to decide which data store class will be used when fetching data - this will be either the BufferooRemoteDataStore or the BufferooCacheDataStore - both of these classes implement the BufferooDataStore repository so that our DataStore classes are enforced.

Each of these DataStore classes also references a corresponding BufferooCache and BufferooRemote interface, which is used when requesting data from an external data source module.

This layers data model is the BufferooEntity. Here the BufferooMapper is used to map data to and from a Bufferoo instance from the domain layer and BufferooEntity instance from this layer as required.

Remote

The Remote layer handles all communications with remote sources, in our case it makes a simple API call using a Retrofit interface. The BufferooRemoteImpl class implements the BufferooRemote interface from the Data layer and uses the BufferooService to retrieve data from the API.

The API returns us instances of a BufferooModel and these are mapped to BufferooEntity instance from the Data layer using the BufferooEntityMapper class.

Cache

The Cache layer handles all communication with the local database which is used to cache data.

The data model for this layer is the CachedBufferoo and this is mapped to and from a BufferooEntity instance from the Data layer using the BufferooEntityMapper class.

Conclusion

We will be happy to answer any questions that you may have on this approach, and if you want to lend a hand with the boilerplate then please feel free to submit an issue and/or pull request πŸ™‚

Again to note, use Clean Architecture where appropriate. This is example can appear as over-architectured for what it is - but it is an example only. The same can be said for individual models for each layer, this decision is down to you. In this example, the data used for every model is exactly the same, so some may argue that "hey, maybe we don't need to map between the presentation and user-interface layer". Or maybe you don't want to modularise your data layer into data/remote/cache and want to just have it in a single 'data' module. That decision is down to you and the project that you are working on πŸ™ŒπŸ»

Thanks

A special thanks to the authors involved with these two repositories, they were a great resource during our learning!

More Repositories

1

android-clean-architecture-boilerplate

An android boilerplate project using clean architecture
Kotlin
3,651
star
2

clean-architecture-components-boilerplate

A fork of our clean architecture boilerplate, this time using the Android Architecture Components
Kotlin
1,277
star
3

BufferTextInputLayout

A simple customised version of the TextInputLayout from the Android Design Support Library ⌨️
Java
983
star
4

AdaptableBottomNavigation

A simpler way for implementing the Bottom Navigation View on Android
Java
830
star
5

android-guidelines

Project Guidelines for the Android Buffer App
Shell
750
star
6

buffer-ios-image-viewer

The BFRImageViewer is a turnkey solution to present images within your iOS app πŸŽ‰!
Objective-C
399
star
7

clean-architecture-koin-boilerplate

A fork of our clean architecture boilerplate, this time using Koin
Kotlin
331
star
8

MultiActionSwipeHelper

An Android RecyclerView Swipe Helper for handling multiple actions per direction
Java
296
star
9

CounterView

A simple Android counter view for showing edittext character counts
Kotlin
176
star
10

Thumby

An Android video thumbnail picker
Kotlin
173
star
11

buffer-components

Buffer's shared collection of React UI components πŸ€œπŸ€›
JavaScript
139
star
12

ReactivePlayBilling

An RxJava wrapper for the Google Play Billing Library
Kotlin
117
star
13

buzzer

A little buzzer app for running your own quizzes or game shows!
JavaScript
94
star
14

buffer-chrome

Buffer for Chrome lets you easily add great articles, pictures and videos to your Buffer and we automagically share them for you through the day!
JavaScript
66
star
15

SocialLinkify

An Android library for linking @ mentions & Hashtags to their corresponding social network
Kotlin
65
star
16

BFRReorderTableView

The BFRTableReorder is an out of the box solution to add long press reordering to your ASDK apps
Objective-C
57
star
17

ui

✨ Buffer's UI Components library and Style Guide✨
TypeScript
51
star
18

old-diversity-dashboard

R
49
star
19

kiner

Python AWS Kinesis Producer with error handling and thread support.
Python
45
star
20

README

Welcome, friend! Here's an overview to our engineering team's documentation
Shell
43
star
21

sqs-worker-go

Go
38
star
22

code-of-conduct

Buffer's Employee Code of Conduct
36
star
23

diggdigg

DiggDigg is the floating all-in-one share bar for your WordPress website.
PHP
33
star
24

buffer-ios-sdk

Buffer iOS SDK
Objective-C
30
star
25

javascript-style-guide

Buffer's JavaScript style guide
24
star
26

Biscotti

A collection of Custom Actions and Matchers for Espresso Testing
Kotlin
23
star
27

buffer-blog-v2

Buffer Blog design starting July 2014
PHP
21
star
28

bootstrap-datepicker

Our own fork of eternicode's bootstrap datepicker that includes time selection.
21
star
29

buffer-extension-shared

Shared code between Buffer extensions
JavaScript
21
star
30

buffer-style

The Buffer Style Guide
JavaScript
20
star
31

EKG

Kubernetes Health And Liveness Check
JavaScript
20
star
32

android-components

Shared components for Buffer Android apps
Kotlin
19
star
33

carden

Service to save MongoDB Change Streams (oplog) records into Big Query
Python
19
star
34

buffer-php-style-guide

Buffer's PHP style guide
19
star
35

pylooker

A Python interface to Looker API
Python
16
star
36

lookerpy

A Python API client for Looker
Python
15
star
37

CustomViewIndicator

An Android ViewPager indicator that allows you to provide custom views for display
Kotlin
15
star
38

sharejs

Trigger the Buffer Share popup from any DOM element
JavaScript
14
star
39

Reactive-Pusher

An RxJava wrapper for the Pusher Java Library [Work in progress]
Kotlin
13
star
40

facebook-api-wrapper

Buffer's Facebook PHP API wrapper
PHP
13
star
41

churnado

Churn forecasting tool
R
13
star
42

buffer-redux-hover

Keep React component hover state in redux
JavaScript
12
star
43

omniauth-buffer2

Omniauth strategy to allow Ruby clients to easily use the Buffer API.
Ruby
12
star
44

k8s-jenkins-pipeline

Jenkins Pipeline Library for k8s Deployment Using Helm Chart
Groovy
11
star
45

stacklogging

Python logging integration with Google Cloud Stackdriver API.
Python
11
star
46

buffer-extensions

Main repo for extension code. Note: this has nested submodules
JavaScript
11
star
47

buffer-firefox

Buffer for Firefox
JavaScript
10
star
48

github-notify-client

Get system notifications when you get PRs assigned to you!
JavaScript
10
star
49

buffer-web-components

Buffer Dashboard Specific Components
JavaScript
10
star
50

buffer-sharekit

A Buffer plugin for your ShareKit sharing menu for iOS
Objective-C
9
star
51

rsdf

Some functions to help Pandas DataFrames communicate with Redshift
Python
9
star
52

twilio-to-slack

πŸ“²πŸ’¬ A simple app to forward SMS messages from a Twilio number to a Slack channel
JavaScript
9
star
53

restream

Replay Firehose Streams in Kinesis Streams!
Python
9
star
54

buffer-ruby-deprecated

Official Ruby API wrapper for Buffer
Ruby
9
star
55

dbt-bigquery-auditlog

Get an overview of all cost and performance data for your BigQuery project
9
star
56

BFRGIFRefreshControl

Objective-C
8
star
57

BufferSwiftKit

Swift based SDK to access the Buffer API. The main goal is to provide a simple and easy interface to use Buffer in your iOS apps.
Swift
8
star
58

micro-rpc

Async RPC microservices made easy
JavaScript
8
star
59

buffer-safari

Buffer for Safari
JavaScript
7
star
60

jquery-dragme

A super lightweight jQuery plugin for dragging elements using CSS3 Transforms
JavaScript
7
star
61

extender

Cross-Browser Extension library and build tool
Ruby
6
star
62

buffer-quality-dashboard

GitHub issue dashboard
JavaScript
6
star
63

css-style-guide

How we CSS at Buffer
6
star
64

kubesecret

A tool to manage secrets in kubernetes
JavaScript
6
star
65

tracking-plan-kit

Utilities for managing Buffer's Data Tracking Plan
Python
5
star
66

segment-config-api

A Python Wrapper for Segment's Config API
Python
4
star
67

buffer-talks

Bufferoo Talks - built on Jekyll and Remark
HTML
4
star
68

docker-demos

Intro to Docker: Images + Containers
Dockerfile
4
star
69

buffer-static-upload

πŸ“β†’β˜οΈπŸ€˜ Making it easy to upload your static assets
Go
4
star
70

aws-key-auditor

Get all keys from an AWS account and send an email if a key is getting old
JavaScript
4
star
71

app-shell

Buffer's shared App Shell for front-end applications
TypeScript
3
star
72

cerone

Extensible consumer made for applications using Amazon's Kinesis Python Client Library (KCL).
Python
3
star
73

mongoct

MongoDB Change Streams tracker.
Python
3
star
74

buffer-bot

DEPRECATED
CoffeeScript
3
star
75

buffer-scripts

⌨️ A collection of useful scripts for all sorts of manual tasks!
Shell
3
star
76

buffer-code-exercise-api

A small api server which will be used in the Buffer interview code exercise.
JavaScript
3
star
77

buffer-opensource

Buffer ❀️ Open Source. Static site generator for Buffer's Open Source Site (https://bufferapp.github.io/)
HTML
2
star
78

gprc-metrics-poc

gRPC-based Metrics Collection pipeline proof-of-concept monorepo
JavaScript
2
star
79

convoyslit

Streamlit app to quickly explore convoys models from BigQuery queries
Python
2
star
80

buffer-js-shutdown-helper

Shutdown your Express.js apps gracefully
JavaScript
2
star
81

buffer-icons

Custom Buffer fonts for all!
HTML
2
star
82

micro-rpc-client

Universal JS RPC Client https://github.com/bufferapp/micro-rpc/
JavaScript
2
star
83

helpscout-api

A Python interface to Helpscout's API
Python
2
star
84

stripe-pipeline

A simple data pipeline for Stripe API events to Redshift
Python
2
star
85

cricket

Your personal Jiminy Cricket when posting online.
Python
2
star
86

pipub

Pipe data from the command line to Google Pubsub.
Python
2
star
87

go-base-worker

Golang packages needed to build a consumers
Go
2
star
88

buffer-js-dragme

module for dragging components
JavaScript
2
star
89

streamlit-causal-impact

Streamlit app to run Causal Infence in your CSVs
Python
2
star
90

android-utils

Common utilities used in our android projects
Kotlin
2
star
91

manual-payments

R
2
star
92

bufferapp.github.io

Buffer's Development Driven Values
HTML
1
star
93

buffer-branding-2018

HTML
1
star
94

buffer-js-logger

Node.js logging for Buffer applications
JavaScript
1
star
95

buffer-update-converters

Convert statuses from Twitter, Facebook and Instagram into Buffer updates
PHP
1
star
96

php-bufflog

php logger for all PHP Buffer services
PHP
1
star
97

dd-tracing-logging-examples

JavaScript
1
star
98

buffer-js-request

JS interface to send requests – thin wrapper around fetch()
JavaScript
1
star
99

slack-channels

Analysis on Buffer's slack channels
Jupyter Notebook
1
star
100

buffer-standards

Standard configuration for shared packages/tools at Buffer
TypeScript
1
star