¿DRY es el enemigo de la gestión de proyectos de software?

83

Uno de los principios más básicos y ampliamente aceptados del desarrollo de software es DRY (no se repita). También está claro que la mayoría de los proyectos de software requieren algún tipo de gestión.

¿Cuáles son las tareas que son fáciles de administrar (estimar, programar, controlar)? Tareas correctas y repetitivas, exactamente las tareas que deben evitarse según DRY.

Por lo tanto, desde la perspectiva de la gestión de proyectos, es excelente resolver una tarea copiando un código existente 100 veces y hacer algunas adaptaciones menores a cada copia, según sea necesario. En todo momento, usted sabe exactamente cuánto trabajo ha realizado y cuánto le queda. Todos los gerentes te amarán.

Si, en cambio, aplica el principio DRY e intenta encontrar una abstracción que elimine más o menos el código duplicado, las cosas son diferentes. Por lo general, hay muchas posibilidades, tienes que tomar decisiones, investigar, ser creativo. Puede encontrar una mejor solución en menos tiempo, pero también puede fallar. La mayoría de las veces, realmente no se puede decir cuánto trabajo queda. Eres la peor pesadilla de un gerente de proyecto.

Por supuesto que estoy exagerando, pero obviamente hay un dilema. Mis preguntas son: ¿Cuáles son los criterios para decidir si un desarrollador está exagerando DRY? ¿Cómo podemos encontrar un buen compromiso? ¿O hay una manera de superar completamente este dilema, no solo encontrando un compromiso?

Nota: Esta pregunta se basa en la misma idea que la anterior, Cantidad de trabajo de rutina en el desarrollo de software y su efecto en la estimación , pero creo que aclara mi punto, perdón por repetirme :).

Frank Puffer
fuente
96
Háganos saber cómo se sienten sus habilidades de administración de proyectos cuando llegue el momento de buscar, cambiar y probar algo en las 100 instancias de copiar y pegar. Y no olvide el tiempo adicional que se dedicará a descubrir por qué termina roto porque solo 98 de ellos realmente cambiaron.
Blrfl
16
@Blrfl, por otro lado, desecando prematuramente el código antes de que una buena abstracción sea clara también puede dañar la productividad, ya que una abstracción compartida es una dependencia compartida. No estoy en desacuerdo, por cierto, solo señalo que definitivamente se puede encontrar un equilibrio.
GoatInTheMachine
16
El principio que evita que DRY se salga de control es el principio YAGNI (no lo va a necesitar) .
Philipp
88
No hay dilema Si el gerente del proyecto quiere que haga mucho trabajo manual superfluo porque es fácil de estimar, entonces la solución obvia es despedir al gerente del proyecto.
JacquesB
10
Si se repite, todavía tiene que hacer todo ese trabajo difícil de estimar , además de un trabajo adicional sin sentido. Entonces, ¿cómo ayuda eso al proyecto?
user253751

Respuestas:

134

Parece asumir que el objetivo principal de la gestión de proyectos es producir estimaciones exactas. Este no es el caso. El objetivo principal de la gestión de proyectos es el mismo que para los desarrolladores: entregar valor para el propietario del producto.

En teoría, un producto que utiliza muchos procesos manuales lentos en lugar de automatización podría ser más fácil de estimar (aunque lo dudo), pero no proporciona una buena relación calidad-precio para el cliente, por lo que es simplemente una mala gestión del proyecto. No hay dilema

Es bien sabido que la estimación de proyectos de software es difícil, y se han escrito numerosos libros y se han desarrollado varios procesos para gestionarlo.

Si el único objetivo del PM fuera producir estimaciones exactas, entonces sería fácil. Simplemente aumente las estimaciones a 10X y deje que los desarrolladores jueguen juegos por el resto si terminan antes. En realidad, esto sería mejor que su sugerencia de utilizar el trabajo ocupado de copiar y pegar para rellenar el tiempo, ya que jugar juegos no reducirá la capacidad de mantenimiento del producto.

Pero en realidad, el propietario del producto quiere estimaciones útiles y un producto de calidad entregado de la manera más rápida y económica posible. Estas son las limitaciones reales que un PM tendrá que navegar.

En cualquier caso, cuestiono su suposición de que el trabajo manual repetitivo es más predecible que automatizado. Toda la experiencia muestra que el trabajo manual repetitivo es más propenso a errores. ¿Y qué pasa si se descubre un error en el código copiado? De repente, el costo de corregir un error se multiplica por la cantidad de repetición, lo que hace que la incertidumbre explote.

