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