2009-12-21 6 views
5

Tenemos algunas bibliotecas comunes (C# pero supongo que esto no es específico de plataforma o de idioma), llamémoslos A, B y C. La biblioteca A tiene referencias a B y C, la biblioteca B tiene una referencia a una DLL de terceros, y la biblioteca C es independiente. La idea detrás de tres proyectos separados era que cada biblioteca tenía una funcionalidad distinta, pero con el tiempo la biblioteca A se ha convertido en una biblioteca común más o menos "atrapante" a la que hace referencia la mayoría de las aplicaciones de los clientes. Solo algunas aplicaciones hacen referencia a B y/o C sin A también.¿Por qué no debería tener una sola biblioteca de utilidad monolítica?

Estamos tratando de mejorar nuestras convenciones de control de código fuente, y una cosa que intentamos hacer es etiquetar y liberar adecuadamente estas DLL de biblioteca, para que los archivos de proyecto del cliente puedan apuntar a una versión estática del código en lugar del -cambiando el baúl. Esto está resultando un poco intrincado, por ejemplo, un proyecto de cliente que hace referencia tanto a A como a B. A sí hace referencia a B, por lo que técnicamente hay dos referencias a B provenientes del proyecto de cliente.

Así que lo más obvio parece ser combinar todo en una única biblioteca común/utilidad con espacios de nombres bien organizados. Como dije, casi todas las aplicaciones de clientes hacen referencia a una de estas bibliotecas, entonces, ¿a quién le importa? Hacer esto no introducirá ninguna situación indeseable con dependencias de terceros, y todas nuestras máquinas de destino son internas y mantienen aproximadamente la misma configuración de entorno/software.

Esto parece una solución muy fácil, así que pensé que al menos tendría una segunda opinión. Una alternativa podría ser usar el GAC y firmar/versionar fuertemente todo. ¿Me falta algo de captura aquí?

Respuesta

7

Creo que tiene razón al consolidarse en una única biblioteca.

Muy a menudo el código se compone en demasiadas unidades desplegables, mientras que la funcionalidad lógica parece ser el criterio para la separación. Esto es incorrecto IMO. En su lugar, los ensamblados deben alinearse con los escenarios de despliegue y los ciclos de lanzamiento. De lo contrario, terminas con un gráfico de dependencia terriblemente complejo donde, de todos modos, todos los ensamblajes se gestionan, crean y despliegan juntos.

¡Pregunta interesante sin embargo! Vamos a ver lo que otras personas piensan :)

+0

Depende de la plataforma. NodeJS usa la componente como una ventaja. Al mantener árboles de dependencia para cada módulo de forma independiente, cada módulo puede usar cualquier versión de una biblioteca para la que fue diseñado originalmente. Al ignorar por completo el problema de la consolidación, el "infierno de la dependencia" se convierte en un problema. A medida que se agrega una nueva funcionalidad, solo se deben actualizar los dependientes que requieren la nueva funcionalidad. –

+0

¿Cuál crees que es más caro, el espacio en disco requerido para almacenar más copias de una biblioteca? ¿O el tiempo de desarrollo que lleva actualizar todos los dependientes de una biblioteca cada vez que se introduce un cambio incompatible con versiones anteriores? ¿Qué pasa con el riesgo de perder un código que rompe una actualización y se empuja a la producción? Una menor funcionalidad significa que el código tendrá que volver a compilarse con menos frecuencia, alcanzará un estado estable antes, y será trivial reemplazarlo. En cierto modo, da vuelta a la convención, pero el énfasis en la componenteción funciona sorprendentemente bien en la práctica. –

+0

No hay nada malo con la componente, la pregunta era por qué criterio. – Alex

1

Sólo compartir alguna experiencia reciente que ha causado que yo tenga un ligero cambio de punto de vista sobre esto ...

La reducción de 150 proyectos en una solución a alrededor de 30 ha cortado nuestro tiempo de construcción a aproximadamente el 25% de lo que era (1 minuto y el cambio frente a 5 minutos en nuestra máquina de desarrollo típica). Si está haciendo referencias dll, no importa demasiado, pero si incluye los proyectos en la solución principal, puede descubrir que es importante. Para ser honesto, estaba un poco sorprendido por la diferencia, pero los resultados anteriores no garantizan rendimientos futuros.

Cada vez que .net carga un archivo DLL por primera vez, se toma JIT-ing y archivo de E/S. Para las aplicaciones WinForm/WPF donde el usuario puede iniciarlo varias veces al día, esta es una preocupación mayor que las aplicaciones web. Incluso para aplicaciones Winform/WPF, puede no ser tan preocupante para muchas aplicaciones.

La otra cosa a tener en cuenta son las intrincadas dependencias que causan situaciones en las que "si utilizo A, tengo que usar B porque A expone tipos de B. Mientras tanto, rara vez uso B solo" Simplemente combínelo y estar hecho con eso.

Por lo tanto, tengo entendido que hay algunas razones concretas para intentar consolidar. Probablemente hay un millón de razones subjetivas, pero en un archivo de solución grande, parece mejor tratar de ser lo más simple que pueda razonablemente lograr.

