La base de código con la que trabajo a diario no tiene pruebas automáticas, nombres inconsistentes y toneladas de comentarios como "¿Por qué está aquí?", "No estoy seguro de si esto es necesario" o "Este método no se llama correctamente" y el código está lleno de "Changelogs" a pesar del hecho de que usamos control de fuente. Baste decir que nuestra base de código podría usar la refactorización.
Siempre tenemos tareas para corregir errores o agregar nuevas funciones, por lo que no se dedica tiempo a refactorizar el código para que sea mejor y más modular, y no parece ser una alta prioridad.
¿Cómo puedo demostrar el valor de refactorizar de modo que se agregue a nuestras listas de tareas? ¿Vale la pena simplemente refactorizar a medida que avanzo, pidiendo perdón en lugar de permiso?
fuente
Respuestas:
"Es mejor pedir perdón que permiso" es cierto.
¿Por qué preocuparse por eso? Solo refactoriza las partes más horribles.
Ya sabes cuáles son los errores más costosos , ¿verdad?
Si no lo hace, entonces el paso 1 es definir de manera positiva e inequívoca el código de problema más costoso, complejo, lleno de errores e infestado de errores.
Identifique el número de tickets de problemas, horas de depuración y otros costos muy específicos y muy medibles .
Luego arregle algo en esa lista de problemas de alto costo .
Cuando tiene que pedir perdón, puede señalar reducciones de costos.
En caso de que no lo sepa, la refactorización requiere pruebas
unitariaspara demostrar que los comportamientos de antes y después coinciden. Idealmente, esto debería ser una prueba codificada y automatizada, por ejemplo, una prueba unitaria.Esto significa elegir una cosa. Escribe una prueba unitaria. Arregla esa única cosa. Has realizado dos mejoras. (1) escribió una prueba y (2) arregló el código.
Iterar.
fuente
Siga la regla de boy scout: deje el campamento (código) un poco mejor de lo que lo encontró. Nunca escuché que alguien fuera escrito por hacer pequeñas mejoras de código "mientras estaban allí".
fuente
Tomaré un punto de vista quizás demasiado cínico.
Refactorizar es una píldora tan difícil de tragar. Obtienes la responsabilidad y la culpa, y los frutos de tu trabajo a menudo van a otra persona que se basa en tu código limpio.
Diría que si tales prácticas de ingeniería se han convertido en la cultura de su empresa, es posible que deba luchar a un nivel superior. Realmente no estás luchando por la refactorización, estás luchando por la excelencia en ingeniería, y ese es el tipo de cambio que solo se da en la administración cuando los golpea en la cara. En ese escenario, probablemente buscarán un zar de mejores prácticas y todas sus grandes ideas quedarán incluidas de todos modos.
Considere unirse a una compañía diferente donde toman las prácticas de ingeniería más en serio.
fuente
Noté que muchos de los carteles aquí parecen estar convencidos de que el problema está en la administración, mientras que la pregunta no menciona eso.
Iría más allá que eso: en mi opinión, una base de código pésima casi nunca es directamente culpa de la administración. La gerencia no escribió ese código, lo hicieron los desarrolladores (hay algunas excepciones en mi compañía donde algunos de nuestros gerentes actuales escribieron la base del código inicial). Por lo tanto, el problema cultural reside en los desarrolladores: si quieren que la cultura cambie, ellos mismos tendrán que cambiar.
Trato de llevar esta realización y cambio de actitud a "mis" desarrolladores también. Cada vez que me preguntan "¿cuándo tendremos tiempo para refactorizar?", Actúo sorprendido y respondo "¡ya deberías estar refactorizando todo el tiempo!". La única forma en que creo que puede mantener una base de código saludable es triple:
Invariablemente, el siguiente comentario de los desarrolladores es "pero ¿cómo tenemos tiempo para hacer esto? ¿No tenemos tiempo ahora?". La única respuesta correcta (nuevamente en mi humilde opinión) es "no tienes tiempo para NO hacer esto". Si no mantiene la base de código en buen estado, encontrará que el tiempo de respuesta se alarga cada vez más, los horarios se vuelven más impredecibles, los errores se vuelven más desagradables y el valor se reduce.
El cambio de actitud más importante que necesita realizar en el equipo de desarrollo es que la "calidad" no es algo que hace en un momento específico ("cuando tenemos tiempo para refactorizar"), es algo que debe hacer todo el tiempo.
Finalmente, una historia de advertencia. Si lo presiono, negaré que esto haya sucedido. En una empresa para la que trabajé, había una aplicación de larga data con una gran base de código heredada que se originó hace más de 10 años. Muchos desarrolladores, incluido yo, creían que esta base de código heredada era mala o al menos desactualizada, no de última generación. Así que presionamos para un gran proyecto de refactorización con éxito, y comenzamos el proyecto de reescritura después de lo cual creíamos que todo sería mejor.
Trabajamos mucho y duro para implementar casi todo de una manera nueva y moderna, utilizando nuevas bibliotecas, nuevas características de lenguaje. Cerca del final, hicimos un gran esfuerzo para unir todo para permitir una nueva versión de la aplicación de larga data con la nueva y mejorada base de código.
Como se esperaba, la nueva versión tuvo algunos problemas iniciales, debido a las nuevas bibliotecas con las que aún no estábamos tan familiarizados, y algunas interacciones en nuestro código que no habíamos previsto. Sin embargo, finalmente logramos que el lanzamiento tenga el mismo estándar que nuestros lanzamientos anteriores y fuera de la puerta. Respiramos aliviados por nuestro "éxito". Luego, un subgrupo de desarrolladores volvió a la gerencia, pidiendo un nuevo proyecto de refactorización porque nuestro nuevo código no era exactamente la bala de plata que esperaban que fuera, y vieron algunas oportunidades para reescribir completamente algunas cosas ...
Moraleja de la historia: a menudo las cosas no están tan rotas como parecen, y 'comenzar de nuevo' generalmente significa que intercambiará un conjunto conocido de problemas con un conjunto de problemas desconocido al menos tan peludo. Refactorizar una parte a la vez!
fuente
Alguien me dijo una vez que cuando voy a una entrevista, no debo olvidar que también estoy entrevistando a la compañía. ¿Es un lugar donde quiero trabajar? ¿Hacen revisiones de código? ¿Tienen pruebas de integración automatizadas? Pruebas unitarias? ¿Qué piensan de la programación en pareja? Personalmente, encontraría otro trabajo y no me olvide de hacer algunas preguntas también esta vez.
fuente
Encuentra otra compañía, honestamente. Dichas mejoras en el proceso de desarrollo requieren grandes saltos culturales que tomarán un tiempo considerable antes de que todos lleguen a la misma página y para entonces ya no le importará tanto.
Si sientes que todavía tienes algo de lucha y aún no te has hundido, entonces da un empujón final. Trate de obtener el mayor apoyo de los miembros del equipo con ideas afines, revele su agotamiento a los superiores que se preocupan por su bienestar, evite directamente y aleje a cualquiera que se oponga a sus creencias e intente impulsar algunas horas obligatorias de refactorización para planificar nuevos proyectos / características.
Si le apasiona lo que hace y se preocupa por su empresa, sería un esfuerzo encomiable de su parte. Si no es apreciado, respétate y rescata antes de convertirte en un programador vacío.
fuente
Si tuviera que introducir una práctica para mejorar las cosas en este tipo de contexto, serían las revisiones de código. Las revisiones de código son
No tiene que hacer revisiones de código sistemáticamente, solo al confirmar porciones de código grandes / complejas al principio.
Por supuesto, si siente que necesita un respaldo oficial antes de presentar revisiones de código, es posible que primero deba convencer a su jefe de que es probable que la base del código se derrumbe si las cosas se dejan como están.
fuente
Esto es lo que hago en tales situaciones (en los 15 años de mi carrera como desarrollador me he encontrado con ese código casi todos los días)
La administración nunca reserva tiempo para volver a factorizar el código (¡nunca tienen suficientes recursos!), Por lo que hacerlo de manera lenta y constante es un enfoque correcto.
fuente
Haga que la gerencia investigue un poco sobre la "deuda técnica". También refiéralos a la "Teoría de la ventana rota", ambos efectos tienen un impacto directo en la eficiencia, la calidad y la moral.
"Un lugar de trabajo limpio es un lugar de trabajo seguro y productivo", y cada contribución a un desastre agrava el desastre de manera exponencial, no lineal.
Si no se trata la situación, eventualmente cruzará un punto de no retorno, donde se vuelve económicamente inviable, al tratarlo gradualmente antes de que eso suceda, los beneficios se recuperarán, dándole más combustible para enfrentar el problema a medida que avanza.
fuente
Parece que tus problemas son más generales.
El problema de refactorización es tanto un síntoma como un alivio potencial de parte del problema.
El líder de software y el equipo asignan el tiempo del equipo
Desde mi experiencia, creo que puede estar encontrando un problema que llamo "todos son administradores de software". Los gerentes de producto, gerentes de proyecto y, a veces, ingenieros y probadores de sistemas pueden ser conocidos por tratar de microgestionar a desarrolladores que probablemente ya tengan un administrador de software experimentado. Incluso puede tener algunos miembros en su equipo que creen que su rol es administrar.
Si usted es el administrador de software, haga asignaciones para la refactorización que desea, o mejor aún, haga que su equipo le proponga la refactorización para su aprobación. Para no microgestión, es posible que tenga pautas sobre la edad / autor / tamaño / contexto del código que se refactorizará que se puede refactorizar libremente frente a la necesidad de aprobación. Si un miembro de su equipo quiere refactorizar masivamente cuatro grandes clases de código antiguo complejo que no escribió y que no forman parte de su función, su desviación de dos semanas es su problema, por lo que necesita una oportunidad para decir que no.
Puede escabullirse, pero creo que es mejor construir sus estimaciones cuidadosamente con tiempo para el análisis, diseño, codificación, múltiples formas de prueba (al menos unidad e integración), refactorización y riesgo como se juzga históricamente y por la falta de experiencia o claridad asociada con la tarea. Si ha sido demasiado abierto sobre el funcionamiento de su equipo (o tiene miembros de su equipo que lo son), puede ser conveniente restringir los canales de comunicación para que lo atraviesen y discutan recursos y resultados, no métodos.
Las primeras elecciones de proyectos crean un círculo vicioso para la refactorización
El mantenimiento del software es difícil. Es doblemente difícil si otros miembros de la organización toman decisiones a su cargo. Esto está mal, pero no es nuevo. Ha sido abordado por Barry Boehm, uno de nuestros grandes escritores de software que presenta un modelo de gestión que describe como Theory W.
http://csse.usc.edu/csse/TECHRPTS/1989/usccse89-500/usccse89-500.pdf
A menudo, los desarrolladores de software se ven obligados a producir bajo el enfoque de gestión de Theory-X que dice que los trabajadores son básicamente perezosos y no funcionarán a menos que sean sometidos. Boehm resume y contrasta su modelo propuesto de la siguiente manera:
"En lugar de caracterizar a un gerente como un autócrata (Teoría X), un entrenador (Teoría Y) o un facilitador (Teoría Z), la Teoría W caracteriza el papel principal de un gerente como negociador entre sus diversos grupos y un paquete de soluciones de proyectos con condiciones ganadoras para todas las partes. Más allá de esto, el gerente también establece metas, monitorea el progreso hacia las metas y es un activista en la búsqueda de conflictos cotidianos del proyecto ganar-perder o perder-perder, enfrentándolos, y transformándolos en situaciones de ganar-ganar ".
Rápido y sucio a menudo es simplemente sucio
Boehm continúa señalando la razón por la cual las cosas son tan miserables para los desarrolladores del equipo de mantenimiento.
"La construcción de un producto rápido y descuidado puede ser una" ganancia "a corto plazo y de bajo costo para el desarrollador de software y el cliente, pero será una" pérdida "para el usuario y el mantenedor". Tenga en cuenta que en el modelo de Boehm, el cliente es más un administrador de contratos en lugar de un usuario final. En la mayoría de las empresas, piense en el gerente de producto como un sustituto del cliente, o tal vez como la persona que compra el producto para su lista de características.
Mi solución sería no liberar al equipo de desarrollo original (o al menos al líder original) hasta que el código se refactorice para al menos cumplir con los estándares de codificación.
Para el cliente, creo que es razonable contar con el gerente de producto como un sustituto del cliente, y el grupo de personas recompensado por entregar algo rápido y sucio ciertamente puede expandirse, por lo que existe una gran cantidad de personas para hacer las cosas de manera incorrecta.
La refactorización no es negociable
Por favor, no retroceda de su rol como administrador de software. Debe tener autoridad y discreción para usar el tiempo de su equipo en el proceso y las mejoras del producto. En ese rol, es posible que deba negociar sus elecciones para que su equipo sea más profesional. Sin embargo, con respecto al proceso, no negocies con el marketing, porque en mi experiencia, ese es un juego perdedor. Negociar con la gerencia de ingeniería. Muestra que tienes visión. La creación de un equipo de software profesional es una extensión de su rol, y es mucho más probable que sea visto como un beneficio mutuo.
fuente
Siempre puedes esperarlo. Eventualmente, el equipo perderá suficientes fechas límite y producirá software con errores suficientes, esa gerencia levantará sus manos y dirá que, por Dios, ¡ algo debería cambiar mejor!
Bien, esa es una propuesta arriesgada. Pero en realidad es lo que sucedió en nuestra tienda hace varios años (parte de la dificultad era comunicarse con la gerencia sobre los plazos, pero esa es otra historia), y es una de las razones por las que ahora tenemos decenas de miles de pruebas automatizadas, propiedad de código compartido, la libertad de refactorizar, la voluntad de eliminar el código muerto y los lanzamientos de la más alta calidad que hemos tenido.
Quizás lo más sorprendente es que nadie perdió su trabajo en el proceso, algo que atribuyo a que nuestro jefe viniera a pelear por nosotros, y a un consultor que defendió el caso de refactorización e integración continua en nuestro nombre. Siempre suena más convincente cuando alguien de afuera lo dice.
fuente
Creo que la respuesta a cómo encontrar el tiempo depende de por qué desea refactorizar el código.
Si funciona, no hay necesidad de refactorización especial y puede hacerlo cuando toque esa parte del código. Por lo tanto, no necesita tiempo especial para eso.
Si ralentiza el desarrollo de su equipo, necesita hablar con el líder del equipo sobre eso y crear una tarea especial para la refactorización y que tendrá tiempo.
Lo mismo para la velocidad de ejecución y otros casos, si el refactor puede mejorar algo y no solo el "buen aspecto del código" o su opinión sobre cómo debería ser el código, y proporcionar un beneficio real, crear una tarea o hablar con alguien que sea responsable de eso.
fuente
Me reí un poco por la forma en que describiste las cosas, ya que eso suena bastante similar al código base en el que trabajo, así que creo que nuestras situaciones son bastante similares. Afortunadamente, en mi situación, tengo un administrador con visión de futuro que ha decidido que la mejor manera de mejorar la base de código es a través de la modularización utilizando un marco de desarrollo web moderno en lugar de simplemente refactorizar toda la base de código. De esta forma, los puntos problemáticos de la aplicación principal pueden reescribirse como módulos separados y luego integrarse en la aplicación principal (pero aún así ser esencialmente independiente). Este puede ser un enfoque que desea plantear, ya que no requeriría refactorizar toda la base de código (¿presumiblemente grande?) Con la que está trabajando.
Por supuesto, puedo estar un poco alejado de lo que está diciendo, ya que tal vez su base de código no sea tan mala como con la que trabajo, en ese caso, diría ¿por qué no hacer pequeñas optimizaciones a medida que avanza? Los desarrolladores de mi equipo no tienen problemas para eliminar comentarios estúpidos u obsoletos y cosas de esa naturaleza, y no creo que sea algo que deba requerir aportes de la administración, ya que generalmente los desarrolladores tienen cierto poder para optimizar las cosas según sea necesario.
Si la base del código es realmente frágil, entonces debe tener cuidado y puede ser la razón por la que no desean realizar una refactorización importante, ya que esto podría terminar convirtiéndose en un proyecto de meses y probablemente requeriría la ramificación de un proyecto y poner desarrolladores en eso proyectar y eliminar otras tareas de desarrollo, como correcciones de errores inmediatas que pueden hacer que pierdan clientes, etc.
A fin de cuentas, en lo que respecta a otras personas que dicen que debe dejar de fumar, etc., creo que depende de cómo la gerencia vea las cosas, si comprenden la situación y se dan cuenta de por qué algunas cosas pueden tomar más tiempo de lo que deberían, entonces las cosas podrían estar bien. en cuanto al entorno de trabajo, pero si constantemente te están contactando sobre un trabajo atrasado, eso podría ser perjudicial con el tiempo. Soy afortunado de tener una administración que básicamente se da cuenta de que la aplicación es una mierda, pero tiene muchos clientes y genera dinero, por lo que sigue siendo valioso y vale la pena hacer correcciones de errores, incluso si es solo a corto plazo .
fuente
Su principal problema es que los códigos no obtienen suficiente visibilidad.
Sugiero usar una herramienta de integración continua como Jenkins , y una herramienta de análisis de código estático integrada que mida la complejidad ciclomática, los estándares de nombres, la longitud del código, etc.
Cuando un programador confirma un cambio, Jenkins ejecutará las pruebas de las unidades, ejecutará la herramienta de análisis de código estático y generará un informe web que todos pueden ver, con un estado de color similar al de un semáforo.
Cuando la calidad del código es visible para todos (especialmente el líder del equipo y el jefe) y el control de versiones y las pruebas de la unidad están ahí para respaldarlo ... la gente se siente alentada a refactorizar.
fuente
El código llegó de esta manera lentamente a través de muchos pequeños cambios. Tendrá que arreglarse de esa manera también.
En primer lugar, puede hacer esto a medida que avanza: aumente todas las estimaciones en un 10% para permitir la mejora del código y el mantenimiento a largo plazo. Si alguien se queja, pregúnteles si es mejor revisar el aceite en el motor de un automóvil cada semana o esperar hasta que el motor se bloquee por completo.
Tener una reunión y determinar estándares de codificación consistentes.
Introduzca reglas básicas para usar a medida que avanza:
Cada vez que se introduce un nuevo código en una clase, se deben escribir pruebas automatizadas para demostrar que la clase funciona (no solo el nuevo código).
Cada vez que se corrige un error, se deben escribir pruebas automatizadas para demostrar que la clase funciona (no solo el código fijo).
Cada vez que un programador modifica un archivo, tiene que corregir todas las advertencias del compilador en ese archivo y actualizar el código para que cumpla con los nuevos estándares de codificación.
Después de un tiempo, el código más utilizado estará actualizado y estará cubierto por pruebas automatizadas. El código anterior se actualizará cuando se cambie, si nunca se cambia, entonces nunca tendrá que preocuparse por ello.
Lo importante es incorporar estos hábitos a las tareas de codificación estándar de modo que ninguno de ellos pierda una gran cantidad de tiempo del trabajo "real", pero todos brindan beneficios reales. ¡No intente hacer un proyecto fuera de la refactorización del código antiguo, es un dolor horrible, aburrido y difícil que parecerá perder mucho tiempo sin conocimientos técnicos!
fuente
La forma de obtener los recursos (tiempo) que necesita es centrarse en alinear la capacidad y el deseo. Su jefe es impulsado por objetivos (generalmente ganancias o tiempos de entrega de nuevas funciones), y ve la refactorización como ingenieros que pierden el tiempo y se comen esos objetivos. Debes encontrar una manera de convencerlo de que los objetivos se cumplirán y se superarán si pasas tiempo refactorizando.
Entonces, el primer paso es descubrir qué dolor siente tu jefe. Identifica cuáles son sus mayores problemas. Luego averigüe cómo lo que quiere hacer se alinea con la solución de sus problemas y presente un sólido caso de negocios para hacerlo. Use sus sistemas de seguimiento de defectos y planificación de proyectos (exceso de tiempo) para proporcionar evidencia de dónde residen los problemas. Necesitas hechos, no sentimientos. Sin métricas (recuento de errores / módulo, costo para solucionarlos), la refactorización es solo un programador que juega a expensas de alguien. Su jefe solo le dará los recursos necesarios si puede mostrar un sólido argumento comercial para hacerlo.
El código basura es más a menudo costoso de arreglar. Sin pruebas de regresión automatizadas, el costo de probar el código refactorizado es extremadamente alto.
La mayoría de las veces que he visto códigos incorrectos con una necesidad real de refactorización, ha habido una gran cantidad de características indocumentadas y complejidad en los requisitos que no se pueden entender desde el principio. No es una tarea menor y mi experiencia es un orden de magnitud más difícil de estimar el costo de un trabajo de refactorización que agregar una nueva característica.
Me abstendría de seguir adelante y hacerlo detrás de tus jefes (si no estaba roto y lo rompiste, ¿cómo se ve?) - arregla el código que necesita cambiar de todos modos, pero si no está roto, no lo hagas No lo arregles.
fuente
Extrañamente, nadie menciona esto:
Para que las cosas sean una prioridad, facilítelas: obtenga una buena herramienta de refactorización.
Existen excelentes herramientas de refactorización (al menos para .NET afaik). Ah, y no te olvides de escribir pruebas unitarias de antemano (como otros ya han señalado).
¡Buena suerte!
fuente