JacquesB
fuente
21
Estoy completamente de acuerdo con sus afirmaciones aquí, pero creo que debe tenerse en cuenta que hay muchos gerentes de proyectos pésimos que realmente prefieren la previsibilidad sobre la velocidad o la calidad. La mayoría de las personas que no tienen capacitación en gestión de proyectos aprenden lo que saben al respecto de lo que han visto y mi experiencia es que los gerentes de proyectos que pueden lidiar con la incertidumbre de una manera tranquila y racional son pocos y distantes.
JimmyJames
55
@FrankPuffer He estado allí. ¿Cuánto tiempo tardará? Una opción aquí es proporcionar un rango. Lea sobre PERT específicamente sobre estimaciones de 3 puntos porque ya deberían saberlo. Porcentaje completo? Esto es lo más molesto. Intenta ignorarlo, pero si no puedes recordar que es un porcentaje de tiempo, no un porcentaje de líneas codificadas o lo que sea. Lo que realmente quieren saber es cuándo se completará. Al principio, haga predicciones conservadoras sobre cada tarea y refine a medida que avanza. Esperar hasta el último minuto para decirte más tiempo hará que la gente se vuelva loca.
JimmyJames
11
¿Cuánto tiempo tardará? Estoy 60% seguro de que podemos terminarlo en x, pero hay un 10% de posibilidades de que demore cinco veces más.
David
18
@David: Esto probablemente volvería loco al primer ministro porque sabe por experiencia que este 10% de probabilidad de que ocurra el 80% de las veces :)
Frank Puffer
77
La realidad es que a muchos lugares les encantaría seguir un proyecto en el terreno y luego tener éxito inesperadamente. Los PM a menudo son recompensados ​​por tener proyecciones precisas, por lo que tienen incentivos perversos. Este es el problema principal-agente .
Trineo
39

Tiene razón: copiar y pegar funciona muy bien, y DRY no tiene sentido cuando su tarea es producir un programa para el cual la plantilla copiada o la copia no tendrán que mantenerse o evolucionar en el futuro. Cuando esos dos componentes de software tienen un ciclo de vida completamente diferente, acoplarlos juntos refactorizando un código común en una biblioteca común que está en desarrollo puede tener efectos impredecibles para el esfuerzo. Por otro lado, al copiar secciones de código dentro de un programa o sistema de programas, todas estas partes generalmente tendrán el mismo ciclo de vida. A continuación ilustraré lo que esto significa para DRY y la gestión de proyectos.

En serio, existen muchos programas de este tipo: por ejemplo, la industria de los juegos de computadora produce muchos programas que deben mantenerse durante un período corto de algunos meses o un año como máximo, y cuando ese tiempo termina, copie y pegue el código antiguo de un juego anterior donde se excede el período de mantenimiento, en la base de código de un juego nuevo está perfectamente bien y podría acelerar las cosas.

Desafortunadamente, el ciclo de vida de la mayoría de los programas con los que tuve que lidiar en los últimos años es muy diferente. El 98% de los requisitos o solicitudes de corrección de errores que me llegaron fueron solicitudes de cambiopara programas existentes. Y cada vez que necesite cambiar algo en una pieza de software existente, la "gestión de proyectos" o la planificación funcionan mejor cuando sus esfuerzos de prueba y depuración son bastante bajos, lo que no será el caso si cambia algo en un lugar, pero debido a la copia lógica empresarial pegada, olvida fácilmente que también necesita cambiar una docena de otros lugares en la base del código. E incluso si logra encontrar todos esos lugares, el tiempo para cambiarlos todos (y probar los cambios) es probablemente mucho mayor, como si solo tuviera un lugar para cambiar. Entonces, incluso podría hacer una estimación precisa del cambio, ya que los costos una docena de veces más altos de lo necesario pueden colisionar fácilmente con el presupuesto del proyecto.

TLDR: siempre que desarrolle un programa en el que no sea necesaria ni responsable la corrección de errores y el mantenimiento del original o la copia, no dude en copiar. Pero si usted, su equipo o su empresa son o podrían ser responsables, aplique DRY siempre que pueda.

Ejemplo

Como anexo, permítanme explicar qué significa "corrección de errores y mantenimiento", y cómo esto conduce a la imprevisibilidad en la planificación, especialmente dentro de un producto, por un ejemplo del mundo real. De hecho, he visto que este tipo de cosas suceden en realidad, probablemente no con 100 instancias, pero los problemas incluso pueden comenzar cuando solo tienes una instancia duplicada.

La tarea: crear 100 informes diferentes para una aplicación, cada informe se ve muy similar, algunas diferencias de requisitos entre los informes, alguna lógica diferente, pero en general, no hay muchas diferencias.

El desarrollador que obtiene esta tarea crea la primera (digamos que toma 3 días), después de algunos cambios o correcciones de errores menores debido al control de calidad y la inspección del cliente está terminada, parece funcionar bien. Luego comenzó a crear el siguiente informe copiando y modificando todo, luego el siguiente, y para cada nuevo informe necesita ~ 1 día en promedio. Muy predecible, a primera vista ...

