¿Cómo aprendo el enfoque correcto para implementar la mitad de una característica? [cerrado]

12

Dirijo un equipo de desarrollo y quiero lanzar nuestro producto con la mayor frecuencia posible (Entrega continua).

En muchos casos, tenemos que implementar una característica que lleva más tiempo implementar que el tiempo entre lanzamientos. Todavía quiero que la gente confirme su código diariamente (Integración continua).

Muchas veces, implementar una nueva característica requiere que se cambie la característica existente y, por supuesto, las características existentes aún deben funcionar, incluso si la nueva característica aún no está terminada.

Si el desarrollador utiliza el enfoque correcto , puede ajustar las características existentes con cuidado y todo lo anterior no es un problema.

Sin embargo, ¿cuál es el enfoque correcto en realidad? Mi propia mente en sintonía con la programación me dice qué hacer para cada caso individual, pero necesito aprender más y necesito material de lectura que pueda leer y recomendar a los miembros del equipo que lo lean. O cualquier otro método para aprender la forma correcta de aprender este enfoque servirá.

Entonces esa es la pregunta. ¿Cómo me aseguro de que los miembros del equipo aprendan el enfoque correcto para implementar la mitad de una característica?

He buscado personas que afirman tener estrategias con respecto a esto, pero aún no las he encontrado, excepto personas que escriben algunos pensamientos al azar sobre el tema. Quizás no estoy usando las palabras de búsqueda correctas o quizás nadie ha hecho ninguna pauta autorizada sobre esto.

Niels Brinch
fuente
"las características existentes, por supuesto, aún deben funcionar" - dependiendo del contexto, el término para un requisito como este podría ser compatibilidad con versiones anteriores o ausencia de errores
mosquito
1
Los diferentes tipos de pruebas automatizadas pueden reducir el riesgo de errores en los cambios de código. Cheque. Estoy buscando el enfoque para usar como desarrollador que tiene que implementar una característica grande que puede implicar cambios del 75% en el código existente y 26% de código nuevo (el porcentaje adicional está ahí para misterio adicional).
Niels Brinch
1
@Niels: Debe tener algunos desarrolladores increíbles para que puedan tener un código de trabajo al final de cada día que pueda registrarse en la rama principal y pasar todas las pruebas. O eso, o solo obtienen un mínimo de huesos, por lo que están en condiciones de verificar su código al final del día.
Dunk
¿No lo llamarían una "Rama de funciones"? Realiza los cambios en la rama y luego vuelve a fusionar la rama con la maestra cuando finaliza la función. No deberías presentar características implementadas a medias en demos, así que no veo por qué esto no funcionaría.
deltree

Respuestas:

14

Tengo una opinión diferente de las otras respuestas aquí ya. Estoy de acuerdo con usted en que desea integrar los cambios de los desarrolladores lo antes posible y seguir probando la combinación combinada de código.

Sin embargo, no estoy de acuerdo con que su código de envío se haya desarrollado esta mañana, solo porque estamos lanzando esta tarde. Esa es una receta para clientes decepcionados.

La solución es tener ramas en su árbol de control de versiones, y que tenga un proceso separado para promover los deltas verificados desde la rama de desarrollo hasta la rama de lanzamiento.

De esa manera, obtienes lo mejor de ambos mundos. Tiene desarrolladores que realizan una integración continua y las ventajas que ofrece, tiene un envío de código estable regularmente al cliente, y tiene un nuevo proceso que prueba las características completadas en la rama del desarrollador y, si pasan las pruebas, las hacen parte del producto lanzado .

Hay dos herramientas que conozco que admiten bien este tipo de procesos. Si su estructura de desarrollo es simple, entonces git, con git-flow implementa una buena estructura de ramificación que funciona bien en equipos pequeños y medianos (quizás 20 desarrolladores).

Para equipos de desarrollo más grandes, o donde se necesita una estrategia de ramificación más compleja para admitir múltiples 'giros' de su producto, accurrev es lo mejor que existe. Los desarrolladores que no participan en la gestión de los cambios se quejarán de que es más difícil que la sub versión, etc., pero admite entornos de desarrollo complejos.

Michael Shaw
fuente
Me interesaría saber más sobre la estrategia de ramificación a la que se refiere. ¿Tiene un enlace a un artículo u otra cosa que explique más a fondo el concepto al que se refiere?
Niels Brinch
2
aquí está nvie.com/posts/a-successful-git-branching-model para git flow
Michael Shaw
La característica clave del flujo de git es su estrategia de ramificación claramente definida, lo que lo convierte en una buena opción para un producto que solo tiene una versión para producir. Accurrev no aplica una estrategia de ramificación, pero tiene la flexibilidad y proporciona las herramientas para administrar eficazmente un árbol de ramas mucho más complejo.
Michael Shaw
6

Aquí hay dos problemas: uno está implementando la mitad de una característica; el otro es mantener el producto de envío funcionando durante el desarrollo continuo.

Implementando la mitad de una característica

Un diseño general fuerte ayudará con esto. Esto le permite implementar la función con sus límites claramente definidos, por ejemplo, API a bits de código adyacentes, expectativas sobre estructuras de datos y una comprensión de cómo y cuándo se llamará al código implementado.

