droid-pure-kotlin-application π§β
πΈπππππππππππ
π‘
compose
for the presentation-layer
, kotlin
for writing the business-logic
, kotlin-dsl
for handeling the dependencies.
Single activity
architecture where compose-navigation
is used for navigating between the screens. Also care is taken so that dependencies used in presentation layer
is not available for domain layer
and data layer
. Multimodule architecture used with reusability
by adhering SOLID-principles
, also unit-testing
, integration-testing
in mind. Coding for abstraction rather than implementation
is followed in the project that enables testing
and so that fakes
can be easily provided for abstractions for testing individual components.
πΏπππ ππππππ
ποΈ
πππ’ πππππ ππππππππππππ ππ ππππππ
ποΈ
πππ’ πππππ ππππππ ππ ππππ ππ πππππππ
ποΈ
π³πππππππππ’ πΈππππππππ
ποΈ
π²ππππππππππππ ππππ πππ πππ πππ’πππ
ποΈ
πΈπππππππππππππ ππ ππΎπ»πΈπ³ ππππππππππ
ποΈ
This applicaion is developed keeping in mind of clean architecture principles
SINGLE RESPONSIBILITY | OPEN CLOSED PRINCIPLE | LISKOV SUBSTITUTION PRINCIPLE | INTERFACE SEGREGATION PRINCIPLE | DEPENDENCY INVERSION PRINCIPLE |
---|---|---|---|---|
Each class having one responsibility. If there is a change in it, it must be because of only one reason only. If there are two reasons for a class to change, then it violates single responsibility principle. | This indicates that the class is open for extension but closed for modification | When we have a class that is inheriting the parent, the parent class functionality must be replaceable using the child class without modifying the functionality of parent class | Here we should not force a class to do something that it does not want to do, Say a class is implementing interface then it overrides all the functions in it. Now if we donβt want a function of interface to be implemented then we give the default behaviour for the interface and so that it will not force the child class to override that method | This indicates that, a class must depend on abstraction instead of concrete implementation. Say we want a implementation to be used for a class thence need to inject a abstraction for it instead of concrete implementation so that if its implementation changes in future , it must not affect where the abstract version of it is implemented |
π°πππππππππ πππ π³ππππππππππππ π?? πππππ ππππππ ππππππππππππ
ποΈ
π°πππππππππ
Clear separation |
Faster build time |
---|---|
β’ Each of the modules is a library and it can depend on each other β’ If there is a scenario where one library is not dependent on another, Then they can't access each other β’ Thus, instead of adding terms of separate packages in the app module, we can enforce strict modularity by modularising it β’ In a large project and big team we can enforce, who works on which project. Thus one person working on one won't affect other modules |
β’ Using the multi-module we can decrease the build time. When in multi-module each module will use separate threads so build time will decrease since all modules will build independently β’ Since Gradle needs to build the module that has been changed, it doesn't need to make the modules that have not been changed β’ Point to note here is that, say there is a root module with few child modules, if the root module changes, all the child modules also need to rebuild β’ Support for instant apps and dynamic feature module β’ Using this we can make parts of our app reusable |
π³ππππππππππππ
β’ Lot of initial code
β’ Not knowing what problem it will cause
πΌπ
π
πΌ πππππππππ ππππ ππ πππππ-ππππππ πππ πππππ ππππππππππππ
πππππππ πππ ππππ
π§ͺ
features
of the code, Each of the features
contain three layers namely data
, domain
, presentation
.
core
layer we can write tests for the implementation
and repository
for each of modules.
Development in progress
πΏππππππ πππππππππ ππ πππ πππππππ
π¦
Project Folder # Root Package
.
βββ app # It is the starting point for the application
β βββ activity # Entire application has just one activity
β βββ view-model # This will be the view-model for the single activity
| βββ navigation # It contains the navigation compose and the routes used in the application
β βββ application # Singleton used at application level
|
βββ buildSrc # It contains all project dependencies & its version references that can be modified from one place
|
βββ core # Module with code that can be re-used in all the modules. This also helps us to manage them easily
β βββ res # String resources used in the project
β βββ java
β βββ data # data layer of the core module
β β βββ implementation # contains implementations of the features hosted in core module
β β βββ repository # contains repository for the features
β β
β βββ di # Hilt dependency injection
β βββ domain # Domain layer for all the reusable third party features in project
β β βββ features # Contains interface for all the reusable third party features in project
β β βββ models # data modules used thorught the project
β β
β βββ platform # Can old other miscellaneous things needed in project, some are listed below
β βββ base # Can hold base classes that are used in different features in project
β βββ extensions # kotlin extensions that can be kept in one place and handeled
β βββ functional # Other util functional elements in teh project
β
β
βββ core-ui # Module contains all the UI related things in the project
β βββ res
β β βββ drawable # Contains all the drawables needed for the project
β β βββ font # Place we can store the font files in the project
β β
β βββ java
β βββ composables # Here we store the reusable composables used for the project
β βββ theme # Contains the theme file used in project
β
βββ features # The module contains all the features used in project
β
βββ common # sub-module that holds the logic that is re-used in multiple features
β β
β β
β βββ common_data # sub-module for data
β β βββ di # di for current module
β β βββ repository # repository used for injection
β β βββ service # service used in repository
β β
β β
β βββ common_domain # sub-module for domain
β βββ di # di used for having use-case data object instance
β βββ repository # interface of the repository
β βββ usecases # individual logic for domain data
β
βββ login # sub-module that contains one feature
β
β
βββ login_data # sub-module for data
β βββ di # di used to build the module and create instances of service and repository of current module
β βββ repository # implementation of the repository
β βββ service # service used in repository
β
β
βββ login_domain # sub-module for domain
β βββ di # di used for having use-case data object instance
β βββ repository # interface of the repository
β βββ usecases # individual logic for domain data
β
β
βββ login_presentation # sub-module for presentation
βββ states # states of the data displayed and view-model
βββ view-composable # composable representing a screen
βββ viewmodel # view model for the composable
π²πππ πππππππ’
πΊ
Run Kt lint
π§
// To check the list of errors
./gradlew ktlintCheck
// Try to auto auto format errors
./gradlew ktlintFormat
π·ππ ππ πππ πππ ππππππ πππππππππππ
π£
ππππ πππππ
ποΈ
οΈ
What | How |
---|---|
|
πΉππππππ π²ππππππ |
|
π²ππππ π°πππππππππππ |
|
π·πππ |
|
π²πππππππππ + Flow |
|
π΅πππππππ |
π²ππππππππ’ ππππππππ πππππππππ
π§°
Demo contains three screen application namely registration
, login
, forgot-password
and external service used here is firebase
. User can create an account using registration
. User can login and once login is successful the user details is saved in data-store
π²πππππππππ
πββοΈ
Read contribution guidelines for more information regarding contribution.
π΅πππππππ
βοΈ
Feature requests are always welcome, File an issue here.
π΅πππ ππππ πππππππ ππππππ
?
β€οΈ
Support it by clicking the
π»ππππππ
π³
This project is licensed under the Apache License 2.0 - see the LICENSE file for details