Digamos que hay dos posibles soluciones a un problema: la primera es rápida pero hacky; el segundo es preferible pero llevaría más tiempo implementarlo. Debe resolver el problema rápidamente, por lo que decide implementar el truco lo más rápido posible, planeando comenzar a trabajar en la mejor solución después. El problema es que, tan pronto como se soluciona el problema, se desploma en la lista de tareas pendientes. Todavía planea implementar la mejor solución en algún momento, pero es difícil justificar su implementación en este momento. De repente te das cuenta de que has pasado cinco años usando la solución menos que perfecta, maldiciéndola mientras tanto.
¿Te suena familiar? Sé que ha sucedido más de una vez donde trabajo. Un colega describe cómo hacer deliberadamente una GUI incorrecta para que no se adopte accidentalmente a largo plazo. ¿Tienes una mejor estrategia?
fuente
Respuestas:
Escribe un caso de prueba en el que falla el truco.
Si no puede escribir una prueba en la que el truco falla, entonces o no hay nada de malo con el truco después de todo, o su marco de prueba es inadecuado. Si es lo primero, huya rápido antes de perder su vida en optimización innecesaria. Si es lo último, busque otro enfoque (ya sea para marcar hacks o para probar ...)
fuente
Estrategia 1 (casi nunca seleccionada): no implemente el kluge. Ni siquiera dejes que la gente sepa que es una posibilidad. Hágalo de la manera correcta la primera vez. Como dije, este casi nunca se selecciona, debido a limitaciones de tiempo.
Estrategia 2 (deshonesta): mentir y engañar. Dígale a la gerencia que hay errores en el hackeo y que podrían causar problemas importantes más adelante. Desafortunadamente, la mayoría de las veces, los gerentes simplemente dicen que esperen hasta que los errores se conviertan en un problema y luego corrijan los errores.
Estrategia 2a: Igual que la estrategia 2, excepto que realmente hay errores. Sin embargo, es el mismo problema.
Estrategia 3 (y mi favorito personal): diseñe la solución siempre que pueda y hágalo lo suficientemente bien como para que un pasante o un codificador pueda hacerlo. Es más fácil justificar el gasto de la pequeña cantidad de dinero del código del mono que justificar su propio salario, por lo que podría simplemente hacerse.
Estrategia 4: Espere una reescritura. Seguir esperando. Tarde o temprano (probablemente más tarde), alguien tendrá que reescribir la cosa. Bien podría hacerlo en ese momento.
fuente
Aquí hay un gran artículo relacionado sobre la deuda técnica .
Básicamente, es una analogía de la deuda con todas las decisiones técnicas que toma. Hay deudas buenas y malas ... y tienes que elegir la deuda que va a lograr las metas que deseas con el menor costo a largo plazo.
El peor tipo de deuda son pequeños atajos acumulativos que son análogos a las deudas de tarjetas de crédito ... cada uno no duele, pero muy pronto te encuentras en la casa de los pobres.
fuente
Este es un problema importante al realizar trabajos basados en plazos. Encuentro que agregar comentarios muy detallados sobre por qué se eligió esta forma y algunas sugerencias sobre cómo debería ser codificado ayuda. De esta manera, las personas que miran el código lo ven y lo mantienen actualizado.
Otra opción que funcionará es agregar un bug.feature en su marco de seguimiento (tiene uno, ¿verdad?) Detallando la reelaboración. De esa manera es visible y puede forzar el problema en algún momento.
fuente
La única vez que puede justificar la reparación de estas cosas (porque no están realmente rotas, solo son feas) es cuando tiene otra característica o corrección de errores que toca la misma sección de código, y también puede volver a escribirla.
Tienes que hacer los cálculos sobre lo que cuesta el tiempo de un desarrollador. Si se cumplen los requisitos de software y lo único malo es que el código es vergonzoso bajo el capó, no vale la pena arreglarlo.
Empresas enteras pueden cerrar porque los ingenieros demasiado entusiastas insisten en una nueva arquitectura cada año cuando se ponen ansiosos.
Si está libre de errores y cumple con los requisitos, está hecho. Envíalo. Siga adelante.
[Editar]
Por supuesto, no estoy defendiendo que todo sea pirateado todo el tiempo. Tienes que diseñar y escribir código cuidadosamente en el curso normal del proceso de desarrollo. Pero cuando terminas con hacks que solo tenían que hacerse rápidamente, tienes que hacer un análisis de costo-beneficio sobre si vale la pena limpiar el código o no. Si durante la vida útil de la aplicación pasará más tiempo codificando un truco complicado del que tendría que arreglarlo, entonces, por supuesto, arréglelo. Pero si no es así, es demasiado caro y arriesgado volver a codificar una aplicación que funcione y que no tenga errores solo porque mirar la fuente te enferma.
fuente
USTED NO HACE SOLUCIONES PROVISIONALES.
A veces creo que los programadores solo necesitan que se les diga esto.
Lo siento, pero en serio: una solución pirata no tiene valor e incluso en la primera iteración puede llevar más tiempo que hacer una parte de la solución correctamente.
Por favor, deje de dejarme su código de mierda para mantener. Solo codifíquelo SIEMPRE CORRECTAMENTE. No importa cuánto tiempo tarde y quién te grite.
Cuando estés sentado jugando con los pulgares después de entregar temprano mientras todos los demás están depurando sus estúpidos trucos, me lo agradecerás.
Incluso si no cree que sea un gran programador, esfuércese siempre por hacer lo mejor que pueda, nunca tome atajos; no le cuesta NINGÚN tiempo hacerlo bien. Puedo justificar esta afirmación si no me cree.
fuente
Si lo está maldiciendo, ¿por qué está al final de la lista de TODO?
fuente
fuente
Es una decisión difícil. Yo he hecho trucos personalmente porque, a veces, TIENES que sacar ese producto por la puerta y llegar a las manos de los clientes. Sin embargo, la forma en que me ocupo de ello es simplemente haciéndolo.
Dígale al líder del proyecto, a su jefe o al cliente: hay algunos puntos que deben limpiarse y codificarse mejor. Necesito una semana para hacerlo, y va a costar menos hacerlo ahora, entonces será dentro de 6 meses, cuando necesitemos implementar una extensión en el subsistema.
fuente
Por lo general, problemas como este surgen de una mala comunicación con la gerencia o el cliente. Si la solución funciona para el cliente, entonces no ve ninguna razón para solicitar que se cambie. Por lo tanto, es necesario que se les informe sobre las compensaciones que realizó de antemano para que puedan planificar más tiempo para solucionar los problemas después de que haya implementado la solución rápida.
Cómo resolverlo depende un poco de por qué es una mala solución. Si su solución es mala porque es difícil de cambiar o mantener, entonces la primera vez que tiene que hacer mantenimiento y tener un poco más de tiempo, entonces es el momento adecuado para actualizar a una mejor solución. En este caso, ayuda si le dice al cliente oa su jefe que tomó un atajo en primer lugar. De esa forma, saben que no pueden esperar una solución rápida la próxima vez. Paralizar la interfaz de usuario puede ser una buena manera de asegurarse de que el cliente regrese para arreglar las cosas.
Si la solución es mala porque es arriesgada o inestable, entonces realmente necesita hablar con la persona que está planificando y tener algo de tiempo planeado para solucionar el problema lo antes posible.
fuente
Buena suerte. En mi experiencia, esto es casi imposible de lograr.
Una vez que baje la pendiente resbaladiza de implementar un truco porque está bajo presión, entonces es mejor que se acostumbre a vivir con él para siempre. Casi NUNCA hay tiempo suficiente para volver a trabajar algo que ya funciona, sin importar lo mal que esté implementado internamente. ¿Qué te hace pensar que mágicamente tendrás más tiempo "en una fecha posterior" para arreglar el truco?
La única excepción que se me ocurre a esta regla es si el hack le impide por completo implementar otra pieza de funcionalidad que necesita un cliente. Entonces no tiene más remedio que volver a trabajar.
fuente
Intento construir la solución hacky para que se pueda migrar a largo plazo de la manera más sencilla posible. Digamos que tiene un tipo que está construyendo una base de datos en SQL Server porque esa es su base de datos más sólida, pero su estándar corporativo es Oracle. Cree la base de datos con la menor cantidad posible de funciones intransferibles (como tipos de datos Bit). En este ejemplo, no es difícil evitar los tipos de bits, pero hace que la transición posterior sea un proceso más fácil.
fuente
Eduque a quien esté a cargo de tomar la decisión final por qué la forma hacker de hacer las cosas es mala a largo plazo.
Básicamente, las personas que no entienden el software no entienden el concepto de volver a visitar cosas que ya funcionan. De la forma en que lo ven, los desarrolladores son como mecánicos que quieren seguir desarmando y reensamblando todo el auto cada vez que alguien quiere agregar una característica, lo que les suena loco.
Ayuda a hacer analogías con las cosas cotidianas. Explíqueles cómo, cuando tomó la solución provisional, tomó decisiones que se adaptaban a su construcción rápidamente, en lugar de ser estable, mantenible, etc. Es como elegir construir con madera en lugar de acero porque la madera es más fácil de cortar y, por lo tanto, podría construir la solución provisional más rápido. Sin embargo, la madera simplemente no puede soportar los cimientos de un edificio de 20 pisos.
fuente
Usamos Java y Hudson para una integración continua. Las 'soluciones provisionales' deben comentarse con:
Cada vez que Hudson ejecuta una compilación, proporciona un informe de cada elemento de TODO para que tengamos un registro actualizado y altamente visible de cualquier elemento pendiente que necesite mejorar.
fuente
Gran pregunta. Esto también me molesta mucho, y la mayoría de las veces soy la única persona responsable de priorizar los problemas en mis propios proyectos (sí, pequeñas empresas).
Descubrí que el problema que debe solucionarse suele ser solo un subconjunto del problema. IOW, el cliente que necesita una solución urgente no necesita que se resuelva todo el problema, solo una parte, más pequeño o más grande. Eso a veces me permite crear una solución alternativa que no es una solución para el problema completo, sino solo para el subconjunto del cliente y que me permite dejar el problema más grande abierto en el rastreador de problemas.
Eso, por supuesto, puede no aplicarse en absoluto a su entorno de trabajo :(
fuente
Esto me recuerda la historia de "CTool". Al principio, CTool fue propuesto por uno de nuestros desarrolladores, lo llamaré Don, como una posible forma de resolver el problema que estábamos teniendo. Siendo un tipo serio y trabajador, Don se enchufó y entregó un prototipo funcional. Sabes a dónde voy con esto. De la noche a la mañana, CTool se convirtió en parte del flujo de trabajo de la empresa con todo un departamento dependiendo de él. Para el segundo o tercer día, empezaron a llegar amargas quejas sobre las deficiencias de CTool. Los usuarios cuestionaron la competencia, el compromiso y el coeficiente intelectual de Don. Las protestas de Don de que nunca se suponía que fuera una aplicación de producción cayeron en oídos sordos. Esto continuó durante años. Finalmente, alguien se dispuso a reescribir la aplicación, mucho después de que Don se fuera. En ese momento, el nombre CTool se había adherido tanto al odio que nombrarlo CTool versión 2 estaba fuera de discusión. Incluso hubo un funeral formal para CTool, algo que recuerda a la escena de ejecución de la fotocopiadora (¿o era una impresora?) En Office Space .
Algunos podrían decir que Don se merecía las hondas y las flechas por no hacer las cosas bien para arreglar CTool. Mi único punto es que decir que nunca debes hackear una solución probablemente sea injustificable en el mundo real. Pero si es usted quien debe hacerlo, pise con cautela.
fuente
Consígalo por escrito (un correo electrónico). Entonces, cuando se convierte en un problema posterior, la gerencia no "olvida" que se suponía que era temporal.
Hágalo visible para los usuarios. Cuanto más visible es, menos probable es que la gente se olvide de volver atrás y hacerlo de la manera correcta cuando la crisis haya terminado.
Negocie antes de que la solución temporal esté en su lugar para un proyecto, recursos y líneas de tiempo para obtener la solución real. El trabajo para la solución real probablemente debería comenzar tan pronto como finalice la solución temporal.
fuente
Presenta un segundo error muy descriptivo contra su propia "solución" y coloca un comentario de tareas pendientes en las áreas afectadas que dice: "Esta área necesita mucho trabajo. Vea el defecto # 555" (use el número correcto, por supuesto) . Las personas que dicen "no hagas un truco" no parecen entender la pregunta. Suponga que tiene un sistema que necesita estar en funcionamiento ahora, su solución sin pirateo es de 8 días de trabajo, su truco es de 38 minutos de trabajo, el truco está ahí para ganar tiempo para hacer el trabajo y no perder dinero mientras lo estás haciendo.
Ahora todavía tiene que conseguir que su cliente o la gerencia acuerden programar los N * 100 minutos de tiempo necesarios para hacer la solución real, además de los N minutos necesarios ahora para solucionarlo. Si debe negarse a implementar el truco hasta que obtenga tal acuerdo, entonces tal vez eso sea lo que tenga que hacer, pero he trabajado con algunas personas comprensivas en ese sentido.
fuente
El precio real de introducir una solución rápida es que cuando alguien más necesita introducir una segunda solución rápida, la presentará basándose en su propia solución rápida. Por lo tanto, cuanto más tiempo esté implementado una solución rápida, más arraigada se volverá. Muy a menudo, un truco toma solo un poco más de tiempo que hacer las cosas bien, hasta que te encuentras con un segundo truco que se basa en el primero.
Entonces, obviamente, a veces es (o parece ser) necesario introducir una solución rápida.
Una posible solución, asumiendo que su control de versiones lo admite, es introducir una bifurcación desde la fuente cada vez que realice un truco de este tipo. Si se anima a las personas a evitar codificar nuevas funciones dentro de estas bifurcaciones especiales de "hazlo listo", eventualmente será más trabajo integrar las nuevas funciones con la bifurcación que deshacerse del truco. Sin embargo, es más probable que se descarte la bifurcación "buena". Y si está lo suficientemente lejos del lanzamiento como para que hacer una bifurcación de este tipo no sea práctico (porque no vale la pena hacer la integración dual mencionada anteriormente), entonces probablemente ni siquiera debería usar un truco de todos modos.
Un enfoque muy idealista.
Una solución más realista es mantener su programa segmentado en tantos componentes ortogonales como sea posible y ocasionalmente hacer una reescritura completa de algunos de los componentes.
Una mejor pregunta es por qué la solución hacky es mala. Si es malo porque reduce la flexibilidad, ignórelo hasta que necesite flexibilidad. Si es malo porque afecta el comportamiento del programa, ignórelo y eventualmente se convertirá en una corrección de errores y se abordará. Si es malo porque se ve feo, ignórelo, siempre que el truco esté localizado.
fuente
Algunas soluciones que he visto en el pasado:
HACK
en el código (o esquema similar comoXXX
)HACK
aparecen comentariosEsta es una excelente pregunta. Una cosa que he notado a medida que adquiero más experiencia: los trucos te permiten ahorrar un tiempo muy corto y, a menudo, te cuestan mucho más. Estrechamente relacionada está la 'solución rápida' que resuelve lo que crees que es el problema, solo para descubrir cuando explota que no era el problema en absoluto.
fuente
Dejando de lado el debate sobre si debería hacerlo, supongamos que tiene que hacerlo. El truco ahora es hacerlo de una manera que minimice los efectos de largo alcance, se pueda arrancar fácilmente más tarde y se convierta en una molestia para que recuerde arreglarlo.
La parte molesta es fácil: haz que emita una advertencia cada vez que ejecutes el kludge.
La parte arrancada puede ser fácil: me gusta hacer esto poniendo el kludge detrás de un nombre de subrutina. Eso facilita la actualización ya que compartimenta el código. Cuando obtenga su solución permanente, su subrutina puede implementarla o no ser operativa. A veces, una subclase también puede funcionar bien para esto. Sin embargo, no permita que otras personas dependan de su solución rápida. Es difícil recomendar una técnica en particular sin ver la situación.
Minimizar los efectos de largo alcance debería ser fácil si el resto del código es bueno. Pase siempre por la interfaz publicada, etc.
fuente
Intente aclarar el costo del truco a los empresarios. Entonces pueden tomar una decisión informada de cualquier manera.
fuente
Podría escribirlo intencionalmente de una manera demasiado restrictiva y con un propósito único y requeriría una reescritura para ser modificada.
fuente
Tuvimos que hacer esto una vez: hacer una versión de demostración a corto plazo que sabíamos que no queríamos conservar. El cliente lo quería en una caja winTel, así que desarrollamos el prototipo en SGI / XWindows. (Hablamos ambos con fluidez, por lo que no fue un problema).
fuente
Confesión:
He usado '#define private public' en C ++ para leer datos de alguna otra capa de código. Entró como un truco, pero funciona bien y arreglarlo nunca se ha convertido en una prioridad. Ahora han pasado 3 años ...
Una de las principales razones por las que los hacks no se eliminan es el riesgo de que se introduzcan nuevos errores mientras se corrige el hack. (Especialmente cuando se trata de bases de código anteriores a TDD).
fuente
Mi respuesta es un poco diferente a las demás. Mi experiencia es que las siguientes prácticas lo ayudan a mantenerse ágil y pasar de la primera iteración / soluciones alfa de Hackey a la versión beta / lista para producción:
Desarrollo basado en pruebas
Pequeñas unidades de refactorización
Y no hace falta decir que debe contar con el apoyo de las partes interesadas para hacer cualquiera de estos correctamente. Pero con estos productos en su lugar, tiene las herramientas y los procesos adecuados para cambiar rápidamente un producto de manera importante con confianza. A veces, su capacidad para cambiar es su capacidad para administrar el riesgo de los cambios y, desde la perspectiva del desarrollo, estas herramientas / técnicas le brindan una base más segura.
fuente