¿Hasta dónde debe cortar verticalmente?

Somos un pequeño equipo de 4 desarrolladores de software que intentan usar Scrum. Tenemos un gran proyecto para comenzar desde cero y nos hemos topado con un obstáculo con respecto a la división del proyecto.

El proyecto es un sistema distribuido con muchos componentes diferentes:

  • Base de datos del servidor SQL
  • Un par de servicios web que implementan OAuth 2.0 (que estamos implementando nosotros mismos)
  • Un servicio web de auditoría
  • Un servicio web FHIR (eventualmente)
  • Módulos del lado del servidor (ensamblajes .NET)
  • Una aplicación de página única (SPA) basada en JavaScript
  • Módulos basados ​​en JavaScript alojados dentro del SPA
  • Nuestro propio marco JavaScript interno para construir los módulos SPA

Nuestro primer PBI parece tan simple: un usuario puede iniciar sesión con su tarjeta inteligente.

El problema ahora es usar esta historia de usuario para cortar verticalmente, como recomiendan casi todos los consejos ágiles: ¿cortamos todo el sistema?

Si lo hacemos, parece que estamos mordiendo una cantidad monumental; necesitaríamos implementar todo el comportamiento de OAuth, incluida la verificación de permisos, la mayor parte del marco JS (manejo HTTP, plantilla y enlace de datos), los conceptos básicos del SPA y toda la estructura de la base de datos y la lógica SQL que se requieren solo para admitir esto.

Si vamos a ver cada PBI como una unidad entregable que proporciona valor al usuario, no parece haber una forma de desglosarlo.

He leído mucho sobre esto, pero todos los ejemplos se refieren a aplicaciones mucho más pequeñas y simples.

¿Estamos siendo demasiado rígidos con nuestra interpretación de Scrum?

Parece que su equipo descubrió que elegir incluir "Un usuario puede iniciar sesión con su tarjeta inteligente" como parte del Sprint Backlog en su primer Sprint sería una mala idea. ¡Eso es bueno! Así que no hagas eso.

Respuestas (3)

Lo vas a necesitar, pero no de inmediato.

Entonces, el objetivo de la división vertical es tomar algo como la base de datos y decir con precisión: "No necesito toda la base de datos en este momento". Así que validemos su afirmación: ¿necesita la base de datos?

Seamos claros sobre lo que hace una base de datos: distribuye los cambios de estado entre varios servidores y persiste esos cambios cuando el servidor se reinicia. Si desea una persistencia simple pero sin distribución, puede escribir en un archivo JSON local más o menos. Si desea distribución pero no persistencia, puede hacer que los nodos transmitan mensajes entre sí, por ejemplo, con ZeroMQ.

No veo nada en su primera historia de usuario sobre ningún número de servidores paralelos, y no estoy seguro de ver nada en su primera historia de usuario sobre persistencia; es posible que pueda tolerar el comportamiento predeterminado en la memoria de "cuando lanzamos una nueva versión del software, todos se desconectan y cualquier cambio que hayan realizado se restablece".

Así que no necesitas una base de datos. Es posible que necesite (si tiene una lista que asigna algunos tokens de tarjeta inteligente a algún tipo de nombre de usuario interno) algún archivo JSON estático (no está claro si debe comprometerse con el repositorio o simplemente un archivo de configuración distribuido por correo electrónico/Slack y copiado como el última parte de la inicialización; si no le importa que los datos se guarden en el repositorio, incluso se pueden guardar en uno de sus archivos fuente, sin necesidad de lectura de archivo/análisis JSON).

Del mismo modo, ¿necesita un gran Javascript SPA? No lo creo, es posible que necesite un lector de tarjetas o un formulario HTML dependiendo de si se trata de un token de hardware que muestra algunos dígitos o algo más interesante.

¿Necesita una estructura de permisos? No, el único permiso que cubre su historia de usuario es "puede iniciar sesión con un nombre de usuario y una tarjeta inteligente asociada con ese nombre de usuario" y ese es un permiso global.

Cuando corta verticalmente, reduce cada capa a solo el subconjunto de funcionalidad que necesita para que la historia de usuario funcione. No está tratando de entregar una vigésima parte de la base de datos y una vigésima parte de la estructura de permisos simplemente porque tiene veinte historias de usuario y está tratando de entregar una de ellas. A menudo puede encontrar que en las primeras fases varias de las capas están vacías.

Use la funcionalidad retrasada para obtener mejores requisitos comerciales

De hecho, deberías desear esto. Recomiendo encarecidamente que retrase la creación de la base de datos tanto como sea posible , lo que significa, hasta que tenga usuarios reales que se enojarán tanto por el tiempo de inactividad como porque sus cambios no se mantendrán durante los reinicios del servidor. Hay una razón muy importante para esto: el diseño de arriba hacia abajo suele ser miope. Desea poder antes de eliminar su libertad de jugar con las estructuras de datos para que un usuario real juegue con la lógica comercial de su herramienta y le diga algo como esto:

"¡Oh, no! Está asumiendo que cada orden de compra tiene un contrato, pero eso no es correcto, en realidad tenemos prototipos que son experimentos para tratar de obtener un contrato... Registramos órdenes de compra contra ellos para construirlos, pero no son parte de ningún contrato".

“Sí, eso no era parte de nuestra especificación original. ¿Tiene un término común que abarque tanto los prototipos como los contratos para que pueda mostrarle una lista de _____ y ​​luego una columna que diga "tipo=prototipo" frente a "tipo=contrato"? ¿Cómo se llamaría esa lista?

