nhibernate - herramientas - ¿Son malos los generadores de código?
generar codigo automatico en java (26)
El error que muchas personas cometen al usar la generación de código es editar el código generado. Si tiene en cuenta que si siente que necesita editar el código, realmente necesita editar la herramienta de generación de código, es una gran ventaja para la productividad. Si lucha constantemente contra el código que se genera, terminará costando productividad.
Los mejores generadores de código que he encontrado son aquellos que te permiten editar las plantillas que generan el código. Realmente me gusta Codesmith por esta razón, porque está basado en plantillas y las plantillas son fácilmente editables. Cuando descubra que hay una deficiencia en el código que se genera, solo edite la plantilla y vuelva a generar su código, y estará para siempre después de eso.
La otra cosa que he encontrado es que muchos generadores de código no son súper fáciles de usar con un sistema de control de fuente. La forma en que hemos solucionado esto es comprobar las plantillas en lugar del código y lo único que comprobamos en el control de código fuente que se genera es una versión compilada del código generado (principalmente archivos DLL). Esto le ahorra mucha pena porque solo tiene que verificar algunas DLL en lugar de posiblemente cientos de archivos generados.
Utilizo MyGeneration junto con nHibernate para crear los objetos POCO básicos y los archivos de mapeo XML. He escuchado a algunas personas decir que creen que los generadores de códigos no son una buena idea. ¿Cuál es el mejor pensamiento actual? ¿Es solo que la generación de código es mala cuando genera miles de líneas de código no comprensible?
Los generadores de código son geniales, el código malo es malo.
La mayoría de las otras respuestas en esta página están en la línea de "No, porque a menudo el código generado no es muy bueno".
Esta es una respuesta pobre porque:
1) Los generadores son herramientas como cualquier otra cosa, si las malgastas, no culpes a la herramienta.
2) Los desarrolladores tienden a enorgullecerse de su capacidad para escribir un gran código una vez, pero no utiliza generadores de código para proyectos únicos.
Utilizamos un sistema de generación de código para la persistencia en todos nuestros proyectos de Java y tenemos miles de clases generadas en producción.
Como gerente, los amo porque:
1) Confiabilidad: no hay errores importantes restantes en ese código. Ha sido tan exhaustivamente probado y refinada a lo largo de los años que cuando se depuraba, nunca me preocupé por la capa de persistencia.
2) Normalización: cada código de desarrollador es idéntico a este respecto, por lo que hay mucho menos que un chico puede aprender al elegir un nuevo proyecto de un compañero de trabajo.
3) Evolución: si encontramos una mejor manera de hacer las cosas, podemos actualizar las plantillas y actualizar miles de clases rápida y consistentemente.
4) Revolución: si cambiamos a un sistema de persistencia diferente en el futuro, el hecho de que cada clase persistente tenga una API exactamente idéntica hace que mi trabajo sea mucho más fácil.
5) Productividad: solo con unos pocos clics crear un sistema de objetos persistentes a partir de los metadatos, esto ahorra miles de aburridas horas de desarrollo.
La generación de código es como usar un compilador: en casos individuales, es posible que pueda escribir un lenguaje de ensamblaje optimizado, pero en un gran número de proyectos preferiría que el compilador lo hiciera por usted, ¿verdad?
Empleamos un truco simple para garantizar que las clases siempre se puedan regenerar sin perder personalizaciones: cada clase generada es abstracta. Luego, el desarrollador lo amplía con una clase concreta, agrega la lógica de negocios personalizada y anula cualquier método de clase base que desee diferir del estándar. Si hay un cambio en los metadatos, puede regenerar la clase abstracta en cualquier momento, y si el nuevo modelo rompe su clase concreta, el compilador se lo hará saber.
El código generado por un generador de código no debe (como una generalización) usarse en una situación en la que posteriormente se edita por intervención humana. Algunos sistemas como los asistentes en varias encarnaciones de Visual C ++ generaron código que se esperaba que el programador editara a mano. Esto no era popular, ya que requería que los desarrolladores separaran el código generado, lo entendieran y realizaran modificaciones. También significaba que el proceso de generación era de una sola vez.
El código generado debe vivir en archivos separados de otro código en el sistema y solo debe generarse desde el generador. El código de código generado debe estar claramente marcado como tal para indicar que las personas no deberían modificarlo. He tenido ocasión de hacer bastantes sistemas de generación de código de un tipo u otro y todo el código así generado tiene algo como esto en el preámbulo:
-- =============================================================
-- === Foobar Module ===========================================
-- =============================================================
--
-- === THIS IS GENERATED CODE. DO NOT EDIT. ===
--
-- =============================================================
Code Generation in Action es un buen libro sobre el tema.
Creo que Mitchel lo golpeó en la cabeza. La generación de código tiene su lugar. ¡En algunas circunstancias es más efectivo que la computadora haga el trabajo por usted! Puede darle la libertad de cambiar de opinión sobre la implementación de un componente en particular cuando el costo de tiempo de hacer que el código cambie es pequeño. Por supuesto, todavía es importante entender el resultado del generador de código, pero no siempre. Teníamos un ejemplo de un proyecto que acabamos de terminar en el que varias aplicaciones de C ++ necesitaban comunicarse con una aplicación de C # en lugar de tuberías con nombre. Era mejor para nosotros usar archivos pequeños y simples que definían los mensajes y tenían todas las clases y códigos generados para cada lado de la transacción. Cuando un programador estaba trabajando en el problema X, lo último que necesitaban era preocuparse por los detalles de implementación de los mensajes y el inevitable ataque de caché que implicaría.
El mayor problema que he tenido con los generadores de código es durante el mantenimiento. Si modifica el código generado y luego realiza un cambio en su esquema o plantilla e intenta regenerarlo, puede tener problemas.
Un problema es si la herramienta no le permite proteger los cambios que ha realizado en el código modificado, entonces sus cambios serán sobrescritos.
Otro problema que he visto, particularmente con los generadores de código en RSA para servicios web, si cambia demasiado el código generado, el generador se quejará de que no coinciden y se rehusará a regenerar el código. Esto puede suceder por algo tan simple como cambiar el tipo de una variable. Entonces está atrapado generando el código en un proyecto diferente y fusionando los resultados nuevamente en su código original.
En ciertos casos (no muchos) son útiles. Por ejemplo, si desea generar clases basadas en datos de búsqueda en las tablas de la base de datos.
Esta es una pregunta de flujo de trabajo. ASP.NET es un generador de código. El motor de análisis XAML realmente genera C # antes de convertirse a MSIL. Cuando un generador de código se convierte en un producto externo como CodeSmith que está aislado de su flujo de trabajo de desarrollo, se debe tener especial cuidado para mantener su proyecto sincronizado. Por ejemplo, si el código generado es ORM y usted realiza un cambio en el esquema de la base de datos, deberá abandonar completamente el generador de códigos o bien aprovechar la capacidad de C # para trabajar con clases parciales (lo que le permite agregar miembros y funcionalidad a una clase existente sin heredarla).
Personalmente no me gusta la naturaleza aislada / Alt-Tab de los flujos de trabajo del generador; si el generador de código no es parte de mi IDE, entonces siento que es un error. Algunos generadores de código, como Entity Spaces 2009 (aún no publicados), están más integrados que generaciones anteriores de generadores.
Creo que la panacea para el propósito de los generadores de código se puede disfrutar en las rutinas de precompilación. C # y otros lenguajes .NET carecen de esto, aunque ASP.NET lo disfruta y es por eso que, digamos, SubSonic funciona muy bien para ASP.NET pero no mucho más. SubSonic genera el código C # en el tiempo de compilación justo antes de que la compilación normal de ASP.NET entre en acción.
Pida a su proveedor de herramientas (es decir, Microsoft) que respalde las rutinas previas a la construcción más exhaustivamente, para que los generadores de códigos puedan integrarse en el flujo de trabajo de sus soluciones utilizando metadatos, en lugar de administrarse manualmente como archivos de código generados externamente que deben mantenerse aislados.
Jon
Este es uno de esos temas altamente polémicos. Personalmente, creo que los generadores de códigos son realmente malos debido al código de mierda no optimizado que la mayoría de ellos emitió.
Sin embargo, la pregunta es realmente una que solo usted puede responder. En muchas organizaciones, el tiempo de desarrollo es más importante que la velocidad de ejecución del proyecto o incluso la capacidad de mantenimiento.
He escrito algunos generadores de código antes, y para ser honesto, ¡me salvaron el trasero más de una vez!
Una vez que tiene un objeto claramente definido, colección, diseño de control de usuario, puede usar un generador de código para desarrollar los conceptos básicos, permitiendo que su tiempo como desarrollador se use de manera más efectiva en la construcción de cosas complejas, después de todo, quién realmente quiere para escribir más de 300 declaraciones de propiedad pública e instancias variables? Prefiero quedar atrapado en la lógica de negocios que todas las tareas repetitivas sin sentido.
La generación de código es mala cuando dificulta la programación (IE, código mal generado o una pesadilla de mantenimiento), pero son buenos cuando hacen que la programación sea más eficiente.
Probablemente no siempre generen código óptimo, pero dependiendo de su necesidad, puede decidir que las horas reservadas por el desarrollador compensen algunos problemas menores.
Dicho todo esto, mi mayor queja con los generadores de código ORM es que el mantenimiento del código generado puede ser un PITA si el esquema cambia.
La generación de código puede causarle un poco de dolor si desea mezclar el comportamiento en sus clases. Una alternativa igualmente productiva podría ser los atributos / anotaciones y la reflexión en tiempo de ejecución.
Los compiladores son generadores de código, por lo que no son intrínsecamente malos a menos que solo desee programar en código máquina sin formato.
Sin embargo, creo que los generadores de código siempre deben encapsular por completo el código generado. Es decir, nunca debería tener que modificar el código generado a mano, cualquier cambio debe hacerse modificando la entrada al generador y regenerando el código.
Los generadores de código no son malos, pero a veces se usan en situaciones en las que existe otra solución (es decir, instanciar un millón de objetos cuando una matriz de objetos hubiera sido más adecuada y lograda en unas pocas líneas de código).
La otra situación es cuando se usan incorrectamente o se codifican mal. Demasiadas personas rechazan los generadores de códigos porque han tenido malas experiencias debido a errores, o su malentendido de cómo configurarlo correctamente.
Pero en sí mismos, los generadores de código no son malos.
-Adán
Los generadores de código pueden ser una gran ayuda para la productividad, pero hay algunas cosas que debe buscar:
Deja que trabajes de la manera que quieres trabajar.
Si tiene que doblar su código no generado para que se ajuste al código generado, entonces probablemente debería elegir un enfoque diferente.
Ejecutar como parte de tu compilación regular.
El resultado debe generarse en un directorio intermedio y no debe registrarse en el control de origen. Sin embargo, la entrada debe registrarse en el control de fuente.
Sin instalar
Lo ideal es que también verifique la herramienta en el control de la fuente. Hacer que las personas instalen cosas cuando preparan una nueva máquina de construir es una mala noticia. Por ejemplo, si bifurca, desea poder versionar las herramientas con el código.
Si es necesario, realice una secuencia de comandos única que tomará una máquina limpia con una copia del árbol de origen y configurará la máquina según sea necesario. Totalmente automatizado, por favor.
Sin salida de edición
No debería tener que editar la salida. Si el resultado no es lo suficientemente útil tal como es, entonces la herramienta no está funcionando para usted.
Además, la salida debe indicar claramente que es un archivo generado y no debe editarse.
Salida legible
La salida debe escribirse y formatearse bien. Desea poder abrir la salida y leerla sin muchos problemas.
#line
Muchos lenguajes admiten algo así como una directiva #line
, que le permite asignar el contenido de la salida a la entrada, por ejemplo al producir mensajes de error del compilador o al ingresar al depurador. Esto puede ser útil, pero también puede ser molesto a menos que se haga realmente bien, por lo que no es un requisito.
Los primeros compiladores de C ++ fueron generadores de código que escupían código C (CFront).
No estoy seguro de si este es un argumento a favor o en contra de los generadores de código.
Mi postura es que los generadores de código no son malos, pero MUCHOS usos de ellos sí lo son.
Si está usando un generador de código para ahorrar tiempo y escribe un buen código, entonces genial, pero muchas veces no está optimizado, o agrega mucha sobrecarga, en esos casos, creo que es malo.
Realmente puede convertirse en un problema con la capacidad de mantenimiento cuando tiene que regresar y no puede entender lo que está sucediendo en el código. Por lo tanto, muchas veces debe sopesar la importancia de realizar el proyecto rápidamente en comparación con la facilidad de mantenimiento.
mantenimiento <> proceso de codificación fácil o rápido
Si es un generador de código cobol de mainframe que Fran Tarkenton está tratando de vender, entonces ¡absolutamente sí!
Sirven como una muleta que puede desactivar su capacidad para mantener el programa a largo plazo.
Son como cualquier otra herramienta. Algunos dan mejores resultados que otros, pero depende del usuario saber cuándo usarlos o no. Un martillo es una herramienta terrible si estás intentando atornillar un tornillo.
Uso My Generation con Entity Spaces y no tengo ningún problema con él. Si tengo un cambio de esquema, simplemente vuelvo a generar las clases y todo sale bien.
Utilizamos generadores de código para generar clases de entidad de datos, objetos de base de datos (como desencadenadores, procesos almacenados), proxies de servicio, etc. En cualquier lugar donde vea gran cantidad de código de repitición siguiendo un patrón y gran cantidad de trabajo manual, los generadores de códigos pueden ayudar. Pero, no debe usarlo demasiado en la medida en que el mantenimiento sea un problema. También surgen algunos problemas si quieres regenerarlos.
Herramientas como Visual Studio, Codesmith tienen sus propias plantillas para la mayoría de las tareas comunes y hacen que este proceso sea más fácil. Pero, es fácil de implementar por su cuenta.
En un proyecto reciente, construimos nuestro propio generador de código. Generamos todo el material de la base de datos y todo el código base para nuestra vista y clases de controlador de vista. Aunque el generador tardó varios meses en construirse (sobre todo porque era la primera vez que lo hacíamos, y tuvimos un par de inicios en falso) se amortizó la primera vez que lo ejecutamos y generó el marco básico para toda la aplicación en unos diez minutos. Todo esto fue en Java, pero Ruby es un excelente lenguaje de escritura de códigos, especialmente para proyectos pequeños y únicos. Lo mejor fue la consistencia del código y la organización del proyecto. Además, tienes que pensar en el marco básico antes de tiempo, lo cual siempre es bueno.
La mejor aplicación de un generador de código es cuando todo el proyecto es un modelo, y todo el código fuente del proyecto se genera a partir de ese modelo. No estoy hablando de UML y basura relacionada. En este caso, el modelo de proyecto también contiene código personalizado.
Entonces, lo único que deben preocupar a los desarrolladores es el modelo. Un cambio arquitectónico simple puede resultar en la modificación instantánea de miles de líneas de código fuente. Pero todo permanece sincronizado.
Este es en mi humilde opinión el mejor enfoque. ¿Suena utópico? Al menos sé que no lo es;) El futuro cercano lo dirá.
Nuestro proyecto actual hace un uso intensivo de un generador de código. Eso significa que he visto los beneficios "obvios" de generar código por primera vez (sin errores de codificador, sin errores tipográficos, mejor adherencia a un estilo de codificación estándar) y, después de algunos meses en modo de mantenimiento, las desventajas inesperadas. Nuestro generador de código, de hecho, mejoró inicialmente la calidad de nuestra base de código. Nos aseguramos de que estuviera completamente automatizado e integrado con nuestras compilaciones automáticas. Sin embargo, yo diría que:
(1) Un generador de código puede ser una muleta. Tenemos varios bloqueos enormes y desagradables de código difícil de mantener en nuestro sistema ahora, porque en un momento en el pasado era más fácil agregar veinte nuevas clases a nuestro archivo XML de generación de código, que hacer un análisis y clase adecuados. refactorización
(2) Las excepciones a la regla te matan. Usamos el generador de código para crear cientos de clases de Pantalla y Objeto Comercial. Inicialmente, aplicamos un estándar sobre qué métodos podrían aparecer en una clase, pero como todos los estándares, comenzamos a hacer excepciones. Ahora, nuestro archivo XML de generación de código es un monstruo masivo, lleno de fragmentos de casos especiales de código Java que se insertan en clases seleccionadas. Es casi imposible de analizar o entender.
(3) Dado que gran parte de nuestro código se genera utilizando valores de una base de datos, se ha demostrado que es difícil para los desarrolladores mantener una base de código consistente en sus estaciones de trabajo individuales (ya que puede haber múltiples versiones de la base de datos). La depuración y el rastreo a través del software es mucho más difícil, y los novatos del equipo tardan mucho más en descubrir el "flujo" del código, debido a la abstracción adicional y las relaciones implícitas entre las clases. IDE no puede recoger las relaciones entre dos clases que se comunican a través de una clase generada por código.
Eso es probablemente suficiente por ahora. Creo que los generadores de código son geniales como parte del kit de herramientas individual de un desarrollador; un conjunto de scripts que escriben su código repetitivo hacen que comenzar un proyecto sea mucho más fácil. Pero los generadores de código no hacen que los problemas de mantenimiento desaparezcan.
Los generadores de código son grandiosos asumiendo que es un buen generador de código. Especialmente trabajando c ++ / java que es muy detallado.