Primero, quiero decir que esta parece ser una pregunta / área descuidada, así que si esta pregunta necesita mejorar, ¡ayúdame a hacer de esta una gran pregunta que pueda beneficiar a otros! Estoy buscando consejos y ayuda de personas que han implementado soluciones que resuelven este problema, no solo ideas para probar.
En mi experiencia, hay dos lados de una aplicación: el lado de "tarea", que es en gran medida impulsado por el dominio y es donde los usuarios interactúan ricamente con el modelo de dominio (el "motor" de la aplicación) y el lado de los informes, donde los usuarios obtener datos basados en lo que sucede en el lado de la tarea.
Por el lado de la tarea, está claro que una aplicación con un modelo de dominio rico debería tener lógica de negocios en el modelo de dominio y la base de datos debería usarse principalmente para persistencia. Separación de preocupaciones, cada libro está escrito al respecto, sabemos qué hacer, increíble.
¿Qué pasa con el lado de los informes? ¿Son aceptables los almacenes de datos o tienen un diseño incorrecto porque incorporan la lógica empresarial en la base de datos y en los mismos datos? Para agregar los datos de la base de datos a los datos del almacén de datos, debe haber aplicado lógica y reglas de negocio a los datos, y esa lógica y reglas no provienen de su modelo de dominio, sino de sus procesos de agregación de datos. ¿Es eso incorrecto?
Trabajo en grandes aplicaciones financieras y de gestión de proyectos donde la lógica de negocios es extensa. Al informar sobre estos datos, a menudo tendré que hacer MUCHAS agregaciones para extraer la información requerida para el informe / tablero, y las agregaciones tienen mucha lógica comercial. Por razones de rendimiento, lo he estado haciendo con tablas altamente agregadas y procedimientos almacenados.
Como ejemplo, supongamos que se necesita un informe / tablero para mostrar una lista de proyectos activos (imagine 10,000 proyectos). Cada proyecto necesitará un conjunto de métricas que se muestran con él, por ejemplo:
- presupuesto total
- esfuerzo hasta la fecha
- velocidad de combustión
- fecha de agotamiento del presupuesto a la tasa de quemado actual
- etc.
Cada uno de estos implica mucha lógica de negocios. Y no solo estoy hablando de multiplicar números o alguna lógica simple. Estoy hablando para obtener el presupuesto, debe aplicar una hoja de tarifas con 500 tarifas diferentes, una para el tiempo de cada empleado (en algunos proyectos, otros tienen un multiplicador), aplicar los gastos y cualquier margen de beneficio apropiado, etc. La lógica es extensa. Tomó mucha agregación y ajuste de consultas para obtener estos datos en un tiempo razonable para el cliente.
¿Debería esto ejecutarse primero a través del dominio? ¿Qué pasa con el rendimiento? Incluso con consultas SQL directas, apenas obtengo estos datos lo suficientemente rápido como para que el cliente los muestre en un período de tiempo razonable. No puedo imaginar tratar de llevar estos datos al cliente lo suficientemente rápido si estoy rehidratando todos estos objetos de dominio, y mezclando y combinando y agregando sus datos en la capa de la aplicación, o tratando de agregar los datos en la aplicación.
Parece en estos casos que SQL es bueno para procesar datos, y ¿por qué no usarlo? Pero entonces tienes lógica de negocios fuera de tu modelo de dominio. Cualquier cambio en la lógica de negocios deberá cambiarse en su modelo de dominio y en sus esquemas de agregación de informes.
Realmente no sé cómo diseñar la parte de informes / tablero de cualquier aplicación con respecto al diseño impulsado por el dominio y las buenas prácticas.
Agregué la etiqueta MVC porque MVC es el sabor del diseño del día y la estoy usando en mi diseño actual, pero no puedo entender cómo encajan los datos de informes en este tipo de aplicación.
Estoy buscando ayuda en esta área: libros, patrones de diseño, palabras clave para google, artículos, cualquier cosa. No puedo encontrar ninguna información sobre este tema.
EDITAR Y OTRO EJEMPLO
Otro ejemplo perfecto que encontré hoy. El cliente quiere un informe para el equipo de ventas del cliente. Quieren lo que parece una métrica simple:
Para cada persona de ventas, ¿cuáles son sus ventas anuales hasta la fecha?
Pero eso es complicado. Cada vendedor participó en múltiples oportunidades de ventas. Algunos ganaron, otros no. En cada oportunidad de ventas, hay varias personas de ventas a las que se les asigna un porcentaje de crédito para la venta por su función y participación. Así que ahora imagine pasar por el dominio para esto ... la cantidad de rehidratación de objetos que tendría que hacer para extraer estos datos de la base de datos para cada vendedor:
Obtenga todos los
SalesPeople
->
Para cada uno obtenga suSalesOpportunities
->
Para cada uno obtenga su porcentaje de la venta y calcule su Monto de ventas y
luego sume todos susSalesOpportunity
Montos de ventas.
Y esa es UNA métrica. O puede escribir una consulta SQL que pueda hacerlo de manera rápida y eficiente y ajustarla para que sea rápida.
EDIT 2 - Patrón CQRS
He leído sobre el patrón CQRS y, aunque es intrigante, incluso Martin Fowler dice que no se ha probado. Entonces, ¿cómo se resolvió este problema en el pasado? Esto debe haber sido enfrentado por todos en algún momento u otro. ¿Qué es un enfoque establecido o bien usado con un historial de éxito?
Edición 3 - Sistemas / herramientas de informes
Otra cosa a considerar en este contexto son las herramientas de informes. Reporting Services / Crystal Reports, Analysis Services y Cognoscenti, etc., todos esperan datos de SQL / base de datos. Dudo que sus datos lleguen a través de su negocio más tarde para estos. Y, sin embargo, ellos y otros como ellos son una parte vital de los informes en muchos sistemas grandes. ¿Cómo se manejan adecuadamente los datos para estos cuando hay incluso lógica de negocios en la fuente de datos para estos sistemas, así como posiblemente en los propios informes?
Respuestas:
Esta es una respuesta muy simplista, pero llegar al meollo del asunto:
En términos de DDD, ¿tal vez piense en informar como un contexto limitado ?, por lo tanto, en lugar de pensar en términos de "EL" modelo de dominio, debería estar dispuesto a pensar que está bien tener más de un modelo. Entonces sí, está bien si el dominio de informes tiene lógica comercial de informes, así como está bien que el dominio transaccional tenga lógica comercial transaccional.
En cuanto a la cuestión de, digamos, procedimientos almacenados de SQL versus modelo de dominio en el código de aplicación, se aplican los mismos pros y contras para el sistema de informes que para el sistema transaccional.
Como veo que agregaste una recompensa a la pregunta, leí la pregunta nuevamente y me di cuenta de que estás pidiendo un recurso específico sobre esto, así que pensé en comenzar sugiriendo que mires otras preguntas de Stack Overflow al respecto, y encontré este https://stackoverflow.com/questions/11554231/how-does-domain-driven-design-handle-reporting
La esencia general de eso es usar CQRS como un patrón para su sistema, que es consistente con DDD, y confiar en las responsabilidades del lado de la consulta como una forma de obtener informes, pero no estoy seguro de que sea una respuesta útil en Tu caso.
También encontré este http://www.martinfowler.com/bliki/ReportingDatabase.html , que encontré vinculado desde aquí: http://groups.yahoo.com/neo/groups/domaindrivendesign/conversations/topics/2261
Aquí hay un artículo interesante de ACM sobre el tema: http://dl.acm.org/citation.cfm?id=2064685 pero está detrás de un muro de pago, por lo que no puedo leerlo (no es miembro de ACM :().
También hay esta respuesta aquí en una pregunta similar: https://stackoverflow.com/questions/3380431/cqrs-ddd-synching-reporting-database
y este: http://snape.me/2013/05/03/applying-domain-driven-design-to-data-warehouses/
¡Espero que esto ayude!
fuente
Según entiendo, su pregunta es la siguiente: la solicitud para la tarea diaria tiene
Ver >> Controlador >> Modelo (BL) >> Base de datos (datos)
Solicitud para informar
Ver >> Controlador >> Modelo >> Base de datos (Datos + BL)
Por lo tanto, el cambio en BL para la ' aplicación de tarea ' también conducirá a cambios en ' informar ' BL. Ese es tu verdadero problema, ¿verdad? Bueno, está bien hacer cambios dos veces, ese dolor que tienes que soportar de todos modos. La razón es que ambos BL están separados por sus respectivas preocupaciones. Uno es para obtener datos y otro para agregar datos. Además, su BL original y BL agregado se escribirán en diferentes tecnologías o lenguaje ( C # / java y SQL proc ). No hay escapatoria para eso.
Tomemos otro ejemplo no relacionado específicamente con los informes. Supongamos que una compañía XXX rastrea los correos electrónicos de todos los usuarios para su interpretación y vende esa información a compañías de marketing. Ahora tendrá un BL para interpretación y un BL para agregar datos para empresas de marketing. Las preocupaciones son diferentes para ambos BL. Mañana, si su BL cambia de tal manera que los correos provenientes de Cuba deben ser ignorados, entonces la lógica de negocios cambiará en ambos lados.
fuente
Informar es un contexto acotado, o un subdominio, para hablar libremente. Resuelve una necesidad empresarial de recopilar / agregar datos y procesarlos para obtener inteligencia empresarial.
La forma en que implemente este subdominio probablemente será un equilibrio entre la (mayoría) forma arquitectónicamente correcta de hacer esto y lo que su infraestructura permitirá. Me gusta comenzar por el primer lado y avanzar hacia el segundo solo cuando sea necesario.
Probablemente pueda dividir esto en dos problemas principales que está resolviendo:
Agregación o almacenamiento de datos. Esto debería procesar alguna fuente de datos y combinar la información de tal manera que se almacene en otra fuente de datos.
Consulta del origen de datos agregado para proporcionar inteligencia empresarial.
Ninguno de esos problemas hace referencia a ninguna base de datos o motor de almacenamiento específico. Su capa de dominio solo debe tratar con interfaces, implementadas en su capa de infraestructura por varios adaptadores de almacenamiento.
Puede tener varios trabajadores o algún trabajo programado, que se divide en algunas partes móviles:
Espero que puedas ver que algunos de los CQRS brillan por allí.
En el lado de los informes, solo debería hacer consultas, pero nunca directamente en la base de datos. Ve a través de tus interfaces y de tu capa de dominio aquí. Este no es el mismo dominio de problemas que sus tareas principales, pero aún debe existir cierta lógica a la que desee adherirse.
Tan pronto como se sumerja directamente en la base de datos, dependerá más de ella y eventualmente puede interferir con las necesidades de datos de su aplicación original.
Además, al menos para mí, definitivamente prefiero escribir pruebas y desarrollar código en lugar de consultas o procedimientos almacenados. También me gusta no encerrarme en herramientas específicas hasta que sea absolutamente necesario.
fuente
Es típico separar los almacenes de datos operativos / transaccionales de los informes. Este último puede tener requisitos para mantener los datos por razones legales (por ejemplo, siete años de datos financieros para auditoría financiera), y no desea todo eso en su almacén de datos transaccionales.
Por lo tanto, dividirá sus datos transaccionales por alguna medida de tiempo (semanal, mensual, trimestral, anual) y moverá las particiones más antiguas a su almacén de informes / historial a través de ETL. Puede o no ser un almacén de datos con un esquema y dimensiones en estrella. Utilizaría herramientas de informes de almacenamiento de datos para realizar consultas ad hoc y roll ups y trabajos por lotes para generar informes periódicos.
No recomendaría informar sobre su almacén de datos transaccionales.
Si prefiere seguir adelante, aquí hay más pensamientos:
¿Software de gestión de proyectos que usas en casa? Compraría antes de construir. Algo así como Rally y Microsoft Project.
fuente
Primero algo de terminología, lo que llama el lado de la tarea se conoce como Transaccional y el lado de Informes es Analytics.
Ya ha mencionado CQRS, que es un gran enfoque, pero hay poca aplicación práctica documentada del enfoque.
Lo que ha sido muy probado es complementar su procesamiento transaccional con un motor de procesamiento analítico. Esto a veces se conoce como Data Warehousing o Data Cubes. El mayor problema con respecto a la analítica es que intentar ejecutar consultas contra sus datos transaccionales en tiempo real es, en el mejor de los casos, ineficiente porque en realidad solo es posible optimizar una base de datos para leer o escribir. Para las transacciones, desea altas velocidades de escritura para evitar demoras en el procesamiento / hacer cosas. Para la presentación de informes, desea altas velocidades de lectura para poder tomar decisiones.
¿Cómo dar cuenta de estos problemas? El enfoque más simple de comprender es utilizar un esquema plano para sus informes y ETL (extracción de la carga de transformación) para transferir datos del esquema transaccional normalizado al esquema analítico desnormalizado. El ETL se ejecuta a través de un agente regularmente y precarga la tabla de análisis para que esté lista para una lectura rápida de su motor de informes.
Un gran libro para ponerse al día sobre el almacenamiento de datos es el Data Warehouse Toolkit de Ralph Kimball. Para un enfoque más práctico. Descargue la versión de prueba de SQL Server y elija el kit de herramientas de Microsoft Data Warehouse que toma la discusión general del primer libro pero muestra cómo aplicar los conceptos usando SQL Server.
Hay varios libros vinculados de esas páginas que dan más detalles sobre ETL, Star Schema Design, BI, Dashboards y otros temas para ayudarlo a seguir adelante.
La forma más rápida de llegar de donde estás a donde quieres estar es contratar a un experto en BI y seguirlo mientras implementa lo que necesitas.
fuente
Recuperar grandes cantidades de información a través de redes de área amplia, incluida Internet, es problemático debido a problemas derivados de la latencia de respuesta, la falta de acceso directo a la memoria a los recursos de servicio de datos y la tolerancia a fallas.
Esta pregunta describe un patrón de diseño para resolver los problemas de manejo de resultados de consultas que devuelven grandes cantidades de datos. Por lo general, estas consultas serían realizadas por un proceso de cliente a través de una red de área amplia (o Internet), con uno o más niveles intermedios, a una base de datos relacional que reside en un servidor remoto.
La solución implica implementar una combinación de estrategias de recuperación de datos, incluido el uso de iteradores para atravesar conjuntos de datos y proporcionar un nivel apropiado de abstracción para el cliente, doble búfer de subconjuntos de datos, recuperación de datos de subprocesos múltiples y división de consultas.
fuente
No creo que estés hablando de lógica de negocios, esto es más lógica de informes. ¿Qué hacen los usuarios con la información en esta pantalla, es simplemente para actualizaciones de estado? Su modelo de dominio se utiliza para modelar operaciones transaccionales, los informes son una preocupación diferente. Extraer los datos de SQL Server o ponerlos en un almacén de datos está bien para los escenarios de informes.
Su modelo de dominio debe hacer cumplir los invariantes de su dominio, como que un miembro del proyecto no puede reservar para el mismo proyecto al mismo tiempo, o solo puede reservar x número de horas a la semana. O no puede reservar para este proyecto ya que está completo, etc., etc., el estado de su modelo de dominio (los datos) se puede copiar para informar por separado.
Para mejorar el rendimiento de la consulta, puede usar una vista materializada. Cuando una operación se comete contra su modelo (por ejemplo, reserve 4 horas de tiempo de esta persona para proyectar x) y tiene éxito, puede lanzar un evento que luego puede almacenar en una base de datos de informes y hacer los cálculos necesarios para su informe. Entonces será muy rápido consultarlo.
Mantenga sus contextos de transacciones e informes separados, se creó una base de datos relacional para informar que un modelo de dominio no.
EDITAR
Publicación de blog útil sobre el tema http://se-thinking.blogspot.se/2012/08/how-to-handle-reporting-with-domain.html
fuente
Han pasado 4 años y acabo de encontrar esta pregunta nuevamente, y tengo cuál es, para mí, la respuesta.
Dependiendo de su aplicación y sus necesidades específicas, su dominio / base de datos de transacciones y sus informes pueden ser "sistemas" o "motores" separados, o pueden ser atendidos por un sistema. Sin embargo, deberían estar lógicamente separados, lo que significa que utilizan diferentes medios para recuperar y proporcionar datos a la interfaz de usuario.
Prefiero que estén físicamente separados (además de estar lógicamente separados), pero muchas veces los comienzas juntos (físicamente) y luego, a medida que la aplicación madura, los separas.
De cualquier manera, nuevamente, deberían ser lógicamente diferentes. Está bien duplicar la lógica de negocios en el sistema de informes. Lo importante es que el sistema de informes obtenga la misma respuesta que el sistema de dominio, pero es probable que llegue a través de diferentes medios. Por ejemplo, su sistema de dominio tendrá un montón de reglas comerciales muy estrictas implementadas en el código de procedimiento (probablemente). El sistema de informes podría implementar esas mismas reglas cuando lee los datos, pero lo haría a través del código basado en SET (por ejemplo, SQL).
Así es como podría verse de manera realista una evolución de la arquitectura de su aplicación a medida que evoluciona:
Nivel 1: dominio y sistemas de informes separados lógicamente, pero aún en la misma base de código y base de datos
Nivel 2: dominios y sistemas de informes separados lógicamente, pero bases de datos separadas ahora, con sincronización.
Nivel 3: sistemas de informes y dominios separados lógica y físicamente, y bases de datos separadas con sincronización.
La idea principal es que los informes y el dominio tienen necesidades radicalmente diferentes. Diferentes perfiles de datos (frecuencia de lecturas frente a escrituras y actualizaciones), diferentes requisitos de rendimiento, etc. Por lo tanto, deben implementarse de manera diferente y eso requiere cierta duplicación de la lógica empresarial.
Depende de su negocio idear una forma de mantener la lógica empresarial del dominio y los sistemas de informes actualizados entre sí.
fuente
El estado de cada proyecto debe almacenarse como información estática, calculada y bien formateada en la base de datos y cualquier simulación debe manejarse en el cliente como aplicación web.
Este tipo de proyección no debe ejecutarse bajo demanda. Administrar esta información a pedido, como realizar cálculos sobre recursos, tasas, tareas, hitos, etc., dará como resultado un uso extenso de la capa de cálculo sin ninguna reutilización de estos resultados para futuras llamadas.
Al imaginar un entorno distribuido ( nube pública o privada ), obtendrá los enormes costos en la capa de computación, el bajo uso de la base de datos y la falta total de caché.
El diseño de su software debe incluir la capacidad de realizar la normalización de los cálculos necesarios para obtener el resultado requerido durante la "entrada de datos", no durante la lectura. Este enfoque reduce en gran medida el uso de los recursos informáticos y, sobre todo, crea tablas que el cliente podría considerar "de solo lectura". Este es el primer paso para crear un mecanismo de almacenamiento en caché sólido y simple.
Entonces, una búsqueda primero, antes de completar la arquitectura del software, podría ser el Sistema de caché distribuido .
(solicitud: agregación)! = 1: 1
Por lo tanto, mi consideración es (para el primer y el segundo ejemplo), tratar de comprender cuándo es apropiado normalizar los datos, teniendo como objetivo reducir las agregaciones por solicitud del cliente. Que no puede ser 1: 1 (solicitud: agregación) si un objetivo es obtener un sistema sostenible.
Distribuir el cálculo en el cliente.
Otra pregunta, antes de terminar el diseño del software, podría ser, ¿cuánta normalización queremos delegar el navegador del cliente?
Fue nombrado MV *, es cierto que está de moda hoy en día, además de esto, uno de sus propósitos es crear una aplicación web (aplicación de una sola página), que puede considerarse el presente de muchas aplicaciones complejas (y afortunadamente para facturas que pagamos al proveedor de la nube, estos se ejecutan en el cliente).
Mi conclusión es por lo tanto:
Comprender cuántas operaciones son realmente necesarias para llevar a cabo la presentación de los datos;
Analizar cuántos de estos se pueden hacer en segundo plano (y luego distribuirlos a través de un sistema de caché, después de su normalización);
Comprender cuántas operaciones se pueden ejecutar en el cliente, obtener la configuración de los proyectos, ejecutarla en Vistas en la aplicación web y así reducir el cálculo realizado en el back-end;
fuente
Use caché para consulta, use dominio para almacenamiento en caché.
Hay una característica llamada "usuarios principales" en stackoverflow. Puede encontrar una línea en la parte inferior de la página de los principales usuarios, que dice "Solo se incluyen en estos totales preguntas y respuestas que no son wiki de la comunidad (se actualizan diariamente )". Esto indica que los datos están en caché.
¿Pero por qué?
Por problemas de rendimiento tal vez. Tal vez tengan la misma preocupación con la lógica de dominio con fugas ("En este caso, solo se incluyen preguntas y respuestas que no sean de wiki comunitario) en estos totales".
¿Cómo?
Realmente no sé cómo hicieron esto, así que aquí es solo una suposición :)
Primero, necesitamos encontrar preguntas / respuestas objetivo. Una tarea de programación podría funcionar, solo busca todos los objetivos potenciales.
Segundo, veamos solo una pregunta / respuesta. ¿Es un wiki no comunitario? ¿Está dentro de los 30 días? Es bastante fácil responder con modelos de dominio. Cuente los votos y almacénelos si está satisfecho.
Ahora tenemos el caché, son la salida de derivaciones de dominio. La consulta es rápida y fácil porque solo se aplican criterios simples.
¿Qué pasa si los resultados deben ser más "en tiempo real"?
Los eventos pueden hacer la ayuda. En lugar de activar el almacenamiento en caché con una tarea de programación, podemos dividir el proceso en muchos subprocesos. Por ejemplo, cuando alguien vota por la respuesta de hippoom, publicamos un evento que desencadena la actualización de la caché de usuarios principales de hippoom. En este caso, podemos ver frecuentes pequeñas tareas rápidas.
¿Es necesario CQRS?
Ni con el enfoque de tareas de programación ni con el enfoque de eventos. Pero cqrs tiene una ventaja. El caché generalmente está orientado a la visualización, si al principio no se requieren algunos elementos, es posible que no podamos calcularlos y almacenarlos en caché. CQRS con fuente de eventos ayuda a reconstituir la memoria caché para datos históricos al reproducir eventos.
Algunas preguntas relacionadas:
1. https://stackoverflow.com/questions/21152958/how-to-handle-summary-report-in-cqrs 2. https://stackoverflow.com/questions/19414951/how-to-use -rich-domain-with-masivo-operaciones / 19416703 # 19416703
Espero eso ayude :)
fuente
Descargo de responsabilidad:
soy bastante inexperto en aplicaciones con modelos de dominio.
Entiendo todos los conceptos, y ya he estado pensando durante mucho tiempo sobre cómo aplicar estos conceptos a las aplicaciones en las que estoy trabajando (que SON ricas en dominios, pero carecen de OO, modelos de dominio reales, etc.) .
Esta pregunta es uno de los problemas clave que enfrenté también. Tengo una idea de cómo resolver esto, pero como acabo de decir ... es una idea que se me ocurrió.
Todavía no lo implementé en un proyecto real, pero no veo una razón por la que no debería funcionar.
Ahora que lo he dejado claro, esto es lo que se me ocurrió: utilizaré su primer ejemplo (las métricas del proyecto) para explicar:
Cuando alguien edita un proyecto, de todos modos lo está cargando y guardando a través de su modelo de dominio.
En este momento, tiene toda la información cargada para calcular todas sus métricas (presupuesto total, esfuerzo hasta la fecha, etc.) para este proyecto.
Puede calcular esto en el modelo de dominio y guardarlo en la base de datos con el resto del modelo de dominio.
Por lo tanto, la
Project
clase en su modelo de dominio tendrá algunas propiedades comoTotalBudget
,EffortToDate
etc., y también habrá columnas con esos nombres en las tablas de la base de datos donde se almacena su modelo de dominio (en las mismas tablas o en una tabla separada ... no 't importa) .Por supuesto, debe realizar una ejecución única para calcular el valor de todos los proyectos existentes al comenzar con esto. Pero después de eso, los datos se actualizan automáticamente con los valores calculados actuales cada vez que se edita un proyecto a través del modelo de dominio.
Por lo tanto, cada vez que necesite un informe amable, todos los datos requeridos ya están allí (calculados previamente) y puede hacer algo como esto:
No importa si obtiene los datos directamente de las tablas donde se almacena el modelo de dominio, o si de alguna manera extrae los datos a una segunda base de datos, a un almacén de datos o lo que sea:
En cualquier caso, la lógica de negocios para los cálculos está exactamente en un lugar: el modelo de dominio.
No lo necesita en ningún otro lugar, por lo que no es necesario duplicarlo.
fuente