lawlorslaw
03/31/2023, 8:32 AMImpl Imp prefix or suffix for the concrete implementation and leave the Interface without any prefix or suffix ... mean while other devs use an I prefix or suffix to denote the Interface and they leave the concrete implementation without any prefix or suffix.
For example: interface UserRepository and class UserRepositoryImpl: UserRepository
vs
interface IUserRepository and class UserRepository: IUserRepostiory
which version is better or is there a better alternative?
My question also applies to LocalDataSource and RemoteDataSource interface vs concrete implementation naming.s3rius
03/31/2023, 8:51 AMI isn't conventionally used for interfaces in the Android world
(2) We don't usually prefix anything with its type anymore. (There was a time where people would use iNumOfItems or strUserName because IDEs weren't that great yet.)s3rius
03/31/2023, 8:57 AMLogger : ILogger seems sensible if you want everyone to use Logger, with an option to write their own if needed. xxImpl implies that its an internal implementation which shouldn't be handled directly).lawlorslaw
03/31/2023, 9:25 AMlawlorslaw
03/31/2023, 9:25 AMlawlorslaw
03/31/2023, 9:25 AMCLOVIS
03/31/2023, 9:44 AMImpl and make it private. Provide a factory named after the interface.
• If it is important for downstream users, give it a proper name!
Everything visible from outside your module should have a proper name.lawlorslaw
03/31/2023, 9:46 AMCLOVIS
03/31/2023, 9:47 AMlawlorslaw
03/31/2023, 9:47 AMlawlorslaw
03/31/2023, 9:48 AMCLOVIS
03/31/2023, 9:48 AMlawlorslaw
03/31/2023, 9:48 AMCLOVIS
03/31/2023, 9:49 AMlawlorslaw
03/31/2023, 9:49 AMCLOVIS
03/31/2023, 9:51 AMlawlorslaw
03/31/2023, 9:52 AMlawlorslaw
03/31/2023, 9:52 AMlawlorslaw
03/31/2023, 9:52 AMCLOVIS
03/31/2023, 9:53 AMlawlorslaw
03/31/2023, 9:54 AMlawlorslaw
03/31/2023, 9:54 AMCLOVIS
03/31/2023, 9:54 AM// domain/src/…
interface UserRepository {
suspend fun getAll(): List<User>
}
// mongodb/src/…
class MongoUserRepository {
override suspend fun getAll(): List<User> { … }
}lawlorslaw
03/31/2023, 9:55 AMlawlorslaw
03/31/2023, 9:55 AMlawlorslaw
03/31/2023, 9:56 AMCLOVIS
03/31/2023, 9:56 AMCLOVIS
03/31/2023, 9:56 AMlawlorslaw
03/31/2023, 9:57 AMlawlorslaw
03/31/2023, 9:57 AMlawlorslaw
03/31/2023, 9:58 AMCLOVIS
03/31/2023, 9:59 AMinterface UserRepository {
suspend fun getAll(): List<User>
}
private class UserRepositoryImpl(
private val source: DataSource,
) {
override fun getAll(): List<User> =
source.getAllUsers()
}
fun userRepositoryFor(source: DataSource) = UserRepositoryImpl(source)CLOVIS
03/31/2023, 10:00 AMCLOVIS
03/31/2023, 10:00 AMlawlorslaw
03/31/2023, 10:02 AMlawlorslaw
03/31/2023, 10:04 AMlawlorslaw
03/31/2023, 10:05 AMCLOVIS
03/31/2023, 10:08 AMUser for tests, you probably have just a data class User , right?
If the repository just delegates to the data source, and the data source is the thing that has the logic, then you never need to mock the repository, you can mock the data source instead.
I don't see the factory pattern in your code snippet above.It's the top-level
userRepositoryFor function. There is no need to create classes for factories in Kotlin.lawlorslaw
03/31/2023, 10:11 AMuseRepositoryFor need to define in the same Kotlin file as class UserRepositoryImpl?lawlorslaw
03/31/2023, 10:13 AMCLOVIS
03/31/2023, 10:13 AMlawlorslaw
03/31/2023, 10:15 AM