Saltar al contenido

Tech Blog | Engineering @ : Creando nuestro producto en colaboración

Hemos pensado y trabajado mucho en el desarrollo de las prácticas de ingeniería que usamos cada día. Estas prácticas se basan en principios que hemos llegado a valorar. Los principios en sí son más importantes que las prácticas, pero las prácticas son las que nos ayudan a lograr las cosas que valoramos. Con el fin de preservar y desarrollar nuestros principios y prácticas, hicimos que nuestros ingenieros nominaran a algunos de nuestros más respetados ingenieros para codificarlos; esto dio lugar a nuestro documento Ingeniería en el Mundo.

Si echas un vistazo a ese documento, notarás que en el lado izquierdo de cada página hay un principio que valoramos, y en el lado derecho hay una lista de elementos que Hacemos , Fomentamos , y Evitamos . La sección Hacer enumera los elementos que hemos acordado que todos los ingenieros harán en . La sección Fomentar enumera las prácticas que fomentamos como mejor práctica, pero reconocemos que podrían no ser apropiadas en todos los casos. Por lo tanto, aunque las valoramos y alentamos a los equipos a utilizarlas, un equipo puede elegir enfoques alternativos si aún cumplen el valor de la izquierda. Y, por último, la sección Evitar enumera las cosas que todos acordamos evitar en .

Tech Blog | Engineering @ : Creando nuestro producto en colaboración
Tech Blog | Engineering @ : Creando nuestro producto en colaboración

Aunque hay varios principios en este documento, este post se va a centrar en el segundo: Creamos nuestro producto en colaboración.

Lo que hacemos

Para apoyar la creación de nuestro producto en colaboración, aquí están las prácticas que pedimos a todos los ingenieros en adoptar:

Trabajamos en equipos multifuncionales. Para facilitar la colaboración, cada uno de nuestros más de 40 equipos son una mezcla multifuncional de individuos que incluyen: Un gerente de producto, un diseñador de producto, un ingeniero de desarrollo, y unos pocos ingenieros de software (generalmente 4-6). Estos equipos multifuncionales trabajan en experiencias de producto completamente verticales, lo que significa que son dueños de todo, desde el front-end hasta el back-end. Organizarse en estos equipos multifuncionales permite a un equipo tener un control completo sobre el producto que envían, desde la investigación y el diseño del cliente, hasta el desarrollo y la producción. Debido a que nuestros equipos multifuncionales también son responsables de la calidad, no tenemos un departamento de control de calidad separado. Todo esto facilita un flujo ininterrumpido de valor a nuestros clientes. Idealmente, nuestros equipos tienen todo lo que necesitan para entregar valor sin los gastos generales de tener que salir de su equipo.

Nos aseguramos de que al menos dos personas revisen todo el código antes de que se envíe. Nos sentimos cómodos trabajando en un código con el que estamos familiarizados; colaborar en el código que escribimos ayuda a difundir el conocimiento sobre nuestra base de código. La mayoría de nuestros equipos, ya sea en el programa de parejas o en el programa de la mafia, para lograr este objetivo, pero para respetar la autonomía de nuestros equipos les permitimos elegir cualquier enfoque que logre este objetivo. Además de difundir el conocimiento alrededor del equipo, tener varias personas colaborando en el código también aumenta la calidad de la arquitectura y del código. A menudo, tener una segunda (o tercera, o cuarta) persona mirando nuestro código nos ayuda a identificar los errores o puntos ciegos que es menos probable que notemos por nuestra cuenta.

Nos integramos temprano y a menudo dentro y a través de los equipos. No somos grandes fanáticos de las ramas de características de larga vida (u otras). Nuestra preferencia, como se discute en Ingeniería @ : Entrega continua de valor, es usar el desarrollo basado en troncos. Permitimos que los equipos elijan de forma autónoma cómo alcanzar este objetivo, incluyendo el uso de ramas de características de corta duración, pero si el desarrollo de una característica en una rama va a llevar más de un día o dos, queremos estar seguros de que estamos integrando este código en la rama troncal (es decir, maestra) con frecuencia. Esto presenta el desafío si la integración de código que está incompleto o no está aún listo para la producción. Para permitir que las características incompletas se integren con la rama maestra, puede que necesitemos envolver el código en una conmutación de características. Los conmutadores de características permiten integrar el código incompleto con otro código que se está desarrollando y enviarlo todo junto a la producción, incluso cuando las características están incompletas. Al integrar temprano y a menudo, somos capaces de detectar problemas de integración antes de ir demasiado lejos en una dirección con una característica. Esto lleva a una colaboración adicional dentro y a través de los equipos que ayuda a nuestra cultura de ingeniería y nos ayuda a entregar más holísticamente valor a nuestros clientes.

Facilitamos la integración documentando sobre la marcha. Aunque no somos una organización particularmente pesada en cuanto a la documentación, nos aseguramos de proporcionar documentación para los puntos de integración y los procesos complejos. Con tantos equipos en , a menudo necesitamos integrarnos con otros equipos – típicamente para enviar o recuperar datos de los sistemas de otro equipo. La mayor parte de esta comunicación se realiza de forma asincrónica a través de la mensajería pub/sub, pero también ocasionalmente a través de llamadas síncronas a la API. En cualquier caso, cuando creamos un nuevo punto de integración, nos aseguramos de documentarlo donde nuestro equipo y otros equipos puedan encontrarlo y comprender cómo integrarlo. A medida que trabajamos, también identificamos cualquier proceso y arquitectura complejos que no se descubren o entienden fácilmente con sólo mirar el código, y documentamos esos procesos y arquitecturas sobre la marcha. Evitamos crear la documentación por adelantado y preferimos crear toda esta documentación a medida que creamos el código – esto permite que nuestro código y arquitectura evolucionen a medida que aprendemos las lecciones mientras estamos codificando.

Tomamos decisiones guiadas por el marco de delegación de decisiones. Si bien es cierto que actualmente tomamos decisiones guiadas por el marco para la delegación de decisiones, es probable que pronto actualicemos esto para decir que tomamos decisiones guiadas por el marco RAPID a medida que avanzamos para ser más coherentes con el resto de nuestras organizaciones en . De cualquier manera, el punto es identificar quién tiene el derecho y la responsabilidad de los diferentes tipos de decisiones. Añadir claridad a quién proporciona aportaciones y recomendaciones y quién toma las decisiones finales ayuda a evitar la confusión y el caos en una organización. Además, creemos en el principio de subsidiariedad, que sugiere que las decisiones deben tratarse al nivel más inmediato (o local) que sea coherente con su resolución. O, en otras palabras, preferimos empujar las decisiones hacia abajo a los equipos e individuos cuando sea posible, en lugar de empujarlas hacia arriba a los gerentes y ejecutivos. Sin embargo, hay decisiones que deben ser delegadas a todos estos diferentes niveles, y nos gusta tener claro dónde deben tomarse esas decisiones.

Lo que alentamos

Para apoyar la creación de nuestro producto en colaboración, aquí están las prácticas que animamos a todos los ingenieros a adoptar. Son importantes para nosotros y creemos que aportarán un valor adicional, pero también respetamos la autonomía de nuestros equipos e ingenieros y por eso, aunque creemos que son valiosas, permitimos cierta flexibilidad aquí basada en el contexto en el que cada equipo está trabajando.

Alentamos la programación en parejas y en la mafia Creemos que la manera más efectiva de crear nuestro producto en colaboración es hacerlo a través de la programación en parejas o en la mafia. En la programación en parejas, tienes dos ingenieros trabajando juntos en todo el código de producción. En la programación mafiosa, todo el equipo de ingenieros codifica juntos. Esto resulta en un proceso de desarrollo de software altamente colaborativo. Juntos, los ingenieros toman decisiones a medida que codifican y pueden ayudar a crear la arquitectura juntos. Creemos que, en la mayoría de las situaciones, esto crea un sistema mejor diseñado y es más efectivo en la difusión del conocimiento que trabajar individualmente con solicitudes de extracción. Cuando se resuelven los problemas juntos, se entiende más profundamente el razonamiento detrás de por qué el código está en el estado en que está. Las revisiones de código proporcionan algo de esto, pero a menudo carecen de la profundidad que se obtiene cuando se trabaja en conjunto para enfrentar un problema y se hacen lluvias de ideas de soluciones. El emparejamiento y el mobbing proporcionan un bucle de retroalimentación más corto que las revisiones de código, ya que deciden juntos, en el momento, qué crear. Creemos que, en la mayoría de los escenarios, esto crea una mejor arquitectura y un código más limpio.

