Estoy estudiando limpio y, como resultado, estoy repensando bastante dramáticamente mucho cómo diseño y escribo el software.
Sin embargo, todavía estoy luchando con reglas comerciales como "guardar actualizaciones de algún elemento, primero cargar toda la lista de elementos que tengo permiso para ver / editar, etc., confirme que este elemento está en la lista, y que la categoría de elementos no está bloqueada actualmente para su uso (y otras reglas, etc., etc.) "porque esa es una regla empresarial (compleja pero no atípica), por lo que debe manejarse en el dominio de la aplicación en lugar de impulsar la lógica empresarial la capa db / persistencia.
Sin embargo, me parece que para verificar de manera eficiente estas condiciones, a menudo se manejará mejor con una consulta db bien diseñada, en lugar de cargar todos los datos en el dominio de la aplicación ...
Sin una optimización prematura, ¿cuál es un enfoque recomendado o algunos artículos del tío Bob que aborden esta pregunta? ¿O diría "validar en el dominio hasta que se convierta en un problema"?
Realmente estoy luchando por encontrar buenos ejemplos / muestras para algo que no sea el más básico de los casos de uso.
Actualizar:
Hola a todos, gracias por las respuestas. Debería haber sido más claro, he estado escribiendo software (principalmente aplicaciones web) durante mucho tiempo, y definitivamente ya he experimentado y estoy de acuerdo con todos los temas que describe colectivamente (validar por backend, no confíe en los datos del cliente, en general persiga la eficiencia en bruto solo cuando sea necesario, sin embargo, reconozca las fortalezas de las herramientas db cuando estén disponibles, etc., etc., y haya seguido el ciclo de vida de aprendizaje del desarrollador de "unir todo" para "construir un controlador gordo gigante con tendencias de código de aplicaciones N-niveles" , y ahora realmente le gusta e investiga el estilo de responsabilidad limpio / único, etc., básicamente como resultado de algunos proyectos recientes que evolucionaron en reglas comerciales bastante torpes y ampliamente distribuidas a medida que los proyectos evolucionaron y surgieron más requisitos del cliente.
En particular, estoy mirando la arquitectura de estilo limpio en el contexto de la construcción de apis REST para la funcionalidad de uso interno y de cara al cliente, donde muchas de las reglas de negocio pueden ser mucho más complejas que básicamente cada ejemplo que ve en la red (incluso por los chicos de la arquitectura Clean / Hex).
Así que supongo que realmente estaba preguntando (y no pude decir claramente) acerca de cómo Clean y una API REST se unirían, donde la mayoría de las cosas MVC que ves en estos días tienen validadores de solicitudes entrantes (por ejemplo, la biblioteca FluentValidation en .NET), pero donde muchos de mis reglas de "validación" no son tanto "es una cadena de menos de 50 caracteres" sino más "puede este usuario que llama a este usuario / interactor realizar esta operación en esta recopilación de datos dado que algún objeto relacionado está actualmente bloqueado por Team X hasta más adelante en el mes, etc., etc. "... ese tipo de validaciones profundamente involucradas donde MUCHOS objetos de dominio de negocios y reglas de dominio son aplicables.
¿Debo convertir esas reglas en un tipo específico de tipo Validator-object para acompañar cada usecase-interactor (inspirado en el proyecto FluentValidator pero con más lógica de negocios y acceso a datos involucrados), ¿debería tratar la validación de alguna manera como un Gateway? poner esas validaciones en una puerta de enlace (que creo que está mal), etc.
Como referencia, me voy de varios artículos como este , pero Mattia no discute mucho sobre la validación.
Pero supongo que la respuesta corta a mi pregunta es muy parecida a la respuesta que he aceptado: "Nunca es fácil y depende".
fuente
Respuestas:
La validación de la entrada de datos es una de esas cosas en las que todos comienzan tratando de hacerlo puro y limpio y (si son inteligentes al respecto) finalmente se rinden, porque hay muchas preocupaciones en competencia.
La capa de IU debe hacer algunas formas de validación allí mismo en la página / formulario del cliente para proporcionar comentarios en tiempo real al usuario. De lo contrario, el usuario pasa mucho tiempo esperando comentarios mientras se publica una transacción en la red.
Debido a que el cliente a menudo se ejecuta en una máquina no confiable (por ejemplo, en casi todas las aplicaciones web), estas rutinas de validación deben ejecutarse nuevamente en el lado del servidor donde se confía el código.
Algunas formas de validación están implícitas debido a restricciones de entrada; por ejemplo, un cuadro de texto puede permitir solo la entrada numérica. Esto significa que es posible que no tenga un "¿es numérico?" validador en la página, pero aún necesitará uno en el back-end, en algún lugar, ya que las restricciones de la interfaz de usuario podrían omitirse (por ejemplo, deshabilitando Javascript).
La capa de IU debe realizar algunas formas de validación en el perímetro del servicio (por ejemplo, código del lado del servidor en una aplicación web) para aislar el sistema contra ataques de inyección u otras formas maliciosas de entrada de datos. Algunas veces esta validación ni siquiera está en su base de código, por ejemplo, validación de solicitud ASP.NET .
La capa de IU debe hacer algunas formas de validación solo para convertir los datos ingresados por el usuario en un formato que la capa de negocios pueda comprender; por ejemplo, debe convertir la cadena "26/06/2017" en un objeto DateTime en la zona horaria adecuada.
La capa empresarial debería hacer la mayoría de las formas de validación porque, oye, pertenecen a la capa empresarial, en teoría.
Algunas formas de validación son más eficientes en la capa de la base de datos, especialmente cuando se necesitan verificaciones de integridad referencial (por ejemplo, para garantizar que un código de estado esté en la lista de 50 estados válidos).
Algunas formas de validación deben ocurrir en el contexto de una transacción de la base de datos debido a problemas de concurrencia, por ejemplo, reservar un nombre de usuario único debe ser atómico para que otro usuario no lo tome mientras está procesando.
Algunas formas de validación solo pueden ser realizadas por servicios de terceros, por ejemplo, al validar que un código postal y un nombre de ciudad van juntos.
En todo el sistema, pueden realizarse verificaciones nulas y verificaciones de conversión de datos en varias capas, para garantizar modos de falla razonables en presencia de fallas de código.
He visto que algunos desarrolladores intentan codificar todas las reglas de validación en la capa empresarial, y luego hacen que las otras capas lo llamen para extraer las reglas comerciales y reconstruir la validación en una capa diferente. En teoría, esto sería genial porque terminas con una sola fuente de verdad. Pero nunca, nunca he visto este enfoque hacer otra cosa que complicar innecesariamente la solución, y a menudo termina muy mal.
Entonces, si te estás matando tratando de averiguar dónde va tu código de validación, ten en cuenta que, en una solución práctica incluso para un problema moderadamente complejo, el código de validación terminará yendo a varios lugares.
fuente
La validación es parte de la capa empresarial.
El punto es: la lógica de negocios en DAO invalidará el concepto de DAO. Hacer la validación en cualquier capa superior dará como resultado una validación redundante si llama a operaciones comerciales desde otro caso de uso.
Tal vez evalúa algo de seguridad en la interfaz de usuario. Pero eso es opcional ya que los objetos de dominio seguro harán el trabajo importante. En la interfaz de usuario, los componentes serán visibles o invisibles dependiendo de los permisos que tenga el usuario conectado actualmente. Pero esto es solo una parte de la experiencia del usuario. No desea que el usuario tenga excepciones de seguridad cada vez que intente realizar una acción que no tiene permitido.
fuente
Es posible que desee verificar su perspectiva sobre quién está haciendo qué con respecto a la validación. ¿Es el DB, donde sabes que estás trabajando con el DB? ¿O es un servicio (que está respaldado y controlado por las operaciones de DB)? En mi proyecto, cada raíz agregada tiene una lista de grupos que pueden leerla y una lista de modificadores. Cuando el código busca una raíz específica o una lista de raíces que el usuario puede ver, todos los detalles se ocultan detrás de un servicio que toma la identificación del usuario y las partes adicionales del contexto de búsqueda, como donde el mosaico comienza con "bla". Al código no le importa que el DB realice una verificación de existencia para ver si los grupos de usuarios existen en los grupos de lectores. Simplemente espera una lista con o sin contenido basado en lo que ofrece el servicio, que se define solo por contrato.
Esto se aplica a todas las capas. La uniformidad de validación es la clave. Ponga la mayor cantidad posible de su validación en el dominio. Devuelve las restricciones con tu api. Soy el final, no piense en las restricciones que provienen de la biblioteca X o el almacenamiento Z, sino del servicio.
fuente
Si alguna lógica de validación se expresa de la forma más simple y más clara en forma de una consulta de base de datos, entonces adelante, usted tiene su respuesta. Pero la eficiencia solo debería ser una preocupación si tiene un problema de rendimiento conocido; de lo contrario, es una optimización prematura.
fuente