2010-09-04 32 views
8

¿Se puede utilizar el patrón arquitectónico CQRS (Segmentación de la responsabilidad del comando-consulta) para construir un sitio como StackOverflow? Soy relativamente nuevo en CQRS y DDD (Domain Driven Design) y estoy explorando el patrón e intentando modelar sitios que conozco del patrón. Si bien puedo ver que CQRS es útil para muchos aspectos para un sitio como StackOverflow, hay algunas áreas de las que no estoy seguro (o, al menos, no puedo entenderlas de inmediato). Específicamente:¿Se puede usar CQRS para un sitio como StackOverflow?

  • Hacer preguntas Cuando creo una pregunta, lo veo inmediatamente y puedo editarlo. En CQRS, ejecuto un comando como 'AskQuestion' y se crea un evento llamado 'QuestionAsked'. Eventualmente, , la pregunta se envía al almacén de datos desnormalizado . Pero la experiencia de SO es inmediata. ¿Es esto posible con CQRS?
  • Votación Mis votos se reflejan de inmediato. En CQRS, me imagino que estos comandos/eventos eventualmente moviéndose a través del evento bus a la tienda de lectura. Pero SO le da a la información de inmediato.

Mis preocupaciones se centran realmente en el concepto de retroalimentación inmediata que proporciona SO. ¿Puede CQRS proporcionar esto? Si es así, ¿cómo se haría esto? ¿Hay buenos ejemplos que ilustran cómo manejar esto?

Si ayuda, mi entorno es VS2010/C#/SQL2008R2, pero estoy abierto a otras opciones como SQLite, etc. También estoy mirando los marcos de NCQRS y LOKAD, junto con la muestra de Mark Nijhof y estoy planeando descargando la muestra de Greg Young. No encontré mucho más por ahí para muestras CQRS.

Gracias!

Respuesta

7

De lo que realmente está hablando es de "consistencia eventual" de la que se habla frecuentemente al mismo tiempo que CQRS, pero puede usar cualquiera de las técnicas de forma independiente.

Lo más simple es actualizar el modelo que la interfaz de usuario usa de inmediato y usarlo para mostrar la pregunta al usuario para su posterior manipulación. Los diversos trabajos por hacer para que los otros usuarios puedan ver la actualización pueden continuar sin bloquear la interfaz de usuario. Para que esto funcione, debes validar tu comando para que sea casi seguro que tenga éxito antes de enviarlo (si el comando falla durante la ejecución, entonces necesitarás manejar la situación, por ejemplo, incorporar algún tipo de devolución de llamada al modelo de UI) .

También vale la pena tener en cuenta que, por lo general, la "eventualidad" de este tipo de cosas es tan rápida que todo habrá aparecido de todos modos, incluso para otros usuarios.

3

Cuando hace una pregunta, puede "falsificar" los datos en la interfaz de usuario. Parecerá que se actualizó inmediatamente al usuario (usted), pero pasará un tiempo antes de que los otros usuarios vean su pregunta. Debe hacer lo mismo para manejar la votación.

Si necesita comentarios inmediatos, puede considerar otras soluciones. Pero, hay algunos trucos que puede hacer para dar retroalimentación inmediata en una solución CQRS. Si, por ejemplo, necesita validar que un nombre de usuario es único, puede consultar la base de datos de lectura para averiguar si existe el nombre de usuario. Si no es así, puedes usarlo. Pero, si otro usuario ha elegido el mismo nombre de usuario mientras tanto, obtendrá un conflicto en el lado del comando. Debe manejar esto en su modelo de dominio y, por ejemplo, darle al usuario un nombre de usuario generado y enviárselo por correo electrónico. Luego puede cambiarlo a otra cosa.

+3

"falso" y "truco" no son muy tranquilizadores ... esto se parece más a un truco, una solución en lugar de una solución de sonido. –

+2

Por falso me refiero a que no tiene que enviar datos a la base de datos/servidor antes de ir a una pantalla donde se necesitan datos. No hay problema en esperar hasta que los datos hayan pasado por el sistema (escritos y leídos), pero debe entrenar al usuario para que actualice la pantalla o configure algún tipo de mecanismo de extracción. Esto puede afectar la experiencia del usuario. Y no es un truco ser inteligente ;-) – Fossmo

