{"id":24972415,"url":"https://github.com/iamjosephmj/Rx-Clean","last_synced_at":"2025-03-29T05:41:00.830Z","repository":{"id":217846393,"uuid":"347596083","full_name":"iamjosephmj/Rx-Clean","owner":"iamjosephmj","description":"This repo is a learning material for Clean Architecture (aka Uncle Bob's Style).","archived":false,"fork":false,"pushed_at":"2021-03-26T06:00:48.000Z","size":1142,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-13T09:47:56.325Z","etag":null,"topics":["android","android-development","architecture-patterns"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/iamjosephmj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-03-14T09:39:32.000Z","updated_at":"2023-10-23T00:31:19.000Z","dependencies_parsed_at":"2024-01-18T13:27:27.926Z","dependency_job_id":"773c663d-4c7a-49f4-8722-c75fa7946bb0","html_url":"https://github.com/iamjosephmj/Rx-Clean","commit_stats":null,"previous_names":["iamjosephmj/rx-clean","imjoz/rx-clean"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iamjosephmj%2FRx-Clean","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iamjosephmj%2FRx-Clean/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iamjosephmj%2FRx-Clean/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iamjosephmj%2FRx-Clean/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iamjosephmj","download_url":"https://codeload.github.com/iamjosephmj/Rx-Clean/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246144978,"owners_count":20730493,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-development","architecture-patterns"],"created_at":"2025-02-03T17:09:26.573Z","updated_at":"2025-03-29T05:41:00.810Z","avatar_url":"https://github.com/iamjosephmj.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/iamjosephmj/Rx-Clean/blob/master/repo-res/images/clean.png\" /\u003e\n\u003c/p\u003e\n\n# Rx-Clean\n\n[![License MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=flat)]()\n[![Public Yes](https://img.shields.io/badge/Public-yes-green.svg?style=flat)]()\n\n\u003cp\u003e\nI hope you all are going well. Are you looking for a sound architectural pattern that will help you to get rid of the \ncomplexity of your project? Have you heard of the Clean Architecture but don't know what all the fuzz is about? You are in the \nright place. \n\u003cbr\u003e\nIn this tutorial, I will take you through :\n\n* What Clean Architecture is\n* Why it’s important to use architecture patterns in software\n* When to use Clean Architecture and SOLID principles\n* How to implement Clean Architecture on Android \n\n\u003cbr\u003e\n\nThe networking library is implemented with RxKotlin, please refer to \u003ca style = \"color: white\" href =\"https://github.com/iamjosephmj/learn-rx\"\u003e`LearnRx`\u003c/a\u003e to get a general understanding of \nReactive Programming.\n\u003c/p\u003e\n\n## Table of contents\n\n* [Getting Started](#Getting-Started)\n* [Clean Architecture](#Clean-Architecture)\n    * [Why is this important](#Why-is-this-important-)\n    * [The Approach](#The-Approach)\n    * [Benefits](#Benefits)\n    * [Dependencies](#Dependencies)\n    * [Layers of Clean Architecture](#Layers-of-Clean-Architecture)\n    * [Project Structure](#Project-Structure)\n    * [The Data layer](#The-Data-layer)\n        * [Creating DataSource](#Creating-DataSource)\n    * [The Use Cases Layer](#The-Use-Cases-Layer)\n    * [Framework Layer](#Framework-Layer)\n    * [Presentation Layer](#Presentation-Layer)\n    * [Sources Implementation](#Sources-Implementation)\n    * [Dependency Injection](#Dependency-Injection)\n\n## Getting Started\n\nWhen it comes to Android development, there has always been an open debate, on which architectural pattern to use. Since my early days of \nAndroid development I got a feeling that thing weren't right the way they were setup, This is the case with more than 60% of developers, which \nin turn; caused a lot of developers to struggle with the architecture in general.\n\nHowever, for quite a long time, there have been talks about writing your applications in a clean way. \nFurthermore, one of the most influential persons in the global programmer community, \nRobert C. Martin( aka Uncle Bob) has written a book, specifically on this topic(I personally suggest you guys to read it).\n\nBecause the Clean architecture can be used in any application and platform, not just Android, \nit’s very informative to understand the idea behind it, and why it’s a good solution, \nfor most problems we find nowadays, as programmers. With that in mind, in this tutorial, \nyou’ll learn how to use the Clean architecture pattern to build a \u003ca href=\"https://jobs.github.com/api\"\u003e`GitHubJobs`\u003c/a\u003e app, a simple app that displays jobs that are available in github and display that on a list.\n\n## Clean Architecture\n\nClean architecture is a software design philosophy that separates the elements of a design into ring levels. \nAn important goal of clean architecture is to provide developers with a way to organize code in such a way that \nit encapsulates the business logic but keeps it separate from the delivery mechanism.\n\n### Why is this important ?\n\nWhen you take a real software development, Implementing an architecture have one common goal - to maintain the complexity \nof your codebase. This may not be a big issue if the codebase is small, but trust me, this will be a real lifesaver  \nfor larger ones.\n\n### The Approach\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/iamjosephmj/Rx-Clean/blob/master/repo-res/images/clean-graph.png\" /\u003e\n\u003c/p\u003e\n\nYou might have seen this graph before. The circles represent different levels of your app. There are \na couple of things that we should note:\n* The inner circle is the most abstract, and the outer circle is the most concrete. This is called the Abstraction Principle. \n  This Abstraction Principle specifies that the inner circles should contain business logic, and outer circles should contain implementation details.\n  (I know this is boring to read this stuff now... but trust me you will get more clarity moving forward).\n* The Other principle of Clean Architecture is the Dependency Rule. This rule specifies, each circle can \n  depend only on the nearest inward circle(This is the backbone of the architecture).\n\nThe outer circle represents the concrete mechanisms that are specific to the platform such as networking \nand database access. Moving inward, each circle is more abstract and higher-level. The center circle is the \nmost abstract and this is where we have our business logic, which doesn't rely on the platform or the framework\nyou’re using(in our case it is Android).\n\n### Benefits\n\n* Parts of the code get decoupled\n* Easier to reuse.\n* Easier to write unit-tests.\n* There’s a method to the madness. When someone else works on your code, \n  they can learn the app’s architecture and will understand it better.\n  \nBefore we dive in to the code, I would suggest you to read a bit about \n\u003ca href= \"https://en.wikipedia.org/wiki/SOLID\"\u003e`SOLID`\u003c/a\u003e principles.\n\n### Dependencies\n\n* \u003ca href=\"https://dagger.dev/\"\u003e`Dagger2`\u003c/a\u003e\n* \u003ca href=\"https://github.com/sockeqwe/AdapterDelegates\"\u003e`AdapterDelegates`\u003c/a\u003e\n* \u003ca href=\"https://github.com/ReactiveX/RxKotlin\"\u003e`RxKotlin`\u003c/a\u003e\n* \u003ca href=\"https://developer.android.com/topic/libraries/architecture/viewmodel\"\u003e`ViewModels`\u003c/a\u003e\n* \u003ca href=\"https://github.com/square/moshi\"\u003e`Moshi`\u003c/a\u003e\n* \u003ca href=\"https://github.com/airbnb/lottie-android\"\u003e`lottie-android`\u003c/a\u003e\n* \u003ca href=\"https://github.com/willowtreeapps/spruce-android\"\u003e`spruce-android`\u003c/a\u003e\n* \u003ca href=\"https://github.com/bumptech/glide\"\u003e`Glide`\u003c/a\u003e\n\n### Layers of Clean Architecture\n\nThere are different theories about layers of the clean architecture, the architecture is in such a way that it gives an abstract idea on which we \ncan adapt the number of layers to our needs. To keeps things much precise, we will use five layers:\n\n* Presentation: A layer that interacts with the UI.\n* Use cases: Sometimes called interactors. Defines actions the user can trigger.\n* Domain: Contains the business logic of the app.\n* Data: Abstract definition of all the data sources.\n* Framework: Implements interaction with the Android SDK and provides concrete implementations \n  for the data layer.\n  \n### Project Structure\n\nWe had pointed out the different layers of the clean, but it is important to know how to implement it. The project \nis divided into two modules:\n\n* The existing app module.\n* A new core module that will hold all the code that doesn't depend on Android SDK.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/iamjosephmj/Rx-Clean/blob/master/repo-res/images/moduleStructure.png\" /\u003e\n\u003c/p\u003e\n\nFollow these steps:\n\n* Create a module named \"core\".\n* Add core module to main app module as dependency.\n* create packages named\n  * data\n  * domain\n  * interactors\n  under the core module.\n    \nNow you are all set to go :)\n\u003cbr\u003e\nWe will start from inner-most layers to the most concrete ones\n\n### The Data layer\n\nThis layer provides abstract definitions for accessing data sources like a database or the internet. \nwe’ll use Repository pattern in this layer. The main purpose of the repository pattern is to abstract\naway the concrete implementation of data access. To achieve this, you’ll add one\ninterface and one class for each model:\n\n* `DataSource interface`: The interface that the Framework layer must implement.\n* `Repository class`: Provides methods for accessing the data that delegate to DataSource.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/iamjosephmj/Rx-Clean/blob/master/repo-res/images/dataLayer.png\" /\u003e\n\u003c/p\u003e\n\nUsing the repository pattern is a good example of the `Dependency Inversion` Principle because:\n\n* A Data layer which is of a higher, more abstract level.\n* Doesn't depend on a framework, lower-level layer.\n* The repository is an abstraction of Data Access and it does not depend on details.\n  It depends on abstraction.\n  \n\n#### Creating DataSource\n\n* you can see the abstract implementation of datasource in \u003ca href = \"https://github.com/iamjosephmj/Rx-Clean/blob/master/core/src/main/java/io/iamjosephmj/core/data/datasource/GitHubJobsDataSource.kt\"\u003e`GitHubJobsDataSource`\u003c/a\u003e.\nIn a broader sense, this is the interface that the Framework layer must implement.\n\n* you can see the abstract implementation of data repository in \u003ca href = \"https://github.com/iamjosephmj/Rx-Clean/blob/master/core/src/main/java/io/iamjosephmj/core/data/repo/GitHubJobsRepository.kt\"\u003e`GitHubJobsRepository`\u003c/a\u003e.. The main purpose of the repository pattern is to abstract away \n  the concrete implementation of data access. \n\n### The Use Cases Layer\n\nThis layer is responsible to collect user actions and in-turn pass it to the inner layers.\n\u003cbr\u003e\nOur application has two key functionalities:\n\n* Fetching the list from gitHub jobs url.\n* displaying it in a list view.\n\nFrom that, you can list the actions users should be able to perform:\n\n* Fetching jobs(based on \u003ca href =\"https://github.com/iamjosephmj/Rx-Clean/blob/master/core/src/main/java/io/iamjosephmj/core/data/models/SearchRequest.kt\"\u003e`domain and page number`\u003c/a\u003e) \n\nLet's start creating use-case class. We are going to create the classes under \u003ca href=\"https://github.com/iamjosephmj/Rx-Clean/tree/master/core/src/main/java/io/iamjosephmj/core/interactors\"\u003e`interactors`\u003c/a\u003e \n\nEach of the use cases class has only one function that invokes the use case. For convenience, \nyou’re overloading the invoke operator. This enables you to simplify the function call on SearchForJobs \ninstance to SearchForJobs() instead of searchForJobs.invoke().\n\n### Framework Layer\n\nBy this, we come to the end of the three inner layers of the core module. We can now take a look at \nFramework layer. The Framework layer holds implementations of interfaces defined in the Data layer.\nOur next job is to provide implementations of Data source interfaces from the Data layer.\n\n* \u003ca href=\"https://github.com/iamjosephmj/Rx-Clean/blob/master/presentation/src/main/java/io/iamjosephmj/presentation/framework/GitHubJobsDataSourceImpl.kt\"\u003e`GitHubJobsDataSourceImpl.kt`\u003c/a\u003e\n\nNow we are all set, let's connect all the dots and display the data.\n\n### Presentation Layer\n\nPresentation layer contains the UI related code. This layer is in the same circle as the framework \nlayer, so we can depend on its classes. \n\n### Architecture\n\nFor this projects, we ar going to use MVVM pattern as it is supported by \u003ca href = \"https://developer.android.com/topic/libraries/architecture\"\u003e`Android Jetpack`\u003c/a\u003e. \nI cannot specifically say that MVVM is the best suite for this project, as there are many other cool architectural \npatterns like MVP, MVI, VIPER, MvRx...etc.. and I don't really want to do a comparison of design patterns here... that's something for some other day. \nTo stay in the context of our project lets stick on to MVVM.\n\nThis is how we are going to implement MVVM:\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/iamjosephmj/Rx-Clean/blob/master/repo-res/images/mvvm.png\" /\u003e\n\u003c/p\u003e\n\nMVVM pattern consists of three components:\n\n* View: responsible for rendering the UI.\n* Model: Contains business logic and data.\n* ViewModel: Acts as a bridge between data and UI.\n\nWhile we are speaking in terms of Clean Architecture, instead of relying on Models, you’ll communicate \nwith Interactors from the Use Case layer.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/iamjosephmj/Rx-Clean/blob/master/repo-res/images/clean-mvvm.png\" /\u003e\n\u003c/p\u003e\n\nYep! This is the last piece of our puzzle :)\n\n### Sources Implementation\n\nBefore moving on to implementing the presentation layer, we will need to provide the Data sources \nto the data layer. You should usually do this using dependency injection. It is the process of \nseparating provider functions or factories for dependencies, and their usage. This makes your classes \ncleaner, as they don’t create dependencies in their constructors.\n\n### Dependency Injection\n\nI had implemented \u003ca href=\"https://dagger.dev/dev-guide/\"\u003e`dagger2`\u003c/a\u003e for dependency management. You can go through \nthese class to know how I categorized application and presentation layer dependencies\n\n* Application Level \u003ca href=\"https://github.com/iamjosephmj/Rx-Clean/blob/master/app/src/main/java/io/iamjosephmj/clean/di/component/ApplicationComponent.kt\"\u003e`ApplicationComponent`\u003c/a\u003e - \u003ca href=\"https://github.com/iamjosephmj/Rx-Clean/blob/master/app/src/main/java/io/iamjosephmj/clean/di/module/ApplicationModule.kt\"\u003e`Application Module`\u003c/a\u003e\n* Presentation Level \u003ca href=\"https://github.com/iamjosephmj/Rx-Clean/blob/master/app/src/main/java/io/iamjosephmj/clean/di/component/ActivityComponent.kt\"\u003e`ActivityComponent`\u003c/a\u003e - \u003ca href=\"https://github.com/iamjosephmj/Rx-Clean/blob/master/app/src/main/java/io/iamjosephmj/clean/di/module/ActivityModule.kt\"\u003e`Activity Module`\u003c/a\u003e\n* Presentation Level \u003ca href=\"https://github.com/iamjosephmj/Rx-Clean/blob/master/app/src/main/java/io/iamjosephmj/clean/di/component/ViewModelComponent.kt\"\u003e`ViewModelComponent`\u003c/a\u003e - \u003ca href=\"https://github.com/iamjosephmj/Rx-Clean/blob/master/app/src/main/java/io/iamjosephmj/clean/di/module/ViewModelModule.kt\"\u003e`ViewModel Module`\u003c/a\u003e\n\nnote: feel free to change it to your own implementations.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiamjosephmj%2FRx-Clean","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fiamjosephmj%2FRx-Clean","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiamjosephmj%2FRx-Clean/lists"}