Ahora, después de que los 100 informes estén "listos", el programa pasa a producción real y ocurren algunos problemas que se pasaron por alto durante el control de calidad. Tal vez haya problemas de rendimiento, tal vez los informes se bloqueen de forma regular, tal vez otras cosas no funcionen según lo previsto. Ahora, cuando se aplicó el principio DRY, el 90% de esos problemas podrían resolverse cambiando la base del código en un solo lugar. Pero debido al enfoque de copiar y pegar, el problema debe resolverse 100 veces en lugar de una vez. Y debido a los cambios ya aplicados de un informe a otro, el desarrollador no puede copiar y pegar rápidamente la corrección para el primer informe en el otro 99. Tiene que buscar en los 100 informes, leerlos, traducir el cambio al modificado informe, pruébelo y quizás depure cada uno individualmente. Para la tarde, esto comienza a ponerse realmente difícil: por supuesto, puede tomarse el tiempo para una corrección de errores "regular" (digamos, 3 horas) y multiplicar esto por 100, pero en realidad, esta es probablemente una estimación incorrecta, algunas de las soluciones podrían ser más fácil de hacer que otros, otros podrían ser más difíciles. E incluso si esta estimación es correcta, hacer que la depuración cueste 100 veces más de lo necesario, le costará mucho dinero a la empresa.

Lo mismo sucederá la próxima vez cuando el cliente solicite cambiar el color del emblema de su empresa en todos esos informes, para hacer que el tamaño de página sea configurable o por algún otro requisito nuevo que afecte a todos los informes de manera similar. Entonces, si eso sucede, puede hacer una estimación de los costos y facturar al cliente 100 veces el precio que tendría que pagar cuando el código hubiera estado SECO. Sin embargo, intente esto varias veces y luego el cliente cancelará el proyecto porque probablemente no estará dispuesto a pagar sus costos de evolución exorbitantes. Y quizás en ese momento alguien haga la pregunta de por qué sucedió esto y señale con el dedo a la persona que tomó la decisión de esta programación de copiar y pegar.

Mi punto es: cuando produce software para otros, siempre tiene al menos durante un corto período de tiempo la responsabilidad de hacer que funcione, corregir errores, adaptar el programa a los requisitos cambiantes, etc. Incluso en un proyecto de campo verde, estos las piezas pueden sumar rápidamente mucho más que el esfuerzo de desarrollo inicialmente planificado. Y especialmente cuando todo su código copiado está dentro de un producto, el período de responsabilidad es para todas las partes iguales, lo cual es bastante diferente de la situación en la que copió un código antiguo de un proyecto muerto que ya no es bajo mantenimiento activo.

Doc Brown
fuente
44
Probablemente una buena respuesta, pero demasiado detallada en comparación con otras buenas respuestas.
Vince O'Sullivan
44
Puede ignorar DRY cuando "la copia no tendrá que ser mantenida o evolucionada en el futuro", pero el código que nunca se usará nuevamente a menudo termina usándose nuevamente de todos modos.
Andy Lester
"copiar y pegar funciona muy bien ..." - ¡no estoy de acuerdo! Incluso si el programa es único y se garantiza que nunca evolucionará más allá de la versión inicial, el código de copiar y pegar aún hace mucho más trabajo y corre el riesgo de corregir errores encontrados durante el desarrollo de la versión inicial del programa. A menos que nunca cometas errores, en cuyo caso eres un Dios.
JacquesB
1
@JacquesB: deberías leer mi respuesta con más cuidado, no escribí algo diferente.
Doc Brown
La programación de computadoras es simplemente diferente de construir máquinas idénticas con una línea de ensamblaje. Huh ¿Quien lo hubiera pensado? Tal vez deberíamos tener programadores trabajando como PMs. Pero entonces necesitaríamos programadores como gerentes. Programadores como accionistas. Los programadores como los clientes ... Disparen, solo enseñen a todos cómo programar y terminar con esto. (En otras palabras: no expertos nunca van a entender las vicisitudes conocidas por los expertos.)
19

Por lo tanto, desde la perspectiva de la gestión de proyectos, es excelente resolver una tarea copiando un código existente 100 veces y hacer algunas adaptaciones menores a cada copia, según sea necesario. En todo momento, usted sabe exactamente cuánto trabajo ha realizado y cuánto le queda. Todos los gerentes te amarán.

Su afirmación base es incorrecta.

Lo que hace que el software sea diferente de otras profesiones es que estás haciendo algo nuevo todos los días. Después de todo, ningún cliente va a pagar usted para construir algo que alguien ya lo ha hecho. A los gerentes de proyecto les puede gustar la previsibilidad, pero a sus jefes les gusta el valor . Si solo está copiando código con ligeras variaciones, no está proporcionando mucho valor a la empresa.

Eventualmente, la compañía se dará cuenta de que pueden hacer el mismo trabajo en una fracción del tiempo contratando a un buen programador. Y si no lo hacen, sus competidores lo harán.

