design patterns - patterns - Mantener todo vagamente acoplado y extensible: ¿Demasiadas capas, ROI demasiado pequeño?
design patterns book (7)
Yo (ahora más que nunca) veo a los desarrolladores escribir enormes cantidades de capas, como:
implementation PresentationLayer ->
interface IMyDTO ->
implementation MyDTO ->
interface IMyService ->
implementation MyService ->
interface IMyDomainRepository ->
implementation MyDomainRepository ->
interface IMyDomainObject ->
implementation MyDomainObject ->
interface IMyIndependentStorageLayer ->
implementation MyMSSQLStorageLayer
Mirando a través de los blogs de C #, esto parece ser lo mejor desde el pan rebanado. Básicamente, todo está débilmente acoplado. No use un objeto de dominio directamente. Ejecuta todo a través de una capa de servicio. Acceda a los datos a través de un repositorio. Todas las capas son perfectamente independientes.
No me malinterpreten, me gusta la idea, pero ¿no es la compensación a largo plazo enorme, especialmente en un proyecto más grande? ¿El ROI en mantenimiento es lo suficientemente grande como para justificar esto?
Las explicaciones que leo son un poco incómodas, como "de esta forma puedo adjuntar una base de datos diferente si es necesario". De Verdad? No creo que sea un problema común que alguien repentinamente demande cambiar de MSSQL a Oracle y ahora te sientas allí y desearías tener un millón de capas que no se conocen entre sí.
¿Hay una tendencia a ir por la borda con el acoplamiento flojo, o acabo de leer los blogs equivocados? ¿Cómo te sientes al respecto y has tenido casos en los que te alegras más tarde que hiciste el trabajo extra al principio?
Cuando evalúo estas cosas, generalmente me resulta útil mirarlo a través del lente del principio DRY y observar la duplicación en tu proyecto.
Si está utilizando una arquitectura que es más compleja que su proyecto, tenderá a ver muchas capas que hacen poco además de envolver otras capas y pasar llamadas. Esto se repite.
Si, por otro lado, está utilizando una arquitectura delgada para un sistema complejo, es posible que la creación de funcionalidad en una parte del sistema no le permita volver a utilizar esa funcionalidad en otra parte, lo que le obliga a escribir un código muy similar. sobre el lugar. Esto se repite.
En mi experiencia, si estás atento para identificar la duplicación y constantemente refactorizar para eliminarla, la estructura se te presentará. Digamos, por ejemplo, que está empezando con una arquitectura más bien básica, pero está dividiendo las cosas en métodos tan pronto como necesitan ser reutilizados, y separando los métodos en clases tan pronto como necesiten ser reutilizados por otras clases. Entonces eventualmente te darás cuenta de que tus 13 clases de Ayudante / Gerente / Manejador que has escrito para eliminar la duplicación en realidad se parecen bastante a que asumen una responsabilidad que podría haberse definido más claramente si hubiera entrado en una capa de Servicio.
Puede ser difícil saber cuándo vale la pena, pero creo que la clave del éxito en la construcción de un sistema con muchas capas es estar muy claro con qué responsabilidades deberían tener las diferentes capas. Cualquier capa que agregue debe serle útil para reducir la complejidad de las operaciones en la capa superior y facilitar la unión de la funcionalidad de una manera elegante.
Nada en el diseño de la aplicación viene sin un precio. Aquí el precio aumenta la complejidad. SIEMPRE tiene que analizar sus opciones antes de elegir la que mejor se adapte a sus necesidades.
Habiendo dicho eso, creo que su pregunta parece un poco parcial. En el mundo real, es probable que no vea a un cliente exigir un nuevo tipo de DB, pero a menudo puede ver a un nuevo cliente que quiere el mismo tipo de acceso a datos que el anterior, pero en otro DB. No se trata solo de la facilidad de cambio, sino también de la reutilización de código.
Obviamente, puede ser exagerado, y es necesario saber "dónde detener" la adición de capas.
Mi regla de oro es que si una capa no necesita incluir ningún código / funcionalidad significativa, no la necesito. Dicho esto, la capacidad de prueba es algo significativo, así que si una capa me compra una mejor capacidad de prueba, la agregaré.
Tome un proyecto de ejemplo hipotético. Las pruebas usan varias bases de datos SQLite en proceso para la velocidad, la base de datos de desarrollo en la computadora de algunos desarrolladores es PostgreSQL, la base de datos de etapas es una única instalación de Oracle y la base de datos de producción es Oracle sumamente escalable, muy costosa y muy difícil de configurar racimo.
¿Cómo lo lograrías sin separar la capa SQL de la capa empresarial?
Es muy difícil diseñar la concepción alineada de negocios adecuada para un software. Quiero decir con un ROI aceptable.
Sin embargo, para mí, ¡el número de capas o el nivel de bajo acoplamiento de una concepción de software depende del contexto en el que se utilizará el software!
Si está seguro de lo que tiene que hacer el software, y probablemente no habrá grandes modificaciones o adiciones en el futuro, una aplicación de acoplamiento de bajo nivel con muchas capas no es la solución. Porque hace que la arquitectura sea demasiado compleja sin ningún motivo y el tiempo invertido para la arquitectura no es rentable ...
Por otro lado, si usted sabe que la aplicación tendrá que ser personalizada para cada cliente y ciertamente será modificada en profundidad, entonces el tiempo invertido en una arquitectura de acoplamiento de bajo nivel es una buena idea ...
El acoplamiento de bajo nivel puede ser inteligente cuando desee reutilizar parte del código para otra aplicación. En este caso, el tiempo dedicado al diseño es totalmente rentable, por supuesto.
Luego, en resumen, diré que todo depende de la evolución del software en el futuro y del potencial de reutilización del código para otras aplicaciones.
Pero es una mejor práctica para mí no hacer arquitectura sistemáticamente muy compleja.
Es una tendencia reciente, y los líderes / arquitectos menos experimentados son presa de saltar en el carro.
En el proyecto en el que estoy, el acceso a los datos fue:
Interfaz de servicio -> Implementación de servicios -> Interfaz de delegados -> Implementación de delegados -> Interfaz DAO -> Implementación DAO -> Ibatis XML.
Esto fue (¡y lo es!) Malo en nuestro caso, porque la mayoría de los códigos en cualquier método de Implementación de delegados eran una sola línea; simplemente llama el DAO. Para cada DAO, teníamos dos clases extra y una configuración extra de bean, y no estábamos obteniendo nada de esto.
Acepta el cambio, refactoriza y sigue adelante. Use tantas capas como sea necesario para separar diferentes conceptos ... y luego deténgase. Si no se percibe ninguna ganancia al escribir algún código, excepto que seguirá una plantilla, reduzca la velocidad y trate de comprender completamente por qué la plantilla lo hizo, o acepte que la plantilla es incorrecta para su aplicación e ignore ese bit.
Actualmente estoy trabajando en un gran proyecto SOA donde cada capa está desacoplada, y casi todas las clases se instancian a través de una fábrica abstracta. Ahora estamos tratando de descargar parte de la funcionalidad existente en servicios alojados por separado, y es una verdadera pesadilla atravesar las capas tratando de extrapolar los bits importantes porque hay un clic permanente sin fin> Ir a la definición ... para perseguir abajo lo que era solo 1 línea de código en la capa más externa!
No hay nada de malo en el desacoplamiento per se, y ciertamente incluso en mi proyecto hay muchas áreas donde lo encuentro útil desde el punto de vista arquitectónico. Simplemente no te dejes llevar ... Sé pragmático y sopesa los pros / contras al examinar las áreas que estás considerando desacoplar.
Aclamaciones