Kotlin
A concise multiplatform language developed by JetBrains
Aumentar la adopción de Kotlin en su empresa
Artículo de Urs Peter, ingeniero de software sénior y formador de Kotlin certificado por JetBrains. Para los lectores que busquen una forma más estructurada de desarrollar sus habilidades en Kotlin, Urs también dirige el Kotlin Upskill Program en Xebia Academy.
Este es el tercer artículo de La guía definitiva para adoptar Kotlin en un entorno dominado por Java, una serie que sigue cómo crece la adopción de Kotlin entre equipos reales, desde la curiosidad de un único desarrollador hasta la transformación de toda la empresa.
Todos los artículos de la serie:
- Introducción a Kotlin para desarrolladores Java
- Evaluación de Kotlin en proyectos reales
- Aumentar la adopción de Kotlin en su empresa
Corra la voz: convenza a sus colegas desarrolladores con argumentos y gánese su corazón
A estas alturas, ya tiene un equipo base convencido de las ventajas de Kotlin. Ahora llega la fase crítica: ¿cómo expandir la adopción?
La clave en esta fase es conquistar la mente y el corazón de los desarrolladores de Java escépticos. Los factores tangibles e intangibles pueden marcar aquí la diferencia:
Factores tangibles: el código
- Deje hablar al código
Factores intangibles: apoye y conecte a los desarrolladores
- Facilite la incorporación
- Ofrezca material de autoaprendizaje
- Establezca una comunidad interna de Kotlin
- Sea paciente…
Deje hablar al código
Aproveche la experiencia adquirida al (re)escribir una aplicación en Kotlin y muestre las ventajas de forma clara y accesible:
- No lo diga, hágalo: demuestre cómo Kotlin es más conciso comparando fragmentos de Java con fragmentos de Kotlin.
- Tome perspectiva para centrarse en los paradigmas generales: Kotlin no solo es diferente de Java: Kotlin se fundamenta en la seguridad, la concisión para una legibilidad y mantenibilidad máximas, las funciones como ciudadano de primera y la posibilidad de extensión, que en conjunto resuelven deficiencias básicas de Java, sin dejar de ser totalmente interoperable con el ecosistema Java.
Estos son algunos ejemplos tangibles:
1. Verificación de valores nulos: no más errores multimillonarios
Java
//This is why we have the billion-dollar mistake (not only in Java…) Booking booking = null; //🤨 This is allowed but causes: booking.destination; //Runtime error 😱 Optional booking = null; //Optionals aren’t safe from null either: 🤨 booking.map(Destination::destination); //Runtime error 😱
Con el tiempo, Java ha añadido algunas funcionalidades de verificación de valores nulos, como Optional y Annotations (@NotNull, etc.), pero no ha conseguido resolver este problema fundamental. Además, el proyecto Valhalla (tipos Null-Restricted y Nullable) no introducirá la verificación de valores nulos en Java, sino que proporcionará más opciones entre las que elegir.
Kotlin
//Important to realize that null is very restricted in Kotlin: val booking:Booking? = null //…null can only be assigned to Nullable types ✅ val booking:Booking = null //null assigned to a Non-nullable types yields a Compilation error 😃 booking.destination //unsafely accessing a nullable type directly causes a Compilation error 😃 booking?.destination //only safe access is possible ✅
Lo bueno de la verificación de valores nulos de Kotlin es que no solo es segura, sino que también ofrece una gran usabilidad. Un ejemplo clásico de que «no se puede nadar y guardar la ropa»:
Imaginemos que tenemos este dominio:
Kotlin
data class Booking(val destination:Destination? = null) data class Destination(val hotel:Hotel? = null) data class Hotel(val name:String, val stars:Int? = null)
Java
public record Booking(Optional destination) {
public Booking() { this(Optional.empty()); }
public Booking(Destination destination) {
this(Optional.ofNullable(destination));
}
}
public record Destination(Optional hotel) {
public Destination() { this(Optional.empty()); }
public Destination(Hotel hotel) {
this(Optional.ofNullable(hotel));
}
}
public record Hotel(String name, Optional stars) {
public Hotel(String name) {
this(name, Optional.empty());
}
public Hotel(String name, Integer stars) {
this(name, Optional.ofNullable(stars));
}
}
Construcción de objetos
Java
//Because Optional is a wrapper, the number of nested objects grows, which doesn’t help readability
final Optional booking = Optional.of(new Booking(
Optional.of(new Destination(Optional.of(
new Hotel("Sunset Paradise", 5))))));
Kotlin
//Since nullability is part of the type system, no wrapper is needed: The required type or null can be used.
val booking:Booking? = Booking(Destination(Hotel("Sunset Paradise", 5)))
Recorrido por objetos anidados
Java
//traversing a graph of Optionals requires extensive unwrapping
final var stars = "*".repeat(booking
.flatMap(Booking::getDestination)
.flatMap(Destination::getHotel)
.map(Hotel::getStars).orElse(0)); //-> "*****"
Kotlin
//Easily traverse a graph of nullable types with: ‘?’, use ?: for the ‘else’ case. val stars = "*".repeat(booking?.destination?.hotel?.stars ?: 0) //-> "*****"
Desenvoltura de objeto anidado
Java
//extensive unwrapping is also needed for printing a leaf booking.getDestination() .flatMap(Destination::getHotel) .map(Hotel::getName) .map(String::toUpperCase) .ifPresent(System.out::println);
Kotlin
//In Kotlin we have two elegant options:
//1. we can again traverse the graph with ‘?’
booking?.destination?.hotel.?name?.uppercase()?.also(::println)
//2. We can make use of Kotlin’s smart-cast feature
if(booking?.destination?.hotel != null) {
//The compiler has checked that all the elements in the object graph are not null, so we can access the elements as if they were non-nullable types
println(booking.destination.hotel.uppercase())
}
La falta de compatibilidad con la verificación de valores nulos en Java es un punto candente clave para los desarrolladores, lo que lleva a una programación defensiva, a diferentes construcciones de nulabilidad (o a ninguna en absoluto), incluso a un aumento de la verbosidad. Además, las NullPointerExceptions son responsables de aproximadamente un tercio de los fallos de las aplicaciones (The JetBrains Blog). La comprobación de nulos en tiempo de compilación de Kotlin evita por completo estos fallos en tiempo de ejecución. Por eso, todavía hoy, la verificación de valores nulos es el principal motor de la migración a Kotlin.
2. Las colecciones son sus aliadas, no sus enemigas
El creador de Spring, Rod Johnson, declaró en una entrevista reciente que no fueron los tipos anulables lo que le hizo probar Kotlin, sino la excesivamente complicada API Java Streams: Creador de Spring: sin ganas de escribir Java.
El siguiente ejemplo muestra las diversas razones por las que la API Java Streams es tan terriblemente complicada y cómo Kotlin resuelve todos los problemas:
Java
public record Product(String name, int... ratings){}
List products = List.of(
new Product("gadget", 9, 8, 7),
new Product("goody", 10, 9)
);
Map maxRatingsPerProduct =
//🤨 1. Stream introduces indirection
products.stream()
//🤨 1. Always to and from Stream conversion
.collect(
//🤨 2. Lacks extension methods, so wrappers are required
Collectors.groupingBy(
Product::name,
//🤨 2. Again…
Collectors.mapping( groupedProducts ->
//🤨 3. (too) low-level types, arrays, and primitives cause extra complexity
//🤨 4. No API on Array, always wrap in stream
Arrays.stream(groupedProducts.ratings())
.max()
//🤨 5. Extra verbosity due to Optional
.orElse(0.0),
//🤨 6. No named arguments: what does this do?
Collectors.reducing(0, Integer::max)
)
));
Kotlin
//😃 rich and uniform Collection API - even on Java collections - due to extension methods
val maxRatingsPerProduct = products.
.groupBy { it.name }
.mapValues { (_, groupedProducts) -> //😃 destructuring for semantic precision
//😃 built-in nullability support, and the same API for
//arrays like other Collections
groupedProducts.flatMap { it.ratings }
.maxOrNull() ?: 0
}
}
Gracias al marco uniforme de colecciones de Kotlin, la conversión entre distintos tipos de colecciones es muy sencilla:
Java
int[] numbers = {1, 3, 3, 5, 2};
Set unique = Arrays.stream(numbers).boxed().collect(Collectors.toSet());
Map evenOrOdd = unique.stream()
.collect(Collectors.toMap(
n -> n,
n -> n % 2 == 0));
Kotlin
val numbers = arrayOf(1, 3, 3, 5, 2)
val unique: Set = numbers.toSet() //😃 simply call to to do the conversion
val evenOrOdd: Map = unique.associateWith { it % 2 == 0 }
Efecto final:
- API intuitiva y repleta de funcionalidades para colecciones: los procesos se leen de izquierda a derecha, no dentro de llamadas al recopilador anidadas.
- Menos código reutilizable y complejidad: sin Collectors.groupingBy, sin Stream, sin Optional, sin Arrays.stream.
- Un modelo mental: tanto si empieza con
List,Set,Arrayo una matriz primitiva, recurre a los mismos operadores de colección. - Rendimiento sin obstáculos: el compilador inserta boxing/unboxing solo donde es inevitable; usted escribe código normal.
- Seguridad frente a valores nulos integrada: la API de colecciones es compatible totalmente con la nulabilidad con varios asistentes que suelen llevar el sufijo
orNull(...). - Interoperabilidad fluida con Java con envolturas idiomáticas: gracias a los métodos de extensión, obtendrá «lo mejor de ambos mundos»: colecciones cargadas de funcionalidades además de las colecciones de Java.
En pocas palabras, Kotlin eleva las tareas cotidianas de recopilación —filtrado, asignación, agrupación, etc.— en funciones componibles de primera clase, de modo que usted expresa qué quiere, no todo el ritual de cómo llegar a ello.
3. No más excepciones comprobadas, pero el código en Kotlin es más seguro
Java es uno de los únicos lenguajes que todavía admite excepciones comprobadas. Aunque inicialmente se implantaron como elemento de seguridad, no han estado a la altura de lo prometido. Su verbosidad, los bloques de captura sin sentido que no hacen nada o que vuelven a lanzar una excepción como una RuntimeException, y su falta de alineación con las lambdas son algunas de las razones por las que resultan un estorbo en lugar de hacer que su código sea más seguro.
Kotlin sigue el paradigma demostrado utilizado por casi todos los demás lenguajes de programación (C#, Python, Scala, Rust y Go) de utilizar excepciones solo para situaciones irrecuperables.
Los siguientes ejemplos ponen de manifiesto los obstáculos que las excepciones comprobadas introducen en su código, sin añadir ninguna seguridad:
Java
public String downloadAndGetLargestFile(List urls) {
List contents = urls.stream().map(urlStr -> {
Optional optional;
try {
optional = Optional.of(new URI(urlStr).toURL());
//🤨 Within lambdas checked exceptions are not supported and must always be caught...
} catch (URISyntaxException | MalformedURLException e) {
optional = Optional.empty();
}
return optional;
}).filter(Optional::isPresent) //Quite a mouthful to get rid of the Optional...
.map(Optional::get)
.map(url -> {
try (InputStream is = url.openStream()) {
return new String(is.readAllBytes(), StandardCharsets.UTF_8);
} catch (IOException e) {
//🤨… or re-thrown, which is annoying, I don’t really care about IOE
throw new IllegalArgumentException(e);
}
}).toList();
//🤨 An empty List results in a NoSuchElementException, so why is it not checked? The chance that the List is empty is as high as the other two cases above...
return Collections.max(contents);
}
Kotlin
//😃 safe return type
fun downloadAndGetLargestFile(urls: List): String? =
urls.mapNotNull { //😃 convenient utility methods to rid of null
//😃 try catch is possible, yet runCatching is an elegant way to convert an exception to null
runCatching { URI(it).toURL() }.getOrNull()
}.maxOfOrNull{ //😃 safe way to retrieve the max value
it.openStream().use{ it.reader().readText() } //😃 convenient extension methods to make java.io streams fluent
}
4. Funciones como ciudadanos de primera clase
Kotlin trata las funciones como ciudadanos de primera clase, lo que puede plantearle dudas si viene de Java: ¿qué significa eso y por qué importa?
La diferencia clave radica en el enfoque limitado de Java: sus capacidades funcionales se centran sobre todo en el lado de la llamada mediante lambdas, mientras que el lado de la declaración sigue ligado a interfaces funcionales verbosas y menos intuitivas. En Kotlin, puede definir, pasar, devolver y componer funciones sin ningún código reutilizable, lo que hace que la programación funcional sea mucho más expresiva y natural.
Java
public void doWithImage(
URL url,
//🤨 Function interfaces introduce an indirection: because we don’t see the signature of a Function we don’t know what a BiConsumer does, unless we look it up
BiConsumer f) throws IOException {
f.accept(url.getFile(), ImageIO.read(url));
}
//🤨 Same here
public void debug(Supplier f) {
if(isDebugEnabled()) {
logger.debug("Debug: " + f.get());
}
}
//🤨 calling no-argument lambdas is verbose
debug(() -> "expensive concat".repeat(1000));
Kotlin
fun doWithImage(
url: URL,
//😃 Kotlin has a syntax for declaring functions: from the signature, we see what goes in and what goes out
f:(String, BufferedImage) -> Unit) =
f(url.file, ImageIO.read(url))
//😃 same here: nothing goes in, a String goes out
fun debug(msg: () -> String) {
if(isDebugEnabled) {
logger.debug(msg())
}
}
//😃 convenient syntax to pass a lambda: {}
debug{"expensive concat".repeat(1000)}
Kotlin proporciona una sintaxis clara y concisa para declarar funciones: solo con la firma, puede ver inmediatamente lo que entra y lo que sale, sin tener que navegar a una interfaz funcional externa.
Java «filtra» sus funcionalidades de programación funcional a través de un gran conjunto de interfaces java.util.function.* con firmas verbosas y complejas, lo que a menudo hace que la programación funcional resulte engorrosa de utilizar. Kotlin, por el contrario, trata a las funciones como ciudadanos de primera clase: estas interfaces permanecen ocultas para el desarrollador, pero siguen siendo totalmente interoperables con el enfoque de Java:

Como resultado, el uso de funciones en Kotlin es bastante más sencillo e intuitivo, lo que reduce considerablemente el umbral para aprovechar este potente concepto de programación en su propio código.
5. Simultaneidad sin complicaciones con corrutinas
Si necesita un alto rendimiento, un procesamiento paralelo dentro de una única solicitud, o streaming, la única opción que tiene en Java es una biblioteca reactiva, como Reactor y RxJava, disponibles en marcos de trabajo como Spring WebFlux, Vert.X, Quarkus, etc.
El problema con estas bibliotecas es que son notoriamente complicadas, lo que le obliga a entrar en la programación funcional. Como tales, tienen una curva de aprendizaje pronunciada, pero es muy fácil cometer errores que pueden tener consecuencias nefastas cuando la aplicación está sometida a carga. Esa es probablemente la razón por la que la programación reactiva nunca se convirtió en la corriente dominante.
Nota: VirtualThreads no sustituye a las bibliotecas reactivas, aunque exista cierto solapamiento. Los VirtualThreads ofrecen E/S sin bloqueo, pero no proporcionan funcionalidades como el procesamiento paralelo o los flujos reactivos. La concurrencia estructurada y los valores con ámbito también permitirán el procesamiento paralelo una vez que los principales marcos de trabajo lo admitan. Para los flujos reactivos, siempre tendrá que recurrir a una biblioteca reactiva.
Supongamos que usted es un desarrollador Java que utiliza Spring Boot y desea realizar una llamada paralela dentro de una única solicitud. Esto es lo que se obtiene al final:
@PostMapping("/users")
@ResponseBody
@Transactional
public Mono storeUser(@RequestBody User user) {
Mono avatarMono = avatarService.randomAvatar();
Mono validEmailMono = emailService.verifyEmail(user.getEmail());
//🤨 what does ‘zip’ do?
return Mono.zip(avatarMono, validEmailMono).flatMap(tuple ->
if(!tuple.getT2()) //what is getT2()? It’s the validEmail Boolean…
//🤨 why can I not just throw an exception?
Mono.error(new InvalidEmailException("Invalid Email"));
else personDao.save(UserBuilder.from(user)
.withAvatarUrl(tuple.getT1()));
);
}
Aunque, desde una perspectiva de tiempo de ejecución, este código funciona a la perfección, la complejidad accidental introducida es enorme:
- El código está dominado por
Mono/Fluxa lo largo de toda la cadena de llamadas, lo que le obliga a envolver todos los objetos de dominio. - Hay muchos operadores complejos por todas partes, como
zip,flatMap, etc. - No puede utilizar construcciones de programación estándar como lanzar excepciones.
- La intención empresarial de su código se resiente significativamente: el código se centra en
MonosyflatMap, oscureciendo así lo que realmente está sucediendo desde una perspectiva empresarial.
La buena noticia es que existe un potente remedio en forma de corrutinas de Kotlin. Las corrutinas pueden enmarcarse como una implementación reactiva a nivel del lenguaje. Como tales, combinan lo mejor de ambos mundos:
- Usted escribe código secuencial como lo hacía antes.
- El código se ejecuta de forma asíncrona/en paralelo en la ejecución.
El código Java anterior convertido a corrutinas tiene el siguiente aspecto:
@GetMapping("/users")
@ResponseBody
@Transactional
suspend fun storeUser(@RequestBody user:User):User = coroutineScope {
val avatarUrl = async { avatarService.randomAvatar() }
val validEmail = async { emailService.verifyEmail() }
if(!validEmail.await()) throw InvalidEmailException("Invalid email")
personRepo.save(user.copy(avatar = avatarUrl.await()))
}
La palabra clave suspender de Kotlin permite una ejecución estructurada y no bloqueante de forma clara y concisa. Junto con async{} y await(), facilita el procesamiento paralelo sin necesidad de callbacks profundamente anidados o construcciones complejas como Mono o CompletableFuture.
Por eso disminuirá la complejidad y aumentará la satisfacción de los desarrolladores y la facilidad de mantenimiento, manteniendo exactamente las mismas características de rendimiento.

Nota: No todos los principales marcos de trabajo web basados en Java admiten también corrutinas. Spring hace un trabajo excelente, al igual que Micronaut, pero Quarkus ofrece actualmente una compatibilidad limitada con corrutinas.
6. Pero bueno, ¡Java también evoluciona!
Java sigue avanzando con funcionalidades como los registros, la coincidencia de patrones y los próximos proyectos como Amber, Valhalla y Loom. Esta evolución constante refuerza la JVM y beneficia a todo el ecosistema.
Pero aquí está el truco: la mayoría de estas «nuevas» funcionalidades de Java son cosas que los desarrolladores de Kotlin han disfrutado durante años. La verificación de valores nulos, las clases de valores, las funciones de nivel superior, los argumentos de forma predeterminada, las colecciones concisas y las funciones de primera clase se han incorporado al diseño de Kotlin, de una forma más unificada y sencilla para el desarrollador. Por eso el código Kotlin suele parecer más limpio, más seguro y mucho más productivo.
Y aún hay más: Kotlin también se beneficia de la innovación de Java. Los avances a nivel de JVM como Virtual Threads y Loom en general, o las mejoras de rendimiento de Valhalla se aplican sin problemas también a Kotlin.
En resumen: Java evoluciona, pero Kotlin se diseñó desde el primer día para ofrecer a los desarrolladores las herramientas modernas que necesitan, lo que lo convierte en una opción segura, moderna y con visión de futuro para construir el futuro.

7. La ventaja evolutiva de Kotlin
Los lenguajes de programación más antiguos arrastran inevitablemente un bagaje heredado en comparación con las alternativas modernas. Actualizar un lenguaje al tiempo que se da soporte a bases de código enormes ya existentes presenta retos únicos para los diseñadores de lenguajes. Kotlin goza de dos ventajas cruciales:
Referencias sólidas: en lugar de reinventar la rueda, el equipo de diseño inicial de Kotlin reunió paradigmas demostrados de los principales lenguajes de programación y los unificó en un todo cohesionado. Este enfoque maximizó el aprendizaje evolutivo de la comunidad de programadores en general.
Aprender de las carencias de Java: los diseñadores de Kotlin pudieron observar los escollos de Java y desarrollar soluciones sólidas desde cero.
Para profundizar en la evolución de Kotlin, Andrey Breslav, del equipo de diseño original de Kotlin, dio una excelente charla en el KotlinDevDay de Ámsterdam: Shoulders of Giants: Languages Kotlin Learned From (Sobre los hombros de gigantes: lenguajes de los que aprendió Kotlin), de Andrey Breslav
Factores intangibles: apoyar y conectar a los desarrolladores en su recorrido hacia la adopción de Kotlin
1. Facilite la incorporación
El objetivo de los fragmentos de código expresivos Java vs. Kotlin es abrir el apetito por Kotlin. Sin embargo, el código por sí solo no basta para ganarse los corazones y las mentes de los desarrolladores Java. Para acelerar la adopción y garantizar un comienzo sin problemas, ofrezca:
- Un proyecto de ejemplo: un proyecto listo para ejecutarse con código Java y Kotlin en paralelo, que ofrece a los equipos una referencia práctica durante la migración.
- Comprobaciones de calidad integradas: preconfigurado con herramientas como SonarQube, ktlint y detekt para favorecer un código limpio, coherente y mantenible desde el primer día. Esto le permitirá aplicar reglas coherentes de lint, marcos de pruebas, bibliotecas y procesos de CI para reducir la fricción entre los equipos.
- Coaching y apoyo: ingenieros experimentados en Kotlin disponibles para formar a los nuevos equipos, responder preguntas y proporcionar asesoramiento práctico durante las primeras etapas de desarrollo.
- Esta es especialmente importante: con solo unas horas de orientación por parte de un desarrollador experimentado de otro equipo que haya pasado antes por estas etapas, se pueden evitar muchos errores y deudas técnicas.
Un poco de apoyo y orientación es la mejor forma de fomentar un entusiasmo duradero por Kotlin.
2. Ofrezca material de (auto)aprendizaje
Especialmente cuando se viene de Java, aprender los fundamentos de Kotlin puede hacerse por cuenta propia. Proporcionar algunos recursos por adelantado facilita el camino para mejorar la productividad con Kotlin y reduce el umbral de entrada.
- El «Tour of Kotlin» de JetBrains (guía de primeros pasos)
Un breve tutorial basado en navegador en el sitio oficial de Kotlin. - Kotlin Koans
Un conjunto de pequeños desafíos de codificación mantenido por JetBrains. - «Kotlin Bootcamp for Programmers» de Udacity
Un curso completo en vídeo creado en colaboración con Google.
Nota: Aunque el autoaprendizaje es valioso para comprender los conceptos básicos, también tiene algunos inconvenientes. Uno de ellos es la opcionalidad: cuando se está atrapado en la vorágine de tareas del día a día, es tentador saltarse el autoaprendizaje. Además, al aprendiz le faltará la retroalimentación de un profesional que conozca los matices sutiles del Kotlin idiomático correctamente aplicado. Es muy probable que después de un curso de autoaprendizaje, escriba Kotlin al estilo Java, lo que le proporciona algunas ventajas pero no desbloquea todo el potencial del lenguaje.
A menos que no tenga una buena mentoría, un curso clásico puede ser muy beneficioso. La asistencia es obligatoria; podrá intercambiar ideas con compañeros de su mismo nivel y obtener respuesta a sus preguntas por parte de un profesional experimentado, lo que le pondrá al día mucho más rápido con un Kotlin menos no-idiomático durante la transición inicial.
3. Establezca una comunidad interna de Kotlin
Una de las formas más rápidas de aumentar los conocimientos de Kotlin en su empresa es crear y, sobre todo, alimentar una comunidad interna.
- Lance una comunidad interna de Kotlin
- Primero busque un equipo base de al menos 3-6 desarrolladores que estén dispuestos a invertir en una comunidad Kotlin. Asegúrese también de que sus superiores les dan tiempo para su tarea y crédito por ella.
- Una vez formado el equipo, organice una reunión de lanzamiento en toda la empresa con ponentes conocidos de la comunidad Kotlin. Esto encenderá la llama de Kotlin y le dará impulso.
- Programe reuniones periódicas (mensuales o quincenales) para que el impulso nunca decaiga.
- Cree un canal de chat/wiki compartido dedicado a preguntas, fragmentos de código y notas de los eventos.
- Invite a ponentes (externos)
- Traiga a ingenieros que hayan puesto Kotlin en producción para que compartan sus anécdotas.
- Alterne entre charlas técnicas en profundidad (corrutinas, KMP, programación funcional) y estudios de casos de mayor nivel (estrategias de migración, consejos sobre herramientas).
- Presente las lecciones aprendidas de otros proyectos internos
- Pida a los jefes de proyecto que presenten lo aprendido sobre Kotlin: lo que funcionó, lo que no y los resultados cuantificables.
- Estos conocimientos pueden plasmarse en un «libro de reglas de Kotlin» que los nuevos equipos pueden consultar.
- Dé protagonismo a sus propios desarrolladores
- Organice sesiones de charlas relámpago en las que cualquiera pueda mostrar en 5-10 minutos un truco ingenioso, una biblioteca o un fracaso que haya superado.
- Felicite a los colaboradores públicamente: las menciones en los boletines internos o en los de todos los empleados fomentan el compromiso y el intercambio de conocimientos.
- Mantenga los bucles de retroalimentación cerrados
- Después de cada sesión, haga encuestas rápidas sobre su claridad y la utilidad, y luego modifique los programas futuros en consecuencia.
- Rote las tareas de organización para que la comunidad no dependa de un único campeón y se mantenga resistente a largo plazo.
Nota: Muchas de las sugerencias anteriores parecen sencillas. Sin embargo, no hay que subestimar el esfuerzo necesario para mantener viva y dinámica una comunidad.
4. Sea paciente…
El cambio cultural lleva su tiempo. El peligro de entusiasmarse con una herramienta que marca la diferencia es forzar las cosas, lo que puede ser contraproducente. Un enfoque eficaz consiste en respaldar el proceso de adopción con todas las actividades comentadas anteriormente, teniendo como guía prioritaria el principio de «muestre, no explique».
Próxima entrega de la serie
Pasamos de convencer a los desarrolladores a persuadir a los responsables de la toma de decisiones. En el próximo artículo mostramos cómo elaborar unos argumentos convincentes para la adopción de Kotlin en la empresa, basados en datos reales y resultados medibles. Aprenderá a traducir las victorias de los desarrolladores en argumentos de gestión, a vincular el aumento de la productividad con el ahorro de costes y a demostrar por qué Kotlin es más que una actualización técnica: es un movimiento estratégico tanto para los equipos como para las empresas.
Artículo original en inglés de:
