Mejores prácticas para compartir pequeños fragmentos de código entre proyectos

102

Siempre trato de seguir el principio DRY estrictamente en el trabajo; cada vez que repito el código por pereza, lo morderá más tarde cuando necesito mantener ese código en dos lugares.

Pero a menudo escribo pequeños métodos (tal vez de 10 a 15 líneas de código) que deben reutilizarse en dos proyectos que no pueden hacer referencia entre sí. El método podría ser algo que ver con redes / cadenas / MVVM, etc. y es un método generalmente útil no específico para el proyecto en el que se encuentra originalmente.

La forma estándar de reutilizar este código sería crear un proyecto independiente para el código reutilizable y hacer referencia a ese proyecto cuando lo necesite. El problema con esto es que terminamos en uno de los dos escenarios menos que ideales:

  1. Terminamos con decenas / cientos de pequeños proyectos, cada uno para albergar las pequeñas clases / métodos que necesitamos reutilizar. ¿Vale la pena crear un nuevo .DLL solo para un poco de código?
  2. Terminamos con un solo proyecto que contiene una creciente colección de clases y métodos no relacionados. Este enfoque es para lo que hizo una empresa para la que trabajaba; tenían un proyecto llamado base.common que tenía carpetas para cosas como las que mencioné anteriormente: redes, manipulación de cadenas, MVVM, etc. Fue increíblemente útil, pero hacer referencia a él arrastra innecesariamente todo el código irrelevante que no necesitabas. li>

Así que mi pregunta es:

¿Cuál es la mejor manera de hacer que un equipo de software reutilice pequeños fragmentos de código entre proyectos?

Me interesa especialmente si alguien ha trabajado en una empresa que tiene políticas en esta área, o si ha enfrentado este dilema personalmente como yo.

nota: mi uso de las palabras "Proyecto", "Solución" y "Referencia" provienen de un fondo en el desarrollo de .NET en Visual Studio. Pero estoy seguro de que este problema es independiente del idioma y la plataforma.

    
pregunta George Powell 30.03.2013 - 14:40
fuente

12 respuestas

75

Si realmente son métodos / clases reutilizables, puede escribirlos en un pequeño número de bibliotecas de 'Swiss Army Knife'. Hacemos esto muy a menudo en mi compañía; Las llamamos bibliotecas de marcos:

  • Framework.Data - Utilidades para trabajar con consultas de base de datos.
  • Framework.ESB : métodos estándar para interactuar con nuestro bus de servicios empresariales
  • Framework.Logging - Sistema de registro unificado
  • Framework.Services - Utilidades para interactuar con servicios web
  • Framework.Strings - Utilidades para la manipulación avanzada de cadenas / búsqueda de cadenas difusas, etc.
  • ...

En total, hay alrededor de una docena de bibliotecas. Realmente puede distribuir el código como mejor le parezca, para que no tenga que terminar con cientos o volcar todo en un ensamblaje gigante. Creo que este enfoque es adecuado porque solo algunos de nuestros proyectos necesitarán Framework.Data y solo unos pocos necesitarán Framework.Strings , por lo que los consumidores pueden seleccionar solo aquellas partes del marco que sean relevantes para su proyecto en particular.

Si realmente son solo fragmentos de código, y no métodos / clases reales que pueden reutilizarse fácilmente, podría intentar distribuirlos como fragmentos de código en el IDE (por ejemplo, Fragmentos de código de Visual Studio ). Los equipos con los que he trabajado en el pasado tenían una biblioteca de fragmentos comunes que facilitaba que todos pudieran seguir nuestras prácticas de codificación estándar con código interno también.

    
respondido por el p.s.w.g 30.03.2013 - 15:40
fuente
21

No estoy de acuerdo con la respuesta aceptada por muchas razones.

En mi experiencia, cuando veo bibliotecas "misceláneas" como la respuesta aceptada, son una excusa para reinventar la rueda (o no se inventa aquí (NIH) ) - un pecado mucho mayor que violar a No se repita (DRY) .

A veces, violar DRY puede ser un compromiso razonable, es mejor que introducir un acoplamiento apretado. La reutilización es una preocupación secundaria en comparación con un buen diseño orientado a objetos. Un poco (me refiero a una pequeña cantidad, aplicar la Regla de tres ) de la duplicación es más fácil de entender que una base de código de espagueti.

El enfoque de numerosas bibliotecas de propósito general establece un mal ejemplo. Esto conduce a una granularidad fina del ensamblaje y demasiados ensamblajes son malos. Hace poco reduje un interno de 24 bibliotecas a 6 bibliotecas. Mejoró el tiempo de compilación de varios minutos a ~ 20 segundos. Visual Studio también es más lento de cargar y responde menos con más ensamblajes. Tener demasiadas bibliotecas también conduce a la confusión sobre dónde debe vivir el código; Prefiero menos, reglas más simples.

¿Por qué las cosas en .Net Framework no son lo suficientemente buenas? El marco es bastante grande; muchas veces he visto código que reimplementa cosas que ya existen allí. Asegúrese realmente de que sus marcos estén llenando los vacíos en el marco .Net y no solo existan por razones estéticas (por ejemplo, "No me gusta el marco .Net aquí" o quizás algunos optimización prematura )

Introducir otra capa en su arquitectura tiene un costo de complejidad significativo. ¿Por qué existe la capa? He visto una reutilización falsa, con eso quiero decir que el código está construido sobre un marco interno. Hubiera sido mucho más eficiente implementarlo directamente sobre las bibliotecas estándar.

El uso de tecnologías estandarizadas (como el marco .Net y las bibliotecas de terceros / de código abierto populares) tiene beneficios que a menudo superan los beneficios tecnológicos comparativos de la creación de uno mismo. Es más fácil encontrar talento que conozca estas tecnologías y sus desarrolladores existentes invertirán más en aprenderlo.

Mis recomendaciones:

  • No compartir este código.
  • Cree una nueva biblioteca si tiene un propósito coherente, no use el diseño de bola de barro .
  • Reutilice las bibliotecas de terceros existentes cuando sea posible.
  • Prefiera un menor número de ensamblajes, con reglas más simples sobre dónde debe vivir el código.
respondido por el Dave Hillier 23.06.2013 - 19:34
fuente
11

Para pequeños fragmentos de código, digamos una sola clase sin dependencias, tendemos a copiar y pegar el código en los proyectos. Esto suena como una violación de DRY, y admito que puede ser a veces. Pero a largo plazo ha sido mucho mejor que tener algún tipo de proyecto masivo, de múltiples cabezas comunes por varias razones.

Primero, es más simple tener el código a la mano, especialmente al compilar y depurar cosas.

Segundo, invariablemente querrás hacer algunos pequeños ajustes al código común para ese proyecto. Si tienes una copia local de la fuente, puedes hacer el cambio y llamarlo un día. Si hay una biblioteca compartida, entonces podría estar intentando modificar esa biblioteca y luego asegurarse de no romper todas las demás aplicaciones o crear una pesadilla de versiones.

Entonces, si no es lo suficientemente robusto para su propio espacio de nombres, tendemos a empujarlo en los bits apropiados del proyecto y llamarlo un día.

    
respondido por el Wyatt Barnett 01.04.2013 - 23:30
fuente
6

La segunda solución que describe no es tan mala. En .NET, también hace referencia a un ensamblado de la GAC, incluso si solo usa una sola clase de él. 'Arrastrar código irrelevante' no es un problema como podría pensar. En este caso, es vital al menos mantener los métodos y clases relacionados organizados de manera limpia en diferentes espacios de nombres. Además, deben aplicarse buenas prácticas para el diseño de API para evitar que esta solución se convierta en un desastre.

Si se trata de fragmentos de código muy pequeños, creo que el siguiente enfoque es un buen complemento para un proyecto común: permitir que se dupliquen en diferentes soluciones. Trate con ellos como mejores prácticas: documéntelas y comuníquelas al equipo.

    
respondido por el Theo Lenndorff 30.03.2013 - 15:35
fuente
6