Lo que evitamos

Esto es esencialmente lo opuesto a la sección “Lo que hacemos”. Pedimos a todos los ingenieros que eviten estas prácticas. Creemos que estas distraen de nuestro objetivo de crear nuestro producto en colaboración.

No creamos silos de conocimiento. Evitamos activamente que alguien (o incluso un par) trabaje extensamente o por largos períodos (más de unos pocos días) en un área de nuestro producto. Los silos de conocimiento crean problemas cuando alguien más necesita trabajar en esa área y no entiende el código o la motivación detrás de las decisiones arquitectónicas y de codificación. Trabajar en un silo también puede conducir a grandes diseños que el equipo luego determina que son una solución inadecuada o deficiente. Acorralar y rotar a la gente en parejas ayuda a evitar estos silos.

No trabajamos de forma aislada. A veces es tentador ir por nuestra cuenta para resolver un problema complejo. A veces puede ser útil hacer esto para entender profundamente un problema, pero si lo hacemos, se ve como una investigación, y no creamos código de producción de esta manera. Ocasionalmente podemos hacer alguna investigación de forma aislada, pero el objetivo es llevar los aprendizajes al equipo y luego hacer que el equipo avance unido en una solución. Esto ayuda a evitar los mismos problemas discutidos anteriormente cuando se habla de los silos de conocimiento.

No pasamos el trabajo a otro grupo para que lo posea. Puedes ver esto de diferentes maneras en . Principalmente donde se puede ver el trabajo tradicionalmente entregado a otro departamento. En primer lugar, no tenemos un departamento de control de calidad; nuestros equipos multifuncionales son dueños de la calidad desde el diseño hasta la producción. Aseguramos esta calidad con un robusto conjunto de pruebas automatizadas y también verificamos la funcionalidad en nosotros mismos en nuestro entorno de puesta en escena. Una vez que verificamos que está listo para funcionar, lo enviamos. Hablando de enviarla, tampoco la entregamos. Nuestros equipos multifuncionales tienen una mentalidad de desarrollo y un ingeniero dedicado al desarrollo. Idealmente, los ingenieros de software del equipo pueden hacer el autoservicio de todos los dispositivos, pero también tenemos al ingeniero de dispositivos para ayudarnos en el camino. Una vez que hemos validado que los cambios están listos para la producción, nosotros (típicamente los ingenieros de software) sólo presionamos un botón y listo. Y eso ocurre muchas veces al día en todos nuestros equipos. El tiempo de inactividad cero, los despliegues diurnos son otra cosa que valoramos, pero eso es un tema para otro día. También tratamos de evitar la transmisión de código de un equipo a otro. Aunque no puedo decir que nunca lo hayamos hecho, es algo que intentamos evitar activamente. Nos sentimos cómodos con nuestro propio código, y trabajar en un código que no ayudamos a crear causa miedo. Cuando temes cambiar de código, el código eventualmente decae porque tenemos miedo de hacer el tipo de refactorización que es necesaria para mantener el código saludable. Y, por supuesto, hacer cambios en el código que no hemos creado consume mucho tiempo y está lleno de peligros porque carecemos de contexto en torno a las decisiones que se tomaron previamente y el impacto no intencionado que nuestros cambios pueden tener en esta misteriosa base de código.

Resumen

La creación de nuestro producto en colaboración es uno de los muchos principios que valoramos y hemos documentado en Ingeniería en . Estos principios rectores y las prácticas correspondientes nos han ayudado a escalar la ingeniería a la vez que comunicamos, mantenemos y evolucionamos nuestros valores y prácticas a medida que crecemos. Ha sido valioso para nosotros separar los valores y principios de las prácticas – esto nos permite adaptar nuestras prácticas para apoyar lo que realmente valoramos. Las prácticas son un medio para un fin. Los valores (o principios) definen los objetivos, y las prácticas son nuestra mejor comprensión actual de cómo lograr esos objetivos. ¿Ha pensado en las cosas que valora en su organización? Si usted fuera a crear algo como la ingeniería en, ¿cómo se vería para su organización?

Categorías: practicesTags: agile, lean, continuous integration, continuous deployment, values, cross-functional, pairing, mobbing