Is a new version of code for my (Social media app) with Clean Architecture

Overview

Social-media

Is a new version of code for my Social media app with Clean Architecture. I used most of Clean code tips with android, SOLID principles and design-patterns..

❤️ Clean Architecture ❤️

  • I have written about how to architect android application using the Uncle Bob's clean architecture approach. and what's this architecture and why we should use an architecture here.
  • And this an old project but i made it again with Uncle Bob's clean architecture approach Let's go and see what's the new here.

Clean Architecture maximizes the use of SOLID principles and we used all of them let's see 🏃 :

⭐ Single Responsibility

Each software component should have only one reason to change – one responsibility. So whatever class you have or whatever function you have these functions and classes should always only have one single responsibility and one reason to change.

for example getPosts function ! 🤩

// I have one responsibility and it's just get important data from database like user data or posts
class RepositoryImp @Inject constructor(
    private var database: Database
) : Repository {
    // I have one responsibility and it's just get post from database and return list of posts
    override suspend fun getPosts(): List<Post> = database.getAllPosts()
    
        // I have one responsibility and it's just get current user from database and return it as User Object
    override fun getUser(): User {
        TODO("Not yet implemented")
    }
}

⭐ Open-closed

  • You should be able to extend the behavior of a component, without breaking its usage, or modifying its extensions.
  • For example in this project we have a Database interface and DatabaseFromFirebase class which is extend or implement Database interface methods. Now if we want to modify something or add a function for example we can do in (Child) 👶 class.
  • Now you opened your Database interface to extention, anyone wants to add or modify something he will extend your Database interface and add what he want in his own child class 👶 (DatabaseFromFirebase class). and your class is closed to modification.
{ TODO("Not yet implemented") } }">
interface Database {
    suspend fun setUserDataInfoOnDatabase(user: User)
    suspend fun getCurrentUserData(id: String): User
    suspend fun getAllUsers(): List<User>
    suspend fun getAllPosts(): List<Post>
}

// this is your own implementation of the Database interface do whatever you want here
class DatabaseFromFirebase @Inject constructor(
    private var databaseRef: DatabaseReference,
    ) : Database {

    //extra functions ...
    
    override suspend fun getAllPosts(): List<Post> {
        return databaseRef.child(Constants.POSTS).get().await()
            .children.map {
                it.getValue(Post::class.java)!!
            }
    }
    override suspend fun setUserDataInfoOnDatabase(user: User) {
        databaseRef.child("users").child(user.id).setValue(user).await()
    }

    override suspend fun getCurrentUserData(id: String): User {
        TODO("Not yet implemented")
    }

    override suspend fun getAllUsers(): List<User> {
        TODO("Not yet implemented")
    }
}

⭐ Liskov Substitution

If you have a class of one type, and any subclasses of that class, you should be able to represent the base class usage with the subclass, without breaking the app.

  • We do that here when we inject RepositoryImp() from RepositoryImp (Child) 👶 Type whith provideMainRepository function which is return type of it Repository(Parent) 👨 .
    @Singleton
    @Provides
    fun provideMainRepository(
        database: Database 
    ): Repository = RepositoryImp(database) //function return type is Repository 'Parent' and this able to return RepositoryImp instead  
  • Now the parent class(Repository) 👨 is replaceable by their subclasses (RepositoryImp) 👶 👶 and that without altering the behavior so that again

⭐ Interface Segregation

  • It’s better to have many smaller interfaces than a large one, to prevent the class from implementing the methods that it actually doesn’t need.
  • Don't force him 💪 to implement it 😂
  • Note we can do that by making a default body for this method in Kotlin like this:
interface RepositoryAuth {
     fun notImportantForAll(){}
}

⭐ Dependency Inversion

Components should depend on abstractions rather than concrete implementations. Also higher level modules shouldn’t depend on lower level modules.

  • See This example :
{ TODO("Not yet implemented") } } class DatabaseFromCustomApi : Database { override suspend fun setUserDataInfoOnDatabase(user: User) { TODO("Not yet implemented") } override suspend fun getCurrentUserData(id: String): User { TODO("Not yet implemented") } override suspend fun getAllUsers(): List { TODO("Not yet implemented") } override suspend fun getAllPosts(): List { TODO("Not yet implemented") } } ">
/*
As a abstractions, if want to get the database from the Mars, I don't care just implement this interface 
and do what you want in your own class and suit concretion (firebase, api,etc..)
*/
interface Database {

