When using interfaces and implementations in Kotli...
# codingconventions
t
When using interfaces and implementations in Kotlin what is considered best practice?
interface UserRepository
and
class UserRepositoryImpl: UserRepository
or
interface IUserRepository
and
class UserRepository: IUserRepository
Or are there any alternative practices?
๐Ÿ‘€ 1
s
Why do you need a separate interface and class in the first place? If there's a reason, the names can convey that reason. If there isn't, just don't make an interface in the first place. That's how I'd approach it, at least.
โž• 4
โž– 1
k
class UserRepositoryImpl: UserRepository
- the class name seems to imply there is only ever going to be one implementation. In that case, why have an interface at all? Just create a class.
class UserRepository: IUserRepository
- this smells of Hungarian Notation, which went out of fashion at the beginning of this century. I would make the names more meaningful:
Copy code
class PostgresUserRepository: UserRepository
class MockUserRepository: UserRepository
๐Ÿ‘† 7
โž• 12
๐Ÿ‘†๐Ÿพ 1
๐Ÿ‡ญ๐Ÿ‡บ 1
c
The way to look at it is, you will see your interfaces everywhere. So make their names clean. Whereas in most cases you will only instantiate an implementation in one place, probably your DI layer, so using
Impl
is fine. Or better yet, something descriptive as mentioned above
๐Ÿ‘ 2
๐Ÿ‘๐Ÿพ 1
s
@Sam can't mock final classes w/o powermock or a very recent version of mockito (and even then it's kind of a smell)
and yeah, don't do `INoun`โ€”you can argue back and forth about whether it's more readable/useful than the JVM-standard
AgentNoun
naming scheme for interfaces, but at the end of the day, the convention is already set, and it's much easier for everyone involved to just follow the convention instead of bikeshedding. You wouldn't use JVM-style naming while writing for the .NET CLR, after all. I would say avoid
Impl
as much as possible because it sets a bad precedent. Strive to describe exactly how you're implementing the given behavior, like how Klitos described
d
It is very useful for testing to separate interface/implementation in domains with lots of objects having disparate responsibility - unit testing them becomes much easier. If there isn't an obvious way to name the "real" implementation (as Klitos described), usually I go with
RealX
, e.g.
RealUserRepository
. Sometimes if there are more possibilities for the real implementation depending on context, but that one is the default, I've used
DefaultUserRepository
.
โž• 1