Solo he trabajado en entornos "empresariales" donde este tipo de cosas ha sido un problema y cada vez ha sido la segunda opción que se ha adoptado. En su mayor parte, ha funcionado bien porque no ha habido ninguna restricción en la huella de la aplicación.

Sin embargo, después de haber pasado la última semana con una empresa nueva que está ejecutando su propio servidor Nuget, me inclino a sugerir esto como una alternativa viable. Por supuesto, los problemas que espero que surjan estarán relacionados con la capacidad de descubrimiento.

Si los proyectos son adecuadamente granulares y los espacios de nombres son sensatos, puedo ver que esto se está convirtiendo en un enfoque popular en lugares.

    
respondido por el ofraski 30.03.2013 - 16:07
fuente
6

Recientemente he pensado en esto y lo que se me ocurrió fue una gran biblioteca de métodos comunes como se ha mencionado hasta ahora, pero con un giro. El proyecto de biblioteca le permitirá configurar en tiempo de compilación qué partes se incluyen como el proyecto BusyBox . Con ese enfoque, puede tener un repositorio de biblioteca de fregadero de cocina, pero solo tome las herramientas que necesita al compilar.

    
respondido por el Harvey 23.06.2013 - 16:30
fuente
5

GitHub tiene una herramienta bastante útil para guardar fragmentos de código enlace

Almacena tus fragmentos de código como repositorios de git que puedes mantener en privado, o usarlos para compartir fragmentos con otras personas.

    
respondido por el blacksh33p 26.05.2013 - 14:09
fuente
3

Dependiendo del tamaño del equipo / proyecto / empresa, esto será algo difícil de hacer de manera eficiente, a menos que ya esté integrado en su entorno de alguna manera, y cada solución que encuentre (si la implementa) costará algo de dinero . (Puede que esté más seguro, pero que no podrá medir fácilmente). Tendrás que comprobar si vale la pena el precio. Tenga en cuenta, también, que las soluciones reutilizables tienden a volverse abstractas y, a menudo, se adaptan a muchas situaciones, pero sin ser óptimas.

En cualquier caso, si desea hacer esto para el código producido por más de una persona, primero necesitará conocer a todos y cooperar. Esto incluye a los desarrolladores y administradores.

Luego, deberá asegurarse de que conoce el alcance en el que desea hacer esto. ¿Equipo? ¿Proyecto? ¿Departamento? ¿Empresa? Dependiendo de la respuesta, el tipo de código que pondrás en tales soluciones variará, al igual que la granularidad con la que adaptes las DLL. Una vez que se decida por esto, alguien (preferiblemente con algo de entusiasmo por la idea, ¿usted?) Debe sentarse y comenzar a estructurar esto.

Sin embargo, solo crear tales dlls no será suficiente para hacer el truco. Para que sean útiles, deberá anunciarlos (a los usuarios y colaboradores) y mantenerlos como cualquier otra pieza de software, lo que generalmente significa que debe poner a alguien a cargo de ellos durante mucho tiempo. También necesitará documentación confiable, que también necesitará mantenimiento. Con algo de suerte y cooperación, puede terminar con algunas de las mejores prácticas, pero también puede evolucionar fácilmente hacia un proyecto propio, dependiendo del tamaño y la cantidad de equipos involucrados. Y para eso todavía necesitarás soporte de administración.

    
respondido por el Thomas 30.03.2013 - 15:50
fuente
3