    suspend fun setUserDataInfoOnDatabase(user: User)

    suspend fun getCurrentUserData(id: String): User
    suspend fun getAllUsers(): List<User>
    suspend fun getAllPosts(): List<Post>
}

// this is your own implementation of the Database interface do whatever you want here
class DatabaseFromFirebase @Inject constructor(
    private var databaseRef: DatabaseReference,
    ) : Database {

    override suspend fun getAllPosts(): List<Post> {
        return databaseRef.child(Constants.POSTS).get().await()
            .children.map {
                it.getValue(Post::class.java)!!
            }
    }
    override suspend fun setUserDataInfoOnDatabase(user: User) {
        databaseRef.child("users").child(user.id).setValue(user).await()
    }

    override suspend fun getCurrentUserData(id: String): User {
        TODO("Not yet implemented")
    }

    override suspend fun getAllUsers(): List<User> {
        TODO("Not yet implemented")
    }
}


class DatabaseFromCustomApi : Database {

    override suspend fun setUserDataInfoOnDatabase(user: User) {
        TODO("Not yet implemented")
    }
    override suspend fun getCurrentUserData(id: String): User {
        TODO("Not yet implemented")
    }
    override suspend fun getAllUsers(): List<User> {
        TODO("Not yet implemented")
    }

    override suspend fun getAllPosts(): List<Post> {
        TODO("Not yet implemented")
    }

}
  • Now We can depended on abstractions (Database interface) and not on concretions (like Firebase or Custom Api) by this way. The Datebase interface now is a replaceable with its childern classes and we will make our reposiory class take Database interface as argument like this: ❤️
= database.getAllPosts() }">
class RepositoryImp @Inject constructor(
    private var database: Database                      //abstractions (firebase or your custom api)
   // private var refDatabase: DatabaseReference       // concretions (just for firebase)
) : Repository {
    
    override fun getUser(): User {
        TODO("Not yet implemented")
    }
    
    override suspend fun getPosts(): List<Post> = database.getAllPosts()
    
}
  • ❤️ Now it's to easy if we want to convert from firebase to custom api and vice versa because our repository don't now what's firebase or what's api, Because it's take atractions not concretions .

Note

  • And i achieve every principle and so imprtant design patterns too in this open source project, Don't forget check the it ❤️
  • Don't forget support me by a star ⭐ for encourge me to write more articales ..
You might also like...
MVVM News Application with clean code architecture & android jetpack components.
MVVM News Application with clean code architecture & android jetpack components.

Android - Clean Architecture - Kotlin The purpose of this repo is to follow up Clean Architecture principles by bringing them to Android. The repo con

Taiwan Social Distancing App - Android

social-distancing-android 臺灣社交距離 App 由衛生福利部疾病管制署與台灣人工智慧實驗室共同研發,提供臺灣地區用戶接收 COVID-19 接觸通知,並提醒收到接觸通知的用戶連繫當地衛生局,以減少傳染風險。 ● 保障個人隱私 利用手機藍牙功能來估計社交互動,資料以匿名方式儲

✨ Social network app made with Android Compose, full Kotlin, Firebase Authentication, Storage and Firestore 🚀
✨ Social network app made with Android Compose, full Kotlin, Firebase Authentication, Storage and Firestore 🚀

Your friends, for real. Share daily random moments with your friends and discover who they really are. ✨ Instant Instant is a social media actually un

Simple app to Transfer Media and Text from computer to mobile.

TransferByte Simple app to Transfer Media and Text from computer to mobile.Written in kotlin. Recycler view used for listing the media posted and down

An Android app to stream and download your media stored in Google Drive in an Awesome way !!
An Android app to stream and download your media stored in Google Drive in an Awesome way !!