“Oh, sí, simplemente los llamamos proyectos a todos”.

Y luego reescribe su estructura de datos internos para que las órdenes de compra pertenezcan a un proyecto, que podría tener type=Prototypeo type=Contract, a menos que obtenga suficientes diferencias entre ellos como para necesitar una tabla de Prototipo y una tabla de Contrato que tengan una clave externa para el Proyecto.

El punto es que si no retrasa la creación de la base de datos hasta que reciba estos comentarios, bajo presión comenzará a obtener una base de datos muy verrugosa:

“Uh, ¿por qué estos contratos tienen todos estos valores nulos? ¿ Olvidamos hacerlos NOT NULL?

"Tal vez. ¿Tienen un número para su prototype_id?

"Sí..."

“Bueno, veamos que lo que la base de datos llama contrato es en realidad lo que la interfaz de usuario llama proyecto, porque cuando empezamos pensamos que todos los proyectos eran contratos, pero no lo son, algunos son prototipos. Entonces, todas las columnas del contrato deben ser nulas y prototype_idno deben ser nulas o las necesidades prototype_idno deben ser nulas y las columnas del contrato deben ser nulas ".

Las personas piensan mejor cuando pueden interactuar con un sistema. Especialmente las personas que te están dando requisitos. El punto de Agile es que el diseño de software tradicional es como pedirle a un comité que no sabe nada sobre ropa que escriba una especificación sobre qué tipo de ropa quieren usar y luego produciremos esa ropa exactamente según esa especificación y luego si son descontentos con la forma en que les quedan, son libres de no usarlos o de producir documentos de seguimiento anticipando cómo cambian. Un taller Agile está tratando de producir un conjunto de sucesivas aproximaciones personalizadas que en todo momento se ajustan exactamente al cliente pero no se ven bien. Así que comienzan con “bien, te tiraremos una sábana por la cabeza” y reciben la respuesta “Está bien, pero no puedo ver a través de la sábana y además es del color incorrecto para lo que busco. ” Hoja nueva en mejor color con un agujero. "No, necesita mangas y una capucha". Etcétera.

Puede retrasar deliberadamente obtener partes importantes de la funcionalidad correctamente, porque podría estar malinterpretando algo como el "color" que requiere una cantidad considerable de reelaboración desde cero. Esto sucede todo el tiempo con estructuras de base de datos.

Gracias por tu respuesta. Digamos que inicialmente no implementamos el marco SPA y JS, ¿en qué momento los implementamos? Al usuario no le importa, pero a nosotros, como desarrolladores, nos gustaría mucho un marco para acelerar el desarrollo de la interfaz de usuario.
@Lee: los implementa cuando alguna parte interesada (podrían ser los desarrolladores) comienza a exigirlo. Si le pregunta a un usuario final, es posible que ni siquiera quiera todo ese asunto de inicio de sesión/permiso.
@Lee Lo que dijo Bart. Tenga en cuenta también que los desarrolladores pueden hacer mucho con las UI que no son SPA, por ejemplo, una lista compartida de solicitudes de Postman a la que todos pueden volver.

Cuando tiene un sistema distribuido con muchos componentes, puede encontrarse con este tipo de problema. Descubrí que un buen punto de partida es la idea de la habilitación técnica. Tiene una expresión de nivel superior de una necesidad, pero puede crear otros elementos de la cartera de productos que pueden habilitar eso. Cada uno debe poder diseñarse, construirse, probarse y entregarse de forma independiente. Quizás, por sí solos, no satisfacen la necesidad del usuario final, pero te permiten planificar el trabajo y asegurarte de que tienes lo que necesitas.

Se vuelve aún mejor si estas piezas de trabajo de habilitación técnica pueden desbloquear varios elementos diferentes de la cartera de productos de cara al usuario. Dependiendo de cuáles sean los diversos Elementos de la Lista de Producto, es posible que pueda encontrar formas creativas de dividir la habilitación técnica en ciertos componentes ("de nivel inferior") para habilitar una franja de Elementos de la Lista de Producto mientras se asegura de que tengan un tamaño y alcance razonables. y entregable.

Dependiendo de las herramientas que esté utilizando para administrar su Product Backlog, es posible que pueda establecer relaciones y vínculos entre el trabajo para identificar que un elemento de habilitación técnica "bloquea" otro trabajo o establece dependencias de manera adecuada. Esto puede ayudar a planificar y programar el trabajo, asegurándose de que todo lo requerido se haga y se entregue cuando sea necesario.

La respuesta corta es: no, no lo cortes todo a menos que lo que estás haciendo realmente lo atraviese todo, entonces mantenlo en un alcance limitado.

La idea de la división vertical era alejarse de elementos pendientes como "Diseñar tablas de bases de datos para clientes". Si está utilizando elementos de la cartera de pedidos que brindan valor desde la perspectiva del cliente y solo toca algunos de ellos, está bien.

Además, comience con arquitecturas simples. Es casi seguro que no necesita todas esas cosas para respaldar sus primeros elementos pendientes. Frecuentemente me sorprende cuán avanzado en un proyecto de software puedo entregar valor sin cosas como una base de datos. Si construimos la aplicación para que sea un código débilmente acoplado o, mejor aún, un código altamente desacoplado, agregar componentes adicionales más adelante cuando los necesitemos no es demasiado trabajo.