Pregunta

I desarrollar y mantener un (500k + LOC) grandes WinForms aplicación escrita en C # 2.0. Es multiusuario y actualmente se implementa en aproximadamente 15 máquinas. El desarrollo del sistema está en curso (puede ser pensado como una versión beta perpetua), y hay muy poco hace para proteger a los usuarios de posibles nuevos errores que puedan insertarse en una acumulación semanal.

Por esta razón, entre otras, me he encontrado a ser muy dependiente de la edición-y-siga en el depurador. Esto ayuda no sólo con el insecto-caza y la corrección de errores, pero en algunos casos con desarrollo en curso así. Me resulta muy valiosa para poder ejecutar código recién escrito desde dentro del contexto de una aplicación que se ejecuta - no hay necesidad de volver a compilar y añadir un punto de entrada específico para el nuevo código (tener que añadir las opciones de menú ficticias, botones, etc para la aplicación y recordar para eliminarlos antes de la próxima construcción de producción) -. todo puede ser probado y comprobado en tiempo real sin detener el proceso

Tengo edit-y-siga en tan alta estima que el código de forma activa escriben para ser totalmente compatible con él. Por ejemplo, evito:

  • métodos anónimos y delegados en línea (a no ser completamente imposible volver a escribir)
  • métodos genéricos (excepto en estable, código de utilidad que no cambia)
  • Orientación de proyectos a 'Cualquier CPU' (es decir, no se ejecuta en 64 bits)
  • La inicialización de los campos en el punto de la declaración (inicialización se mueve al constructor)
  • bloques empadronador escrito que el uso yield (excepto en el código de utilidad)

Ahora, soy plenamente consciente de que el nuevo lenguaje presenta en C # 3 y 4 son en gran medida incompatible con edit-y-seguir (expresiones lambda, LINQ, etc). Esta es una de las razones por las que he resistido a mover el proyecto a una versión más reciente del Marco.

Mi pregunta es si es una buena práctica para evitar el uso de estas construcciones más avanzadas en favor de código que es muy, muy fácil de depurar? ¿Hay legitimidad en este tipo de desarrollo, o es un desperdicio? También, de manera importante, realice una de estas construcciones (expresiones lambda, métodos anónimos, etc) incurrirá en gastos generales de funcionamiento / memoria que bien escrito, editar y continuación compatible con código podría evitar? ... o hacen el funcionamiento interno del compilador de C # hacen tales construcciones avanzadas correr más rápido que manualmente-escrito, 'ampliado' código?

¿Fue útil?

Solución

Sin querer trillado sonido - es una buena práctica de pruebas de unidad de escritura / integración en lugar de confiar en Edit-Continuar.

De esa manera, hacer el esfuerzo una vez, y todas las otras veces es 'libre' ...

Ahora no estoy sugiriendo que las unidades de forma retrospectiva de escritura para todo el código; más bien, cada vez que tiene que corregir un error, empezar por escribir una prueba (o más comúnmente múltiples pruebas) que demuestra la corrección.

Como @Dave Swersky menciona en los comentarios, libro Mchael plumas, trabajar eficazmente con Legado código es un recurso bueno (es heredadas 5 minutos después de que lo has escrito, ¿verdad?)

Así que sí, creo que es un error para evitar nuevos constructos C # en favor de lo que permite editar y continuar; Pero también creo que es un error de aceptar nuevas construcciones sólo por el bien de ella, y sobre todo si llevan a la más difícil de entender el código.

Otros consejos

Me encanta 'Modificar y Continuar'. Me parece que es un gran facilitador para el desarrollo interactivo / depuración y yo también resulta bastante molesto cuando no funciona.

Si 'Editar y continuar' ayuda a su metodología de desarrollo entonces por todos los medios a tomar decisiones para facilitar que, teniendo en cuenta el valor de lo que se dan por vencidos.

Una de mis manías es que cualquier cosa en la edición de una función con las expresiones lambda temáticas 'Editar y continuar'. Si me tropiezo con suficiente que puede escribir la expresión lambda. Estoy en la valla con las expresiones lambda. Puedo hacer algunas cosas más rápido con ellos pero no es así me ahorra tiempo si termino escribirlos más tarde.

En mi caso, evito el uso de las expresiones lambda, cuando en realidad no necesito. Si se ponen en la forma en que puede envolver en una función para que pueda 'Editar y continuar' el código que utiliza ellos. Si ellos son gratuitos puedo escribirlos.

Su enfoque no tiene por qué ser en blanco y negro.

Se busca aclarar estas cosas un poco

  

es una buena práctica para evitar el uso de estas construcciones más avanzadas en favor de código que es muy, muy fácil de depurar?

Editar y continuar en realidad no es la depuración, se está desarrollando. Hago esta distinción porque las nuevas características de C # son muy depurable. Cada versión del lenguaje de depuración añade soporte para el nuevo lenguaje de cuenta para que sean lo más fácil posible de depuración.

  

todo puede ser probado y comprobado en tiempo real sin detener el proceso.

Esta declaración es engañosa. Es posible con Editar y continuar para verificar un cambio corrige un problema muy específico. Es mucho más difícil para verificar que el cambio sea correcta y no se rompe una serie de otras cuestiones. A saber, porque ni continuará no modifica los archivos binarios en el disco y por lo tanto no permite que elementos tales como las pruebas unitarias.

En general, aunque sí creo que es un error para evitar nuevos constructos de C # a favor de permitir editar y continuar. Editar y continuar es una gran característica (muy amado cuando me encontré por primera vez en mis días C ++). Pero de valor como un servidor de producción ayudante no compensan las ganancias producitivy de la nueva C # cuenta con mi humilde opinión.

  

