Ejercicio Grupal en clase 2C08

Esta página cuenta el camino que estamos siguiendo para diseñar una arquitectura en conjunto con toda la clase. Una descripción funcional de lo que queremos hacer pueden encontrar acá.

La intención es mostrar no sólo los resultados que fuimos generando sino también cuáles fueron las dudas que se fueron planteando, qué preguntas nos hicimos en cada momento, que estrategias seguimos para resolver los problemas que fuimos encontrando en el camino. Por eso para cada clase tenemos:

  • La documentación de la arquitectura hasta donde hayamos llegado en cada caso (documentos que pueden ser modificados o extendidos posteriormente).
  • Una breve reseña de lo que trabajamos en clase, con la intención de dejar constancia de cómo llegamos a esas decisiones.

Cabe destacar que esta secuencia de pasos no pretende ser una metodología ni mucho menos, simplemente fueron los pasos que nosotros fuimos siguiendo: Podría haber otras muchas formas de encararlo (de hecho la nuestra está en parte limitada por el orden de los temas que se dan en la materia, no podemos resolver problemas en la arquitectura de los que antes no hayamos hablado en clase!).

Paso 1 - Atributos de Calidad

  • Comenzamos tratando de entender el dominio y los potenciales problemas.
  • Nos pusimos como objetivo determinar los requerimientos en cuanto a los atributos de calidad ya vistos: performance, disponibilidad, modificabilidad.
  • Además de los atributos detectamos el riesgo que representa la conectividad, por ahora es el único riesgo en nuestra planilla, ya habrán más.
  • Generamos este documento que resume nuestras decisiones: APIT - Ejercicio Grupal Cuatrimestral - Atributos de calidad.pdf

¿En qué pensamos al hablar de requerimientos?

Durante la charla surgieron algunas ideas que me parecen más importantes que el documento que generamos:

  1. Necesitamos bajar a detalle: decir "tiene que estar siempre disponible" no es suficiente. En el ejemplo surgen dos ideas:
    • Por un lado, pensar qué significa disponibilidad en nuestro caso puntual. ¿Para qué operaciones es importante la disponibilidad? Hay algunas operaciones para las que la disponibilidad es más importante que otras, establecer un requerimiento de disponibilidad igual para todo el sistema puede hacerlo más costoso o más difícil de cumplir y nos desvía del objetivo principal.
    • Por el otro, entendiendo que 100% de disponibilidad no es posible, hay que pensar en un número razonable. En particular el sistema que estamos reemplazando está lejos de alcanzar un 100%. Tener una estimación del número real actual puede ser un buen punto de partida para definir un objetivo alcanzable.
  2. Entender el juego permantente de trade-offs entre los distintos requerimientos, en nuestro ejemplo nuestros requerimientos de disponibilidad podrían ir en desmedro de la disponibilidad.
    • Y eso nos lleva a que pensar en prioridades: ¿cuál de los dos me importa más?
    • Con esa idea en mente ordenamos nuestros requerimientos por prioridad. Muchas veces los requerimientos no vienen en forma de un conjunto cerrado, inamovible donde todos son indispensables. Un entorno donde se trabaja con el entendimiento de las necesidades del cliente y con un juego de requerimientos que (dentro de ciertos límites obvios) es maleable a la viabilidad técnica y al desarrollo del proyecto, suele ser más productivo.
  3. La vinculación con las decisiones posteriores, de nuevo: determinadas combinaciones de requerimientos pueden ser inviables de construir o prohibitivamente costosas, esto hay que tenerlo en mente en el momento de cerrar los requerimientos si no después es demasiado tarde. En el ejemplo:
    • Es importante la decisión de dónde está el saldo, las dos estrategias, los riesgos de una y otra.
    • La solución distribuida por ejemplo requiere de un análisis de viabilidad, estudiar el mercado, las tecnologías que yo podría utilizar para hacer eso, antes de tener una verificación concreta de que lo que yo estoy pidiendo tiene sentido no puedo jugármela a eso.
    • En algunos casos tengo que tomarme el tiempo para tomar una decisión, en otros puedo tratar de plantear el camino de forma de tomar esa decisión más adelante cuando tenga más información.
  4. (Y esto no tiene que ver sólo con los requerimientos:) Cuando yo elijo entre dos alternativas, es muy probable que la que yo elegí también presentaba desventajas o riesgos, entonces es importante pensar cómo los voy a mitigar.