Telastyn
fuente
2
Yo diría que la mayoría de las profesiones de ingeniería son sobre "hacer algo nuevo todos los días"
BlueRaja - Danny Pflughoeft
12
@ BlueRaja-DannyPflughoeft: En realidad no. Después de haber trabajado como ingeniero electrónico / eléctrico, puedo testificar que la mayoría de las profesiones de ingeniería a gran escala (aquellos proyectos que requieren puesta en marcha, como la construcción de barcos y centrales eléctricas) consisten en asegurarse de que las personas que hacen algo probado y probado lo hagan correctamente. Eso es lo que las empresas consideran "ingeniería". Hacer algo nuevo es "I + D"
slebetman
3
@Slebetman Tal vez simplemente no notaste todo el trabajo que estaba haciendo tu gerencia; incluso cuando estás haciendo lo mismo una y otra vez, el entorno cambia cada vez: no tienes una plantilla de una planta de energía que puedas entregar a un cliente y terminar con ella, debes hacer encuestas, descubra cómo suministrar a la planta materias primas y devolver el producto, administrar todas las materias primas para la construcción y lidiar con problemas de suministro y escasez de trabajo y un millón de otras cosas. Se ve como el trabajo de la plantilla (como muchos de los esfuerzos de software hacen), pero en realidad no lo es.
Luaan
1
@Luaan: Sí, pero nada de eso está haciendo algo nuevo. Todos ellos están "haciendo algo que sabemos hacer". El desarrollo de software es diferente. Principalmente porque en el software, a diferencia de los proyectos de ingeniería física, tendemos a encapsular cosas que ya sabemos cómo hacer en las bibliotecas para no tener que "hacer encuestas" manualmente, etc. Simplemente importamos una biblioteca para eso y la usamos .
slebetman
2
@slebetman Casi todo el software que se está escribiendo es "algo que sabemos hacer". Las bibliotecas también viven en un entorno que siempre cambia. Y no tiene el 100% de conocimiento y experiencia con toda la biblioteca, y todas las dependencias de esa biblioteca y las otras dependencias que tiene, y hay muchos sistemas extraños y configuraciones de hardware que simplemente se niegan a funcionar como un sistema razonable trabajo. La encapsulación es excelente, pero sigue siendo cara como el infierno y necesita toneladas de encuestas. Y la ingeniería tiene encapsulación también - bloques prefabricados, circuitos integrados, etc.
Luaan
12

La programación de cortar y pegar finalmente conduce a un software abandonado. Fui contratista de un sistema para ordenar servicios de telefonía fija de una compañía telefónica muy grande. El sistema fue cortado y pegado ad nauseum porque todas las pruebas fueron manuales y no querían cambiar ningún código de trabajo. La mejora más pequeña podría resultar en una nueva copia de cientos de líneas de código. Originalmente, la aplicación fue escrita para manejar cuentas de hasta doce líneas físicas. Por supuesto, esta limitación se realizó en cientos de ubicaciones en el código. Después de aproximadamente cuatro años, el negocio preguntó al equipo qué se necesitaría para manejar cuentas más grandes. Estimaron alrededor de $ 18 millones. En ese momento, el proyecto fue entregado a un equipo offshore para un mantenimiento mínimo. El equipo existente fue despedido.

Las organizaciones que piensan de esta manera están siendo aplastadas por compañías con mejor tecnología.

Kevin Cline
fuente
Piensa que es mejor cerebro, en lugar de mejor tecnología. La tecnología proviene del cerebro, ¿verdad? ¿Qué pasó con "Piensa más inteligente, no más duro"?
10

Una máxima a menudo olvidada que se aplica aquí es la regla de 3 . Esto indica que está bien copiar el código una vez, pero más allá de eso debe ser reemplazado por un código genérico.

3 puede parecer un número arbitrario, pero un escenario común es donde los datos y la lógica se duplican en una aplicación y base de datos. Un ejemplo a menudo citado es cuando hay una tabla de búsqueda en la base de datos y un lado del cliente de enumeración. La diferencia en los paradigmas no permite que esto se almacene fácilmente en un solo lugar, por lo que la información a menudo aparece en ambos lugares.

Si bien es bueno tener código DRY, puede haber ocasiones en que la lógica de negocios dicte una excepción, por lo que debe crear dos o más bits de código de origen que antes era genérico.

¿Entonces lo que hay que hacer? Código para el status quo (después de todo, YAGNI ). Si bien el código debe escribirse para facilitar la modificación, escribir una serie completa de campanas y silbatos para algo que podría no ser necesario es simplemente incendiar dinero.

Robbie Dee
fuente
66
Tenga en cuenta que esto significa que debe comentar que ha copiado el código (en ambos lugares) para saber si está a punto de copiarlo nuevamente, ¡no debería!
Mark Hurd
3
Lo hice en un caso en el que dos clases necesitaban el mismo método pero apenas estaban relacionadas, como primos lejanos. Hubiera tenido que agregar dependencias a casi una docena de clases para que realmente compartan el código. Así que me gustó lo que Mark sugirió: copiar y pegar el método y también dejó un comentario grande y obvio que señalaba la otra ubicación para ese método.
Jeutnarg
@MarkHurd Sí - gran punto ...
Robbie Dee
8