Mi pregunta es si es una buena práctica para evitar el uso de estas construcciones más avanzadas en favor de código que es muy, muy fácil de depurar

Yo diría que cada vez que están obligando a ti mismo para escribir código que es:

  1. Menos expresiva
  2. Longer
  3. repetida (de evitar métodos genéricos)
  4. No portátil (no de depuración y prueba de 64 bits ??!?!?)

Está añadiendo a su coste total de mantenimiento mucho más que la pérdida de la "Editar y continuar" funcionalidad en el depurador.

Yo escribiría el mejor código posible, no código que hace que una característica de su trabajo IDE.

Si bien no hay nada inherentemente malo en su enfoque, que hace que el límite a la cantidad de expresividad entendido por el IDE. Su código se convierte en un reflejo de sus capacidades, no las del lenguaje, y por lo tanto su valor total en el mundo del desarrollo disminuye, porque tiene en sus manos a sí mismo volver a aprender otras técnicas que mejoran la productividad. Evitar LINQ a favor de Editar-and-Continuar siente como un enorme costo de oportunidad para mí personalmente, pero la paradoja es que usted tiene que ganar un poco de experiencia con ella antes de que pueda sentirse de esa manera.

Además, como se ha mencionado en otras respuestas, la unidad de pruebas de su código elimina el necesidad para ejecutar la aplicación completa todo el tiempo, y por lo tanto resuelve el dilema de una manera diferente. Si no puede botón derecho del ratón en el IDE y la prueba sólo las 3 líneas de código que le interesan, lo estás haciendo demasiado trabajo durante el desarrollo ya.

Debe introducir realmente continúa la integración, que puede ayudar a encontrar y eliminar errores antes de la implementación de software. Especialmente grandes proyectos (I consideran 500k bastante grande) necesita algún tipo de validación.

http://www.codinghorror.com/ blog / 2006/02 / revisitar-edit-y-continue.html

En cuanto a la cuestión específica: No evite estas construcciones y no se basan en sus habilidades de depuración de locos - tratar de evitar a toda insectos (en software implementado). pruebas de la unidad de escritura en su lugar.

También he trabajado en proyectos muy grandes-beta permanente.

He utilizado métodos anónimos y delegados en línea para mantener algunos bits relativamente simples de uso sin una lógica cerca de su lugar de uso único.

He utilizado métodos genéricos y clases de reutilización y fiabilidad.

He inicializado clases en constructores como plena medida posible, para mantener los invariantes de clase y eliminar la posibilidad de errores causados ??por objetos en estados no válidos.

He usado bloques empadronador para reducir la cantidad de código necesario para crear una clase de enumerador a unas pocas líneas.

Todos estos son útiles en el mantenimiento de un gran proyecto que cambia rápidamente en un estado fiable.

Si no puede editar y continuación, me editar y volver a empezar. Esto me cuesta unos pocos segundos la mayor parte del tiempo, un par de minutos en los casos desagradables. Su pena por las horas que una mayor capacidad de razonar sobre el código y una mayor fiabilidad a través de la reutilización me salva.

Hay mucho que voy a hacer para que sea más fácil encontrar errores, pero no si se va a hacer que sea más fácil tener errores también.

Test Driven Desarrollo . Me pareció muy útil para evitar el uso del depurador en absoluto. Se parte de una nueva prueba (por ejemplo, prueba de la unidad), y, después, sólo ejecuta esta unidad de prueba para comprobar su desarrollo - no se necesita toda la aplicación que se ejecuta todo el tiempo. Y esto significa que no es necesario editar y continuación!

Sé que TDD es la palabra de moda actual, pero realmente funciona para mí. Si necesito utilizar el depurador lo tomo como un fracaso personal:)

Basándose en Editar y Cont. sonidos como si hay muy poco tiempo empleado en el diseño de nuevas características, permiten pruebas unitarias solas. Esto me parece ser mala porque es probable que termina haciendo un montón de depuración y corrección de errores, ya veces sus correcciones de errores causan más errores, ¿verdad?

Sin embargo, es muy difícil juzgar si se debe o no debe utilizar las características del lenguaje o no, porque esto también depende de muchos, muchos otros factores: reqs del proyecto, los plazos de liberación, habilidades de equipo, el costo de administración de código después de la refactorización, a por nombrar algunos.

Espero que esto ayude!

El problema que parece estar teniendo es:

  

Se tarda demasiado tiempo para reconstruir aplicación que,   ponerlo en marcha de nuevo y llegar a la broca   de interfaz de usuario que se está trabajando.

Como todo el mundo ha dicho, pruebas unitarias ayudarán a reducir el número de veces que tiene que ejecutar su aplicación para encontrar errores / fix en ninguno de código de interfaz de usuario; sin embargo, no ayudan a cuestiones como el diseño de la interfaz de usuario.

En el pasado he escrito una aplicación de prueba que va a cargar rápidamente la interfaz de usuario que estoy trabajando y llenarlo con datos ficticios, con el fin de reducir el tiempo de ciclo.

La separación de código de ninguna interfaz de usuario en otras clases que se pueden probar con pruebas unitarias, permitirá que usted hace uso de todas las construcciones de C # en esas clases. A continuación, sólo puede limitar las construcciones en uso en el código de interfaz de usuario de su auto.

Cuando empecé a escribir un montón de pruebas unitarias, mi uso de “editar y continuación” se fue abajo, cómo casi no lo uso, aparte de código de interfaz de usuario.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top