Me he encontrado con muchos problemas, y mi solución preferida es publicar el código en un repositorio habilitado para web de github / pubic. resuelve muchos problemas -

  1. acceso fácil y fácil de compartir. cvs / svn / enterprise-repos significa revisar el proyecto en múltiples áreas de trabajo IDE y, a veces, tener que cambiar las áreas de trabajo o las computadoras solo para referirse a un pequeño fragmento de código.
  2. asumiendo que estos fragmentos de código no son piezas de código de propiedad / clasificados y son variaciones del conocimiento disponible públicamente, publicándolos en un repositorio público como github significa que otros lo verán, e incluso podrían contribuir.
  3. publicar algo en el dominio público bajo tu nombre tiene la presión adicional de la reputación. comprobará y actualizará las cosas, ya que se refleja en sus habilidades como programador.
  4. actualizaciones. Lo que pasa con el mantenimiento de fragmentos de código en un repositorio es que, si no se ha utilizado un fragmento en mucho tiempo, podría quedar obsoleto (contener apis / libs obsoletos). Ejemplo: fragmento de código Java para leer un archivo. es posible que haya descubierto la mejor manera de hacerlo en 2009, pero en 2014 aparece una nueva API que lo cambia todo. tu fragmento? aún estancado en 2009. en un repositorio público, las cosas se actualizarán, ya sea por usted (porque el punto 3), sus compañeros de equipo o algún miembro de la población general de programadores, y en el proceso, incluso puede obtener sugerencias para solucionar algo es posible que haya estado haciendo mal durante mucho tiempo.

Una cosa que recomendaría: no importa dónde guardes tus fragmentos de código, siempre busca cosas en Google antes de usarlo. Las cosas cambian todo el tiempo. Los fragmentos guardados ahorran tiempo, pero también generan complacencia .

    
respondido por el Quest Monger 23.06.2013 - 12:14
fuente
2

Tenemos un proyecto separado de "utilidades" donde almacenamos todos estos pequeños métodos junto con las pruebas.

Cuando un proyecto necesita alguna utilidad, solo agrega el archivo de origen con el método requerido con "agregar como enlace".

Esto significa que no se han agregado dependencias de tiempo de ejecución (a menos que el archivo incluido necesite una).

El sistema ha funcionado bien, pero como todos los demás, necesita información sobre lo que es una utilidad. Requerir una alta cobertura de pruebas nos ha funcionado bien y las pruebas también son una buena documentación de uso. El descubrimiento sigue siendo un problema sin resolver para nosotros.

Una complejidad del proyecto de utilidad es decidir el nivel de visibilidad de los elementos. Una regla general es que los métodos deben ser internos y las estructuras de datos públicas.

    
respondido por el adrianm 31.03.2013 - 12:01
fuente
2

Mi empresa utiliza servicios web locales de intranet. Tenemos algunos servicios web que se configuran como servicios web internos comunes, y cuando otro proyecto necesita acceso a uno de los servicios, envía una solicitud http con una interfaz definida. Dado que está en la intranet, alojada en la misma granja de servidores, estas solicitudes son muy rápidas.

Obviamente, esto solo funciona con las aplicaciones de Internet (y solo funciona en milisegundos cuando está en la misma red local), pero tiene algunas ventajas realmente interesantes.

    
respondido por el Ben Lee 01.04.2013 - 23:11
fuente
0

Recientemente se me ocurrió este servicio: Snip2Code ( enlace ).

Es una forma interesante de compartir solo tus fragmentos (no solo bibliotecas) con tu equipo. Se rompe el punto habitual de crear bibliotecas comunes a las que se debería hacer referencia en otros proyectos, y en mi opinión, esta es una visión valiosa.

Además, hay muchos escenarios en los que el uso de una biblioteca común simplemente no se aplica: consideremos, por ejemplo, algunos patrones de diseño como Singleton, Strategy u Observer. Puede crear bibliotecas para admitir dichos patrones, pero aún no hay una cobertura del 100%.

La necesidad real es tener una herramienta para compartir prácticas comunes entre el equipo. Intenté usar las gistas de Github, pero estoy atascado en su búsqueda (realmente pobre) y en el hecho de que no puedo compartirlas solo entre mi equipo y no con otros ...

(Descargo de responsabilidad: soy uno de los fundadores de Snip2Code, y estaba, junto con mis co-fundadores, en su misma mentalidad hace algún tiempo: ¡¡es por eso que decidimos comenzar este proyecto!)

    
respondido por el Cristiano Ghersi 08.07.2013 - 18:49
fuente

Lea otras preguntas en las etiquetas