En su pregunta, solo enumera tres funciones de gestión de proyectos: estimación, programación y control. La gestión de proyectos se trata de lograr objetivos dentro de las limitaciones del proyecto. Los métodos utilizados para lograr los objetivos dentro de las limitaciones de un proyecto son diferentes para proyectos de software que muchos otros tipos de proyectos. Por ejemplo, desea que los procesos de fabricación sean altamente repetibles y bien entendidos. Sin embargo, el desarrollo de software es principalmente trabajo de conocimiento- no es de rutina y requiere pensar en lugar de seguir instrucciones y procedimientos rígidos. Las técnicas utilizadas para iniciar, planificar, ejecutar, monitorear y controlar, y cerrar un proyecto de software deberán dar cuenta del tipo de trabajo que se debe realizar en un proyecto de software, específicamente, trabajo no rutinario que no se puede hacer a instrucciones y procedimientos específicos.

Creo que el otro problema es que está tomando DRY, un concepto que se relaciona con la repetición de información, y está tratando de aplicarlo a la gestión de tareas. DRY simplemente dice que solo debe tener una representación autorizada de la información. Los gerentes de proyecto deberían estar adoptando esto, ya que significa que todos sabrán a dónde ir para obtener la información, la comunicación de los cambios será fácil y los cambios pueden controlarse y administrarse bien. DRY, a través de piezas reutilizables, ayuda a mantener bajos los costos a largo plazo, ayuda a mantener cronogramas a largo plazo y a mejorar la calidad: tres piezas para el Triángulo de Gestión de Proyectos . Es necesario invertir algo de tiempo y dinero para hacer que las cosas se sequen de manera efectiva, pero el trabajo del gerente del proyecto es hacer concesiones de tiempo, costo, cronograma y calidad.

Thomas Owens
fuente
Claro, el desarrollo de software es trabajo de conocimiento. En realidad, ni siquiera consideraría que mi primer ejemplo (copiar / pegar) sea el desarrollo de software en sentido estricto. Aún así, administrar este tipo de trabajo es mucho más difícil, por lo que el primer ministro, incluso si tiene antecedentes de desarrollo y sabe todo esto, en su papel de primer ministro, tiende a ignorarlo. (No digo que esto sea algo bueno, es justo lo que he observado muchas veces. Tampoco creo que esos PM sean estúpidos o incompetentes. Es más como si el papel a veces los obligara a actuar así. )
Frank Puffer
3
@FrankPuffer No estoy de acuerdo con que el rol del gerente del proyecto obligue a la persona a tomar decisiones particulares. Es más probable una fuerza educativa u organizativa. Por lo que he visto, la mayoría de la educación en gestión de proyectos se centra en técnicas de gestión de proyectos más tradicionales (probablemente porque son más comúnmente aplicables a más proyectos) que las técnicas de gestión de proyectos de software. Esto puede sangrar en organizaciones que esperan esto y no buscan otras técnicas para administrar proyectos de trabajo de conocimiento como el desarrollo de software.
Thomas Owens
2
@FrankPuffer Claro que es más difícil, pero proporciona más valor. Si el jefe de su jefe es lo suficientemente inteligente, se librará del gerente que trata de "hacer las cosas más fáciles para sí mismo" y encontrará a alguien que realmente pueda hacer su trabajo. No me malinterpreten, si hacer las cosas más fáciles proporciona valor, adelante, pero en lo que describe, esto es casi seguro en detrimento del valor final.
Luaan
4

Escribir un nuevo código es solo una pequeña parte de la tarea

Su sugerencia facilitaría la estimación de la parte de escribir inicialmente un nuevo código. Sin embargo, para traer algo nuevo (no importa si se trata de un sistema nuevo, una adición de características o un cambio de funcionalidad), hacer esto no es suficiente y es solo una minoría de trabajo: las estimaciones observadas en la literatura indican que en la práctica esto parte es algo así como 20% -40% del trabajo total.

Por lo tanto, la mayoría del trabajo (que incluye adaptar su desarrollo inicial a lo que realmente se necesitaba, integración, prueba, reescritura, reevaluación) no es más fácil de estimar; al revés, evitando intencionalmente DRY acaba de hacer que esa parte sea mucho más grande, más difícil y con estimaciones más variables: ese error o necesidad de cambio que requiere cambiar todas las partes clonadas puede no ocurrir, pero si lo hace, entonces sus estimaciones van a estar totalmente equivocados

No obtiene mejores estimaciones al mejorar la calidad de su estimación de una pequeña parte del trabajo pero empeorarla en una gran parte del trabajo; por lo que no es realmente una compensación, sino una situación de perder-perder donde se obtiene una peor productividad pero también peores estimaciones.