Paso 2 - Atributos de Calidad

Hoy nos planteamos como objetivo tirar alguna ideas sobre las tácticas para disponibilidad, performance y modificabilidad (que ya vimos), quedarían para el siguiente paso las demás (en particular las de seguridad que es uno de nuestros drivers).

Decisión estratégica: ¿centralizado o distribuido?

Sin embargo, rápidamente nos damos cuenta que nuestro principal problema es más bien estratégico: decidir si utilizar un esquema distribuido o centralizado. Esta parece una decisión que no se puede posponer.

Entonces tiramos los riesgos o desventajas de cada uno de los esquemas (una especie de FODA, pero en este caso nos fijamos más en las desventajas, en concreto para buscar tácticas que nos permitan mitigarlas).

Del esquema centralizado vemos como desventajas o riesgos:

  • Disponibilidad, conectividad.
  • Performance.

Y decidimos:

  • Para ambos casos planteamos como táctica principal la opción de trabajar localmente cuando hubiera problemas de disponibilidad o de carga.
  • Que todo proceso masivo se corra fuera del horario pico, en particular hablamos del proceso de resincronizar estas operaciones locales.

Del esquema distribuido parece el mayor problema la posibilidad de fraude, tiramos algunas ideas pero como son justamente tácticas de seguridad quedamos en volver sobre eso a la clase siguiente.

De esa discusión llegamos a la conclusión de que necesitamos un sistema mixto, en principio hablamos de ir por un centralizado con la posiblidad de laburar localmente en caso de falta de conectividad o performance.

  • Una reflexión al pasar, si bien no se dijo en clase, me parece importante mencionar que el otro esquema que hablamos también era "mixto": distribuido con sincronizaciones… el esquema es parecido. La diferencia es cuál considero main y cuál alternativo.

Ahora sí, las tácticas

Una vez resuelto nuestro problema estratégico, ahora sí podemos meternos en las tácticas.

  • A1. Disponibilidad: A la posibilidad de operación local se suma la redundancia del server centralizado y de la conexión.
  • A2. Disponibilidad: En los puntos de venta. No recuerdo si lo mencionamos explícitamente. También iría por el lado de la operación local + redundancia (en este caso del server central, no tiene sentido tanto sentido para la conexión).
  • A3. y A4. Seguridad: Queda para la siguiente iteración.
  • A5. y A6. Performance: No dijimos mucho más que "cluster", también es una idea sobre la que se debería volver.

Un nuevo atributo

Durante esta charla aparecieron nos dimos cuenta que aparecían dos atributos nuevos que no habíamos explicitado en nuestra primera iteración:

  • A7: la carga o performance del sistema.
  • A8: (tal vez menos importante) la "usabilidad" en la interfaz para la compra de boletos, sobre eso también volveremos la próxima clase.

Lo que más me interesa destacar de esto es cómo no consideramos como "cerrados" nuestros documentos, sino que todo puede ser mejorable en cada iteración.

Paso 3 - Más atributos de calidad

Fue una charla cortita, pensamos un poco en los requerimientos de seguridad y usabilidad. Para evitar el fraude por parte de las empresas de colectivos y/o puntos de venta planteamos:

  • Prevención: Cada tarjeta tendrá una firma única que no pueda falsificarse, en toda transacción deberá adicionarse esta firma.
  • Prevención: Las máquinas de los colectivos y/o puntos de venta estarán sellados físicamente para impedir su adulteración y serán controlados periódicamente.
  • Detección: Los datos de cada transacción serán guardados en forma redundante (por triplicado en el servidor central, en la tarjeta, y en la máquina del colectivo o punto de venta según corresponda).
    • En caso de realizarse operaciones off-line, las mismas deberán ser informadas en forma batch por los sistemas en colectivos o puntos de venta.
    • En la siguiente oportunidad que la tarjeta se conecte al sistema se verificará su historial de transacciones con lo informado por otros sistemas.