Más subjetivamente, también le sugiero que considere el archivo de proyecto como un artefacto de construcción y no como un artefacto de código. Piense en el archivo .cs como lo que realmente desea reutilizar y no en .csproj. Claro, la mayoría de las veces también reutilizarías el .csproj y solo construirías el ensamblaje de la misma manera todo el tiempo. Pero no trate de obligarse a tener dependencias o un código mucho más de lo que realmente necesita en su proyecto @. La relación entre .csproj y .cs es razonablemente laxa la mayor parte del tiempo.

EDIT: @ - añadió "en que proyecto"

1

Estoy de acuerdo que el tener una única biblioteca de estas utilidades es ideal, siempre y cuando los espacios de nombres se mantengan adecuadamente y el propio código se rompe muy bien para cualquier futura mantenimiento en la biblioteca. La principal justificación que veo para esto es exactamente lo que mencionaste, casi todas tus aplicaciones internas lo están usando.

Sin embargo, una cosa a tener en cuenta es la funcionalidad de estas piezas. Si una pieza es el espacio de nombres de la utilidad para hacer trucos ingeniosos con controles o etiquetas, y la segunda es la biblioteca de seguridad que maneja sus procedimientos de inicio de sesión, puede encontrarse con algunos problemas involuntarios cuando se agrega "cool trick D" a la biblioteca de utilidades. pero rompe una aplicación existente que depende de la biblioteca de seguridad, pero se ve obligada a actualizar ya que la DLL completa se ha actualizado.

Puede considerar reescribir las tres bibliotecas de una manera que elimine las dependencias cruzadas y vea si eso mejora la situación general de sus aplicaciones actuales y futuras.

1

Puede haber un motivo para tener proyectos separados para bibliotecas con propósitos completamente diferentes, o proyectos que hacen referencia a bibliotecas de terceros. Aparte de eso, puedes poner más en una base común de libarary.

Tenemos una biblioteca común para muchas clases, pero un proyecto separado para clases relacionadas con la web, un proyecto separado para clases relacionadas con PDF (ya que utiliza una DLL de terceros que no queremos en todas las aplicaciones), un proyecto separado para clases relacionadas con MySQL (ya que usa un conector de terceros).

También tenemos un proyecto separado para las clases relacionadas con la base de datos (MS SQL), pero eso realmente podría haber ido a la biblioteca común ya que tenemos muy pocas aplicaciones que no usan una base de datos.

2

Ver punto 1
Tener la menor cantidad de bibliotecas posible simplifica las secuencias de comandos y la implementación (menos partes de las que preocuparse). Tener una biblioteca con todos los componentes de interfaz de usuario desarrollados internamente es excelente para comenzar nuevos proyectos. Simplemente agregue esa referencia y ya tiene listos todos los componentes internos. Es de esperar que eso reduzca el tiempo dedicado a reinventar los componentes porque alguien olvidó que ya había una biblioteca con dicho componente. Lo mismo ocurre con una biblioteca de utilidad general: es mejor tener solo una, por lo que tiene toda la funcionalidad disponible con una sola referencia.

View Point 2
Separar los diversos bits relacionados de funcionalidad en bibliotecas separadas mantiene esas bibliotecas enfocadas y deja clara su intención. Como cada biblioteca está más enfocada, cada biblioteca individual será más pequeña. Por lo tanto, su paquete de implementación final puede ser más pequeño ya que solo incluirá las bibliotecas que realmente necesita. Sin embargo, tendrá que recordar cuántas bibliotecas tiene y qué contiene cada una. Esto puede ser una pesadilla de documentación y transferencia de conocimiento.

Entonces, ¿qué es más importante para usted, el tamaño de implementación o la usabilidad del desarrollador? Elija la prioridad y luego haga coincidir la organización del código con ella.

1

Yo diría que realmente todo se reduce a lo que funciona mejor para usted. Una gran biblioteca de utilidades puede ser difícil de encontrar, pero una vez más todo está en un lugar donde todos saben dónde buscar, pueden ser de mayor beneficio. También dependiendo de cómo se administre la biblioteca, puede ser más fácil para diferentes grupos mantener sus propias bibliotecas de utilidades (si necesitan controlar los cambios en ellas), pero si es administrado por un solo grupo (o si todos se llevan bien), entonces uno grande uno puede ser más fácil. Entonces realmente lo que sea que funcione para ti.

3

Este es un problema clásico de "Goldilocks and the 3 Bears".

No desea una sola biblioteca monolítica, y no quiere demasiadas bibliotecas. Desea exactamente el número correcto de bibliotecas :) No demasiadas, no muy pocas, simplemente correctas.

Hay razones para tener diferentes bibliotecas:

1) Independencia de desarrollo - las bibliotecas se pueden desarrollar de forma independiente. 2) Implementación más pequeña

Creo que una regla general podría ser si hay un equipo separado que se dedica a hacer desarrollo a tiempo completo en una sección particular de la biblioteca, debe estar separado. Si varios equipos agregan algunos bits de código aquí y allá de vez en cuando, entonces no debería haber problemas con independencia de desarrollo e implementación, y también podría tener una única biblioteca común. Parece que este es el caso en tu situación, así que ve con una sola biblioteca.

Otra pregunta que debe hacerse es "¿Qué problema que estamos experimentando actualmente dividiría la solución de la biblioteca?" Si no resuelve ningún problema, no hay necesidad de bibliotecas separadas.

+0

+1 para "Ricitos de oro y los 3 osos" –

+0

¿No dividir las bibliotecas según los límites del equipo solo conduce a la creación de silo (consulte el 'antipampañado de copa')? –

Cuestiones relacionadas