Pedro es
fuente
Ese es un buen punto. Sin embargo, DRY o principios similares también se aplican a otras tareas como pruebas o integración. La mayoría de las cosas se pueden hacer de forma mecánica, sin pensar mucho o de manera más inteligente. Las soluciones inteligentes a menudo son mucho más rápidas pero implican un riesgo de falla. Además, debe poner una buena cantidad de trabajo en ellos antes de obtener cualquier resultado.
Frank Puffer
No hay "riesgo de falla", hay una certeza de falla. Todo fallará tarde o temprano. Solo está eligiendo qué tan caro es el coche fúnebre y qué tan rápido conduce.
4

DRY es útil pero también está sobrevalorado. Algunas personas pueden llevarlo demasiado lejos. De lo que muchos desarrolladores no se dan cuenta es que cada vez que implementa DRY para usar el mismo método para dos propósitos (ligeramente) diferentes, está introduciendo una especie de acoplamiento muy estrecho entre los diferentes usos. Ahora, cada vez que cambie el código para el primer caso de uso, también debe verificar si regresa el segundo caso de uso. Si estos son casos de uso ampliamente independientes, es muy cuestionable si deberían estar estrechamente acoplados, probablemente no deberían estarlo.

El uso excesivo de DRY también puede conducir a métodos de Dios que explotan en complejidad para manejar todos los diferentes casos de uso a los que se someten, cuando los métodos atómicos más pequeños que replican algún código serían mucho más fáciles de mantener.

Sin embargo, sugeriría que la pregunta no es realmente relevante a nivel de gestión de proyectos. Un gerente de proyecto realmente no querrá preocuparse por este nivel de detalle de implementación. Si lo son, probablemente sea microgestión. Realmente ... cómo se implementan las cosas es más responsabilidad del desarrollador y líder técnico. La gestión de proyectos está más preocupada por lo que se hace y cuándo .

EDITAR: por comentario, estoy de acuerdo, sin embargo, en la medida en que facilita la estimación del tiempo de desarrollo, evitar DRY a veces puede reducir la cantidad de incertidumbre. Pero creo que este es un tema insignificante en relación con las preguntas más apremiantes de (1) cuánto tiempo hasta que se cumplan los requisitos comerciales, (2) qué deuda técnica se asume en el proceso, y (3) riesgos para el costo total de la propiedad de las elecciones arquitectónicas realizadas, ya sea que se seque o no en muchos casos, es una elección de diseño que debería basarse más en el riesgo / recompensa de esos factores, que en si hace que sea un poco más fácil proporcionar a los gerentes de proyecto información más precisa .

Brad Thomas
fuente
Por supuesto, el gerente del proyecto no debe ocuparse de los detalles de implementación. Ese no es mi punto. Mi punto es que, dependiendo de la forma en que un desarrollador implemente algo, es más o menos capaz de proporcionar la información requerida para la gestión del proyecto.
Frank Puffer
Para mí no tiene sentido dañar / restringir el producto o acumular deuda técnica simplemente para poder informar mejor sobre él. El valor del informe seguramente debe ser de órdenes de magnitud inferiores al valor del trabajo de calidad. Pero YMMV
Brad Thomas
¿Quizás los programadores deberían recibir órdenes de magnitud más que los gerentes?
2

Creo que estás malentendido DRY.

Usemos un ejemplo:

public Class A
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }
}

public Class B
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }

    public int Add(int x, int y)
    {
        return x + y;
    }
}

vs.

public Class C : A
{
    public int Add(int x, int y)
    {
        return x + y;
    }
}

Al reemplazar la clase B con C, hemos seguido el principio DRY y hemos reducido la duplicación de código. Pero no hemos aumentado las incógnitas o el riesgo para el proyecto (a menos que nunca haya hecho una herencia antes).

Creo que lo que quieres decir cuando hablas de DRY es algo más como una tarea de diseño. Es decir:

public Class A
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }
}

!!!¡Nuevo requerimiento! ¡Algunos clientes necesitan poder multiplicar dobles!

// Use class B for new clients!!
public Class B
{
    public int Multiply(double x, double y)
    {
        return x * y;
    }
}

vs.

public Class A // Version 2
{
    public int Multiply(int x, int y)
    {
        return Multiply(x as double, y as double);
    }

    public int Multiply(double x, double y)
    {
        return x * y;
    }
}

Aquí (suponiendo que funcione) hemos diseñado una solución que puede abordar tanto el requisito antiguo como el nuevo, esencialmente tratando de crear un modelo matemático del problema de la vida real o las reglas comerciales. En la vida real, el sistema que estamos modelando obviamente será mucho más complicado, nuestro modelo no se ajustará exactamente y los casos extremos y los resultados inesperados tomarán tiempo para encontrarlos y corregirlos.

Entonces, ¿deberíamos tomar B o A versión 2 en este caso?

  • B será más específico para el cambio solicitado real con menos efectos secundarios y será más fácil de estimar y más rápido de hacer.

  • Una versión 2 dará como resultado menos código general en el futuro y será la solución más elegante

Una vez más, voy a decir que se reduce a la calidad de las especificaciones y requisitos.