Sobre usabilidad planteamos:

  • Que el sistema lo manipulen los conductores de colectivos y no los pasajeros, lo que nos permite pensar en un plan de capacitación.
  • El sistema debe permitir vender un boleto presionando un único botón, no sólo debe ser simple sino también muy rápido.
  • La interfaz del sistema debe ser lo más parecida posible a la operación que tienen actualmente los colectivos.
  • (Agrego ahora:) El boleto debe indicar la tarifa en forma bien visible, para permitir que el pasajero controle lo que le están cobrando.

Nos faltó hablar un poco más sobre las restricciones de arquitectura, apuntando a robustez y constructibilidad. Veremos de hacer eso la próxima clase.

Paso 4 - Robustez y constructibilidad. Estilos arquitectónicos.

Comenzando tirando algunos objetivos de robustez / constructibilidad, pero al charlar sobre eso nos dimos cuenta de dos nuevos requerimientos que no tenían que ver exactamente con estas restricciones:
- Es muy posible que haya que soportar múltiples tipos de tarjeta.
- Hay que ser capaz de actualizar el sistema frecuentemente, para eso se necesita seguramente automatizar de alguna manera esa distribución porque está instalado en muchos lugares.

Los requerimientos de robustez y constructibilidad que definimos son:

  • La arquitectura debe proveer un mecanismo único para la realizaciónd de validaciones de consistencia anti-fraude cada vez que una tarjeta entra en contacto con el sistem.
  • El diseño debe encapsular al resto del sistema de los detalles propios de la tarjeta a leer, de forma de poder manejar múltiples tipos de tarjeta en forma transparente.
  • Manejo de excepciones y transacciones en forma uniforme por parte de la arquitectura y transparente para el código de negocio.
  • Cifrado manejado por la arquitectura y transparente para el código de negocio.
  • La arquitectura debe proveer un mecanismo para garantizar que todos los usos del sistema han pasado por el control de autenticación y autorización que se defina.
  • La comunicación debe ser manejada por la arquitectura en forma transprarente para el código de negocio.

También agregamos un requerimiento de testeabilidad:

  • Se debe poder testear el sistema en el entorno de desarrollo / test emulando el entorno real sin necesidad de tener todo el hardware que se usaría en el entorno productivo.

Otras cosas para destacar:

  • Nos quedó pendiente pendiente revisar requerimientos para la ejecución distribuida y para testing.
  • Analizamos la idea de distribuir los servidores pero convenimos que no era ventajoso.
  • También estuvimos charlando sobre los patrones para lógica de negocio pero no llegamos a ninguna conclusión.

Casos de uso

Definimos estos casos de uso que nos fueron guiando para tomar decisiones.

Caso de Uso 1 (sistema)

  1. Ingreso tarifa
  2. Lectura de tarjeta
  3. Envío de datos al server
  4. Server: Autenticación, verificación de saldo, descontar saldo, confirmar transacción
  5. Actualizar la tarjeta con el nuevo saldo y otros datos.
  6. Imprimir ticket.

Caso de uso 2 (negocio)

  1. Venta de boleto offline: se registra la tarjeta y se registran los datos de la venta localmente.
  2. En modo batch se comunica la venta al servidor central.
  3. En el siguiente uso de la tarjeta se verifica la historia de la tarjeta contra el servidor central.

Primeros diagramas

En este diagrama se reflejan algunas de las cuestiones de estilos arquitectónicos que estuvimos charlando.
VistaLógica

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-Share Alike 2.5 License.