⚡ Thunder : An Android app to stream and download your media stored in Google Drive in an Awesome way !! (Just Movies for now) 🔘 Getting Started : Le

ArchGuard is a architecture governance tool which can analysis architecture in container, component, code level, create architecure fitness functions, and anaysis system dependencies..
ArchGuard is a architecture governance tool which can analysis architecture in container, component, code level, create architecure fitness functions, and anaysis system dependencies..

ArchGuard backend ArchGuard is a architecture governance tool which can analysis architecture in container, component, code level, database, create ar

A cryptocurrency data aggregator that tracks price, volume, social stats.
A cryptocurrency data aggregator that tracks price, volume, social stats.

CryptoMania A cryptocurrency data aggregator that tracks price, volume, social stats. Challenge description Design & implement an Android application

Modern Social Profile Layout For Android
Modern Social Profile Layout For Android

Social Profile Layout Modern Simple Social Profile Layout for your Android App Project Installation Just run this project on your Android Studio Proje

Covidapp - The COVID-19 crisis and social distancing had a significant impact on our lives
Covidapp - The COVID-19 crisis and social distancing had a significant impact on our lives

Covid App The COVID-19 crisis and social distancing had a significant impact on

Comments
  • Discussion about DI

    Discussion about DI

    image Above i think return type of first method should not be Task<Any> as i think Task is related to Firebase itself (if not so no problem with that).

    as we do abstraction layer so it is preferred to not use a source/lib specific return type so it can be used with any source/lib.

    opened by MahmoudMabrok 1
Owner
Kareem Aboelatta
android developer
Kareem Aboelatta
A fully functional social media app built with Kotlin (Android Studio) with multiple features

A social media app built with Kotlin (Android Studio) with multiple features ?? If you like this repo, give it a star ✨ and share ????‍?? it to your f

ThanhPhong 9 Dec 13, 2022
🐦 Loritta's Social media relayer via Discord Webhooks micro-service

?? SocialRelayer ?? SocialRelayer is a social media relayer to Discord via webhooks, pulling Loritta's guild configurations to automatically register

Loritta 6 Jun 2, 2022
A minimalist clone of the popular Social Media Platform "Instagram"

InstaLocal A minimalist clone of the popular Social Media Platform "Instagram" powered by Firebase and written in Kotlin. The app allows users to sign

Raktim Bhuyan 1 Nov 7, 2021
H4SGTAG MANAGER - CRUD that saves hashtags for social media

H4SGTAG_MANAGER CRUD that saves hashtags for social media made using android stu

Aldo Malacara 0 Jan 13, 2022
Media Provider Manager - An Xposed module intended to prevent media storage abuse

Media Provider Manager - An Xposed module intended to prevent media storage abuse

null 104 Dec 26, 2022
HyperUPnP is Android Application that lets you to Stream Media from PC, NAS or any other device running UPnP/DLNA compliant media server to your Android Device.

Hyper UPnP Android UPnP/DLNA client Stream Media from PC, NAS or any other device running UPnP/DLNA compliant media server to your Android Device. Int

Var Bhat 8 Jul 17, 2022
New version of my Android app that shows you popular movies using themoviedb.org API.

New version of my Android app that shows you popular movies using themoviedb.org API. Using Modern Android Develpment skills like Kotlin, Room, Retrofit, Hilt, coroutines, Flow and Jetpack Compose.

Gemma Lara Savill 0 Apr 21, 2022
This project is focused on the sample using the API's new preview version of Android-L, use of transitions, shadows etc...

Android L preview example Description This project is focused on the sample using the API's new preview version of Android-L, use of transitions, shad

Saul Molinero 165 Nov 10, 2022
NewsSpac-MVVM-CleanArch-TDD - The App uses MVVM architecture together with Clean architecture

Aplicativo NewsSpace Arquitetura O App utiliza a arquitetura MVVM em conjunto co

null 1 Feb 11, 2022
Weather application example with Android Architecture components and Clean Architecture

Weather application example with Android Architecture components and Clean Architecture Weather app that shows how to architect an android app in a cl

null 2 Dec 3, 2021