class Customer()
class Product()
interface CustomersFinder {
fun findCustomers(query: String): Set<Customer>
}
interface ProductFinder {
fun findProducts(query: String): Set<Product>
}
Now, suppose we want to have a MegaFinder class that is capable of querying both Customers and Products. The standard way to do this is- pass instances of the finders to the MegaFinder
- have the MegaFinder stash those instances in private properties, and
- call on them as needed
All that is in the realm of boilerplate stuff and Kotlin has a concise alternative. This is how it looks like:
class MegaFinder(customerFinder: CustomerFinder, productFinder: ProductFinder)
: CustomerFinder by customerFinder, ProductFinder by productFinder
{
fun loadAll() {
val customers = findCustomers("*:*")
val products = findProducts("*:*")
//...
}
}
What this says is that MegaFinder implements the finder interfaces by delegating to the designated instances. It is more terse then the traditional approach with two caveats that I see
- The delegating approach requires the MegaFinder to implement the finder interfaces. This is not necessarily bad, but the freedom not to do that is not available
- When reading the code it is not immediately obvious where the findCustomers(...) and findProducts(...) are implemented - it is almost is if you need some sort of IDE to figure this out :-)
No comments:
Post a Comment