Semantically speaking, classes and interfaces act as nouns and methods/functions act as verbs . This is something that I recently read in the Java to Kotlin and it is aligned with how the vast majority of the people naturally name methods and classes.
For example we would expect a Car
class to have a getBrand
method, not a GetBrand
class with an invoke
method returning the brand of the car.
However, while reading the recent Guide to app architecture from Google, I have came across their naming convention for use cases , where they suggest this naming:
verb in present tense + noun/what (optional) + UseCase
with the following syntax to use it in Kotlin (example from here ):
class FormatDateUseCase(userRepository: UserRepository) {
private val formatter = SimpleDateFormat(
userRepository.getPreferredDateFormat(),
userRepository.getPreferredLocale()
)
operator fun invoke(date: Date): String {
return formatter.format(date)
}
}
Looking at the code above, we just have a class acting as a function. Why does Google recommend using these classes instead os just using top-level functions? Am I missing something here?
Your statement is not completely correct: We don't "have a class acting as a function", but you can say that each instance of the class acts as a function. That is important, since for instance, the constructor of FormatDataUseCase
has a parameter of type UserRepository
.
So, if we wanted to convert the FormatDataUseCase
into a top-level function, it would not have the same signature as the invoke
function of FormatDataUseCase
, but it should also have userRepository
as an additional parameter:
fun formatDateUseCase(userRepository: UserRepository, date: Date): String {
val formatter = SimpleDateFormat(
userRepository.getPreferredDateFormat(),
userRepository.getPreferredLocale()
)
return formatter.format(date)
}
And that is probably the main advantage of the recommended approach: You can have often-needed parameters and values automatically injected when you inject the use case class. This hides the dependencies from the caller of the use case, and makes it more comfortable to use.
Also, in the example the SimpleDateFormat
is just initialized once and then reused for every call of the function, but if we converted it to a function, we would need to create a new instance on each call.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.