Las pruebas pueden incluir versiones simuladas del código para las otras partes de la función; Esto ayuda a suavizar la transición cuando se implementa la segunda mitad.

Mantener el producto de envío funcionando

Hay un puñado de opciones aquí:

  1. Desactive la función en el producto enviado. El hecho de que el código esté en el producto no significa que deba ejecutarse o presentarse a los usuarios. La desventaja es que no entregará un valor incremental a sus usuarios, y no recibirá comentarios.
  2. Revele los bordes de la función a sus usuarios. Muestre lo que tiene y proporcione alguna indicación de lo que vendrá.
  3. Permita que los usuarios cambien entre funcionalidad nueva y antigua. Esto a veces requiere mantener dos rutas de código preparadas por el usuario final.

Finalmente, si tiene problemas con alguna de estas soluciones, considere si ha dividido la función en los límites correctos. Si cortara las cosas de una manera diferente, ¿sería más fácil separarlas?

Alex Feinman
fuente
Es bastante fácil desactivar una nueva función que no está completamente lista. Ese es un buen consejo. Entonces, el problema central en el producto enviado es que las características EXISTENTES pueden romperse si las personas no usan el enfoque correcto cuando alteran el código existente.
Niels Brinch
2
Ahí es donde entra una buena prueba. Si no tiene una cobertura decente para su base de código, ¿tal vez esto podría ser un disparador para ese esfuerzo?
Alex Feinman
¿Pero la respuesta a mi pregunta puede ser simplemente "realizar una buena práctica de código y hacer pruebas unitarias", etc.?
Niels Brinch
1

¿Cómo me aseguro de que los miembros del equipo aprendan el enfoque correcto para implementar la mitad de una característica?

Al enseñarles. (duh)

El aprendizaje implicará la iteración: probar algo, ver cómo funciona y luego modificar su enfoque para lograr mejores resultados. Para este tipo de cosas, recomendaría revisiones de diseño / código. Puede ver cómo se diseña / implementa la media característica y tiene la oportunidad de dar su opinión. "Esto y aquello no funcionará porque romperán nuestro CI; ¿qué tal XYZ?", "Buen trabajo aquí, eso está realmente limpio".

Hacer las revisiones en equipo ayudará a todos a aprender lo que ya sabes intuitivamente.

Telastyn
fuente
Estoy totalmente de acuerdo con esto. Pero al igual que puedo enseñarle a alguien cómo hacer pruebas unitarias O referirlas al libro "El arte de las pruebas unitarias". ¿Hay algún recurso similar al que pueda referirme para este tema?
Niels Brinch
1

Lo más importante que lo ayudará aquí es tener una buena separación de preocupaciones para que, en la medida de lo posible, un área de código no interfiera con otra.

Este es un lugar donde el uso de la inyección de dependencia y la programación en la interfaz realmente ayuda, para que pueda tener su implementación actual de ISupportingFeature en el sitio y luego, cuando necesite crear INewFeature que depende de una implementación diferente, simplemente puede desarrollar con nueva implementación y mantener la existente en producción hasta que esté bien probada y lista para entrar en funcionamiento. Asumiendo que su DI funciona en algún tipo de sistema de configuración, esto le permitirá tener el mismo código en paralelo en su sistema y usar un código estable en todo momento.

De hecho, Martin Fowler describe este enfoque de configuración como una función de alternancia.

Por supuesto, el problema solo surge si está implementando todo el código todo el tiempo. Este es precisamente el tipo de escenario para el que se diseñaron las ramas de características y, aunque reconozco que el Sr. Fowler las frunce el ceño, no sé si son tan malas, especialmente si se crean y usan de manera planificada y pensada. a través del camino.

glenatron
fuente
Tengo la impresión de que comprometer todo el código en la misma sucursal e implementar todo mi código todo el tiempo es parte de una buena estrategia de integración continua.
Niels Brinch
Leer más sobre la entrega continua, sin duda es parte de eso. Sin embargo, me estremezco al pensar en eso: ¿desea implementar código medio escrito incluso si se debe desactivar? Quizás funcione bien en un escenario donde la seguridad no es importante, pero parece un enfoque de alto riesgo para muchos espacios de aplicaciones. Sin embargo, esto probablemente me señala como un viejo fanático de la seguridad que abraza la seguridad.
glenatron
Parece que hay dos estrategias en competencia, donde una tiene una rama principal única y otra tiene una rama para cada tarea y muchas fusiones ... No estoy seguro de qué es lo mejor o lo correcto, o si responde al núcleo de mis preguntas.
Niels Brinch
Creo que depende mucho del tipo de cosas que esté haciendo: estaría más inclinado hacia las sucursales si tuviera prioridad en la seguridad y no quisiera arriesgarme a implementar un código no probado donde alguien pueda encontrarlo o podría ser accidentalmente habilitado Entonces, si estaba ejecutando un sitio bancario, no creo que el CD fuera lo adecuado, pero tal vez si estuviera ejecutando un sitio web de alta rotación para visitantes ocasionales u ocasionales, podría ser ideal.
glenatron