+0

¡Tranquilícese, Fake es exactamente lo que necesita! Es un poco un cambio de mentalidad ... – gkdm

1

Por falsificación o truco, puede pensar en el evento como un "evento pendiente", algo que es probable que tenga éxito en la fase de compromiso/publicación, pero podría fallar. Cuanta más validación realice en el lado del cliente, antes del envío inicial para la confirmación, más probabilidades tendrá de tener éxito. Por lo tanto, si tiene la intención de confiar en un compromiso pendiente, planifique un cliente más grueso en términos de validación y exposición a reglas comerciales.

Uno podría entonces permitir que el usuario continúe usando los datos (para modificaciones adicionales) al marcar o etiquetar los datos dentro de la UI confiando en "commit pending". Sería un meta atributo del objeto o atributo. Por supuesto, agregar y usar ese atributo meta aumentará la complejidad, pero dependiendo de la aplicación podría ser un caso de uso necesario.

Las colas/historias de comandos del lado del cliente pueden ser una forma de ayudar a manejar las situaciones en las que los sucesos posteriores se basaron en una falla pendiente de confirmación. En otras palabras, todo lo que dependa de una confirmación pendiente podría ser parte de un historial que podría guardarse, guardarse mientras se realizan correcciones a la confirmación pendiente fallida, desenrollarse y volverse a aplicar al evento pendiente cambiado y reenviado nuevamente, y una notificación que el evento pendiente tuvo éxito en la confirmación, todo el historial posterior del lado del cliente comenzaría a disiparse, envió el siguiente elemento en la cola, marcándolo como el evento pendiente ahora. mirada

5

Vamos a las dos preguntas ...

Hacer preguntas Cuando creo una pregunta, lo veo de inmediato y se puede editar. En CQRS, ejecuto un comando como 'AskQuestion' y se crea un evento llamado 'QuestionAsked'. Eventualmente, la pregunta se envía al almacén de datos desnormalizado. Pero la experiencia de SO es inmediata. ¿Es esto posible con CQRS?

Esto se puede lograr fácilmente. ¿Todos los usuarios necesitan ver la pregunta de inmediato o solo la persona que la pregunta? Si se demora entre 1 y 2 segundos para que aparezca a todos, ¿marcará la diferencia? Con mayor frecuencia en sistemas consistentes eventualmente existe una diferencia entre el usuario que envía una solicitud y el resto de usuarios.

Votación Mis votos se reflejan de inmediato. En CQRS, me imagino estos comandos/eventos eventualmente moviéndose a través del bus de eventos a la tienda de lectura. Pero SO me da la información de inmediato.

¿Lo da TAN de inmediato? Probemos con otro ejemplo, Facebook. Cuando haces clic en algo, ¿aparece esto inmediatamente en tus Me gusta? Los trucos de UI como poner el pulgar hacia arriba te hacen sentir como si lo hiciera. Otro ejemplo, amazon. Cuando haces clic en agregar al carrito, ¿entra inmediatamente en tu carrito? Las representaciones visuales como "agregado al carrito" o "aprobación" te hacen sentir como si el usuario lo hubiera hecho.

Hay muchos trucos como estos que pueden hacer que un sistema finalmente consistente parezca un sistema totalmente consistente.

Como nota al margen, muchas personas piensan que este tipo de cosas se hacen para la escalabilidad (que a veces es el caso). Más a menudo se están haciendo por confiabilidad. La pregunta se vuelve realidad si XYZ está inactivo. ¿Desea fallas locales aleatorias raras o desea arriesgarse a una interrupción generalizada? Uno de los mejores ejemplos para ver aquí es visitar amazon para comprar Kindle, es extraño que puedan procesar su tarjeta de crédito en 100ms mientras que los demás tardan 3-5 segundos :) ¿Qué sucede si su sistema de procesamiento de tarjetas de crédito está caído? ?

Cuestiones relacionadas