Si tenemos especificaciones muy claras que cubren los casos límite y la compatibilidad con versiones anteriores, entonces podemos estar seguros de que entendemos el sistema lo suficientemente bien como para refactorizar el modelo sin producir errores.

Si tenemos una solicitud de emergencia para un solo cliente donde el único requisito es que el comportamiento cambie para ese cliente sin tener en cuenta el sistema general; entonces 'mejorar' el modelo refactorizando A conlleva un riesgo sustancial. Tanto para romper otros clientes como para sobrepasar la fecha límite debido al tiempo extra desconocido necesario para diseñar y probar la solución.

Ewan
fuente
77
No estoy de acuerdo La herencia no es algo que haces una vez y luego lo dominas. Hay muchas trampas. Hay razones por las que la composición debería preferirse a la herencia. Entonces tenemos que tomar una decisión: ¿herencia? ¿Composición? ¿Algo más? Esta decisión probablemente será difícil en el mundo real. En el segundo ejemplo también hay muchas alternativas. ¿Qué pasa con los genéricos / plantillas? ¿Tal vez algún enfoque funcional con lambdas? Nuevamente: muchas posibilidades, cada una de las cuales tendrá implicaciones específicas.
Frank Puffer
44
El punto es en el primer ejemplo que literalmente elimina el código duplicado a través de cualquier método. pero el mismo código se ejecuta exactamente de cualquier manera. Entonces no hay cambio de funcionalidad. En el segundo ejemplo, cambias el enfoque a algo que esperas que sea funcionalmente equivalente pero que en realidad sea un código diferente
Ewan
1
Estaba en una situación donde su "solicitud de emergencia" era la norma. La compañía para la que trabajé creó sistemas de datos personalizados para muchos clientes diferentes. Al principio crearon un sistema con Cobol, luego lo copiaron para el siguiente cliente, etc., hasta que tuvieron 100 clientes. Ahora tenían un trabajo en sus manos tratando de hacer mejoras y actualizaciones sistemáticas. Estaba trabajando en un sistema que podía replicar el comportamiento de la mayoría de estos sistemas, utilizando un único conjunto de código fuente, pero personalizaciones almacenadas en los datos de configuración. No pudimos hacer todo, y algunas cosas no se pudieron agregar.
1

Párrafo por párrafo

Uno de los principios más básicos y ampliamente aceptados del desarrollo de software es DRY (no se repita). También está claro que la mayoría de los proyectos de software requieren algún tipo de gestión.

Correcto.

¿Cuáles son las tareas que son fáciles de administrar (estimar, programar, controlar)? Tareas correctas y repetitivas, exactamente las tareas que deben evitarse según DRY.

Las tareas repetitivas deben ser automatizadas, obligatorias . Son aburridos, propensos a errores, cuando se hacen a mano.

Por lo tanto, desde la perspectiva de la gestión de proyectos, es excelente resolver una tarea copiando un código existente 100 veces y hacer algunas adaptaciones menores a cada copia, según sea necesario. En todo momento, usted sabe exactamente cuánto trabajo ha realizado y cuánto le queda. Todos los gerentes te amarán.

Creo que puede cambiar la palabra "adaptación" con "configuración". Considere que tiene un error en este código que se supone que debe copiarse. Un error que aparece bajo condiciones específicas. Si no se repara en la fuente original, y se copia, habrá muchos lugares para arreglar. Esto puede ser malo, pero alguien tiene que:

  • primero arregle el código en la fuente original;
  • arreglar el código en cualquier otro lugar;
  • asegúrate de que esos fueran todos los lugares. Cuando dices que esto tuvo que hacerse con el gerente, probablemente al menos odie a alguien.

Si, en cambio, aplica el principio DRY e intenta encontrar una abstracción que elimine más o menos el código duplicado, las cosas son diferentes. Por lo general, hay muchas posibilidades, tienes que tomar decisiones, investigar, ser creativo. Puede encontrar una mejor solución en menos tiempo, pero también puede fallar. La mayoría de las veces, realmente no se puede decir cuánto trabajo queda. Eres la peor pesadilla de un gerente de proyecto.

Eliminar las duplicaciones conduce a un solo punto de falla. Si algo falla, puede estar bastante seguro de dónde sucede. SOLID y Design Patterns están ahí para ayudar a solucionar exactamente ese problema. Los plazos demasiado cortos tienden a provocar una "codificación" de estilo procesal. Más tiempo invertido en un proyecto para crear algo reutilizable significa que debe haber una cantidad mínima de tiempo invertido en el próximo proyecto cuando la función se reutilizará, pero debe ser configurable en primer lugar.

Por supuesto que estoy exagerando, pero obviamente hay un dilema. Mis preguntas son: ¿Cuáles son los criterios para decidir si un desarrollador está exagerando DRY? ¿Cómo podemos encontrar un buen compromiso? ¿O hay una manera de superar completamente este dilema, no solo encontrando un compromiso?

Mucha gente señaló que no hay dilema aquí. Si y no.

