Kotlin: Dos mundos en un solo lenguaje
\n\n¿Alguna vez te has preguntado por qué algunos desarrolladores escriben en Kotlin como si fuera un Java mejorado, mientras que otros convierten el código en una cascada de lambdas y cadenas de llamadas? La respuesta es simple: Kotlin es un lenguaje multiparadigma que se lleva igual de bien con la programación orientada a objetos (POO) y con la programación funcional (PF).
\n\nPero, ¿cómo puede un principiante no perderse en esta diversidad? ¿Y un desarrollador experimentado, no caer en el "código espagueti" debido a la mezcla de estilos? En este artículo analizaremos en qué se diferencian estos enfoques, dónde y cuál aplicar, y cómo Kotlin ayuda a combinar sus mejores aspectos. Prepárate: habrá mucho código y nada de aburrimiento.
\n\nSi estás aprendiendo Kotlin para desarrollo Android o backend, entender estos paradigmas es tu boleto al mundo del código limpio, legible y mantenible. ¡Allá vamos!
\n\nKotlin orientado a objetos: Clásico con un envoltorio moderno
\n\nEl enfoque orientado a objetos trata sobre entidades. Tienes clases, las clases tienen propiedades y métodos. Todo lo que hace el programa es la interacción de objetos. Kotlin toma lo mejor de Java, pero añade azúcar: data class, object, propiedades perezosas y mucho más.
Clases y herencia: ejemplo
\n\nImagina que estamos escribiendo un sistema para una tienda online. El enfoque POO se vería así:
\n\n// Clase base\nopen class Product(val name: String, val price: Double) {\n open fun getDescription(): String {\n return "$name cuesta $price руб."\n }\n}\n\n// Herencia\nclass DiscountedProduct(name: String, price: Double, val discount: Double) : Product(name, price) {\n override fun getDescription(): String {\n val finalPrice = price * (1 - discount / 100)\n return "$name con descuento del $discount% cuesta ${"%.2f".format(finalPrice)} руб."\n }\n}\n\nfun main() {\n val apple = Product("Manzana", 50.0)\n val saleApple = DiscountedProduct("Manzana", 50.0, 20.0)\n \n println(apple.getDescription()) // Manzana cuesta 50.0 руб.\n println(saleApple.getDescription()) // Manzana con descuento del 20% cuesta 40.00 руб.\n}\n\nAquí todo es lógico: hay jerarquía, polimorfismo, encapsulación. Pero también hay desventajas: el código se vuelve pesado si hay muchas clases. Y si solo necesitamos aplicar un descuento a cualquier producto, tendríamos que crear subclases.
\n\n¿Cuándo manda la POO?
\n- \n
- Modelos de negocio complejos — cuando las entidades tienen múltiples estados y comportamientos. \n
- Componentes de UI — Activity, Fragment, View — todo esto es POO clásica. \n
- Trabajo con bases de datos — ORM (por ejemplo, Room) usa reflexión y anotaciones vinculadas a clases. \n
Kotlin funcional: Concisión y seguridad
\n\nLa programación funcional trata sobre cálculos, no sobre estados. En lugar de mutar objetos, usamos datos inmutables y funciones puras. Kotlin no te obliga a escribir en estilo funcional, pero proporciona todas las herramientas para ello: lambdas, funciones de orden superior, construcciones similares a mónadas (por ejemplo, Result).
Funciones de orden superior: ejemplo
\n\nResolvamos la misma tarea de descuentos, pero de forma funcional:
\n\ndata class Product(val name: String, val price: Double)\n\nfun applyDiscount(discount: Double): (Product) -> Product = { product ->\n val finalPrice = product.price * (1 - discount / 100)\n product.copy(price = finalPrice)\n}\n\nfun main() {\n val apple = Product("Manzana", 50.0)\n val saleApple = applyDiscount(20.0)(apple)\n \n println("${apple.name} cuesta ${apple.price} руб.") // Manzana cuesta 50.0 руб.\n println("${saleApple.name} con descuento cuesta ${saleApple.price} руб.") // Manzana con descuento cuesta 40.0 руб.\n}\n\nObserva: no creamos una nueva clase. Simplemente pasamos datos a través de la función