Si tiene algo altamente experimental que nunca antes se había hecho, no hay dilema. De lo contrario, si tiene que volver a hacer algo, como un nuevo sistema de reservas, ya tiene abstracciones, solo depende de lo que necesite.

Creo que el dilema es: si implementamos algo en una característica, si es poco probable que se solicite. Implemente algo cuando se le solicite. Nadie necesita una gran infraestructura que no se utilizará.

Bakudan
fuente
Implemente algo de la manera simple y rápida ahora, porque eso fue solicitado. Más tarde, cuando se necesita una forma compleja, el esfuerzo original es para nada, tiene que comenzar de nuevo. Al gerente no le gusta esto. Como si dijeras: "El tiempo que pasamos manejando hacia el oeste fue inútil si ahora necesitamos ir hacia el este". Pero dar la vuelta al mundo la primera vez solo para poder ir al este todo el tiempo también es una pérdida de tiempo.
1

No se trata en absoluto de diseñar para una futura reutilización o del principio YAGNI. Se trata de repetir código en el paquete de trabajo actual.

Absolutamente se trata de diseño. Tal vez no se reutilice per se, pero no obstante, diseñe.

¿Cuáles son los criterios para decidir si un desarrollador está exagerando DRY?

Experiencia y su entorno / situación existente. Para un problema dado, obtendrá un fuerte sentido del Principio de Prado al intentar mayores grados de SECADO. Entonces, de repente, entran en juego consideraciones de gestión. El tiempo, los objetivos, el cliente, la gestión del código a largo plazo (alguien dijo que la deuda técnica ), etc. informarán su plan de ataque.

¿Cómo podemos encontrar un buen compromiso?

Uh ... ¿diseño? Refactorizar es diseño, bueno, se supone que debe ser. El alcance de DRYing puede expandirse fácilmente como una supernova desde el bucle, el método y las clases. He estado allí, hecho eso. Pero realmente no puede saber hasta que estudie el problema: esto es diseño.

¿Cómo puede no ser un problema de diseño? Debe considerar el problema más ampliamente que el código duplicado inmediato a la mano. Esta es una actividad de diseño, ya sea código existente o una hoja en blanco; ya sea "método de extracción" o creando nuevas clases y módulos.

Epílogo

... la pregunta referida y sus respuestas no cubren el aspecto de gestión del proyecto.

Gestión típica, ignorando el tiempo de diseño. Idealmente, habríamos diseñado la repetitividad superfluamente redundante antes de la codificación. En cambio, la gerencia piensa que el desarrollo (y la corrección de errores) es un evento olímpico único, la codificación, cuando en realidad es un decatlón. Y miden 1/1000 de segundo porque piensan que todo es analógico.

Si, en cambio, aplica el principio DRY e intenta encontrar una abstracción que elimine más o menos el código duplicado, las cosas son diferentes.

Tuve esta experiencia: "Pasé dos días escribiendo esta fila (de un formulario GUI) y dos horas escribiendo el resto del formulario". Quiero decir que me tomé el tiempo para identificar las clases reutilizables, DRY es un efecto secundario natural, la fila de formulario GUI y w / in que algunos otros. Una vez depurados, estos se usaron, individualmente y en composición, en todo el formulario, que ahora se codificó muy rápido y las pruebas fueron excepcionalmente rápidas a pesar de la complejidad de la construcción. Y también pasó por pruebas formales con una tasa de errores sorprendentemente baja.

La mayoría de las veces, realmente no se puede decir cuánto trabajo queda. Eres la peor pesadilla de un gerente de proyecto.

Yo tampoco lo sabía, pero tenía fe en que el esfuerzo inicial de diseño valía la pena. Todos decimos esto, pero la administración en particular no confía en ello. La gerencia hubiera pensado que estaba jodiendo. "¡Dos días y aún no tienes el 2% codificado!"

En un caso, nos apegamos a nuestras armas cuando la gerencia dijo "estás pasando demasiado tiempo en el diseño, ponte en marcha". Y compañeros de trabajo diciendo "son demasiadas clases". Bueno, se suponía que un subproyecto mucho menos complejo tomaría alrededor de 1 mes (pensé que estaba bien adivinar) pero tardó 5 meses. 3 meses de eso fue en pruebas / arreglos porque era un punto de venta. "¡Pero no tuvimos tiempo de diseñar!". En realidad dijeron eso.

Mis preguntas son: ¿Cuáles son los criterios para decidir si un desarrollador está exagerando DRY? ¿Cómo podemos encontrar un buen compromiso? ¿O hay una manera de superar completamente este dilema, no solo encontrando un compromiso?

Muestre a la gerencia cómo funciona. Captura algunos datos. Compare con otro trabajo, especialmente el de sus compañeros de trabajo que hacen el trabajo apresurado. Ese montón de fallas siempre parece perder la carrera, quedando atascado en la prueba y luego, después del lanzamiento, volvió una y otra vez para corregir más errores.

radarbob
fuente
"Mide con un micrómetro, marca con tiza, corta con un hacha".