Objetivo 2: Comienzo de la implementación del proyecto

Descripción

Se trata de entender el paso de historias de usuario al diseño inicial de una clase o clases en nuestro programa.

Prerrequisitos

Se tendrá que haber avanzado en el objetivo 1 antes de poder entregar este.

TL;DR

Tras elegir el lenguaje de programación que se va a usar, se creará un módulo o módulos que compilen, aunque no pueden tener todavía ninguna funcionalidad. Estos módulos tendrán que usar las estructuras de datos más adecuadas para resolver el problema, así como el interfaz de la clase o de la estructura de datos que mejor permita implementar las historias de usuario existentes, evidentemente avanzando las historias de usuario que se hayan creado en el primer hito en la secuencia.

Explicación

El convertir los deseos de los clientes en una realidad informática implica una serie de decisiones técnicas, y en principio no tiene nada de trivial. En entornos de desarrollo ágil hay que tener en cuenta no sólo los requisitos (historias de usuario) que se conozcan en ese momento, sino también posibles cambios que pueda haber en el futuro.

En desarrollo ágil, también, se va a separar lo más posible la lógica de negocio (lo que efectivamente hace la aplicación) de su implementación completa (cómo va a aparecer al público, cómo va interaccionar con el sistema). El hacerlo así permite asegurarse de que esta lógica de negocio cumpla todos los requisitos (que están expresados en historias de usuario), y que se pueda adaptar a diferentes entornos según evolucione la aplicación.

En todo caso, hay que pasar de una historia de usuario al diseño general de algunas de las clases (o módulos) que van a intervenir en una aplicación. La metodología más aceptada se denomina Domain Driven Design, y consiste en identificar las entidades (clases que van a incluir lógica de negocio, y van a ser capaces de gestionar otras clases, así como almacenamiento y otros objetos) y objetos valor (objetos inmutables cuyo ciclo de vida va a estar controlado por objetos de otras clases).

Diferentes conceptos a tener en cuenta:

  1. Interfaz vs clase. Un interfaz tiene sólo el API. Algunos lenguajes, como Java o TypeScript, permiten crear interfaces que se tendrán que implementar en una clase concreta, sin tener ninguna lógica de negocio.
  2. Mutabilidad frente a inmutabilidad: una clase inmutable no permitirá cambiar de valor tras su creación. A veces se denominan “congeladas” (frozen) o dataclasses (ya que, esencialmente, son datos, o sea, objetos que contienen sólo un valor). En ocasiones se consigue la inmutabilidad simplemente no permitiendo cambiar ningún atributo desde el API de la clase.
  3. En esta mutabilidad se tendrá que tener en cuenta el uso de variables de instancia privadas, así como sólo los getters (ningún setter). En general, conviene usar lenguajes que tengan en cuenta este tipo de distinción.
  4. Composición frente a herencia. La programación dirigida a objetos es muy rica, y mientras que algunos lenguajes permiten sólo herencia, otros permiten composición de roles o mixins (como Ruby o Raku).
  5. Tiempo de ejecución frente a tiempo de compilación: Es mejor trabajar con un lenguaje que permita comprobaciones de tipos en tiempo de compilación, sobre todo en funciones; eso ahorrará un montón de trabajo más adelante.

Los factores anteriores son comunes a casi todas las aplicaciones, y llevarían normalmente a la elección de un lenguaje que tenga comprobación de tipos en tiempo de ejecución, o tipado “fuerte” o tipado gradual. Este objetivo se cumplirá evidentemente cuando se elija un lenguaje, porque sin él no se puede crear los primeros interfaces o clases sin código (sólo declaración de métodos y funciones).

Finalmente, en el momento que vaya a haber algo de código se tiene que comenzar a seguir las mejores prácticas del lenguaje correspondiente, que incluirán una disposición de directorios determinada, forma de llamar los ficheros y las clases dentro de los ficheros, y así sucesivamente. Conviene antes de crear el fichero o ficheros informarse sobre el tema.

Sobre el trabajo con issues

Usar un repositorio de forma correcta no solo permite organizar el trabajo de desarrollo de forma más eficiente, sino que también contribuye a que sea más fácil colaborar con él y a la creación de buenos hábitos de trabajo colaborativo. Hay una serie de buenas prácticas, que incluyen las comentadas en el objetivo anterior, pero que además, en este objetivo, deberán de tener en cuenta lo siguiente.

soluciona #1 de la forma x

Estas buenas prácticas se tendrán que seguir en todos los objetivos subsiguientes del proyecto, empezando por este, y no hacerlo se indicará al estudiante para su mejora. También se testearán a la hora de hacer el envío.

Orden de trabajo en este objetivo

Este objetivo construye sobre el anterior. Se tienen que empezar a implementar las historias de usuario y avanzar hasta el primer hito, que podría ser perfectamente el resultado de este objetivo (ya que es una clase diseñada con todos los elementos que permitan implementarse luego). Así que

  1. Consultar el milestone e historias de usuarios asignadas, ordenadas (si lo ha hecho el autor) en un orden lógico.
  2. Tratar de crear issues “como programador” asignados a esas historias de usuario, también organizadas de forma lógica. Recordad que los issues son siempre problemas, no tareas o soluciones al mismo. Plantean un problema que se resolverá iterativamente en los comentarios al mismo y eventualmente en el código.
  3. Este issue tiene un porcentaje importante de solución de problemas, y un porcentaje muy inferior de programación. Es esencial entender bien el dominio problema tal como está descrito, y para ello se crearán una serie de issues que vayan disgregando el problema en sus diferentes componentes, planteando los retos que representa la implementación de cada uno de ellos. La identificación de palabras clave es fundamental para su conversión en estructuras de datos, porque será lo que más adelante (objetivo 4 probaremos; estas palabras clave incluirán tanto verbos (que indicarán las funciones que se quieren hacer) como adjetivos (que nos dirán cómo comparar lo obtenido con lo que desea el cliente) como sustantivos (esenciales en esta etapa, serán las estructuras de datos sobre las que se va a trabajar).
  4. Usar esas issues como una guía para diseñar las clases (o módulos, entidades en general). En este proceso se tendrá en cuenta la metodología de diseño dirigido por dominio, decidiendo qué será un objeto valor, qué una entidad que los incluya, qué los agregados. Es esencial que se entienda el problema y sus diferentes apartados antes de comenzar a escribir código, y así tenéis que reflejarlo en los issues que creéis.

Implícitamente, en este objetivo se seleccionará el lenguaje de programación; pero el hacerlo será también un issue en el que se discutirá la elección.

Importante: si en tres semanas la persona a la que se ha asignado el repositorio propio no hace nada, conviene ponerse en contacto con el profesor para asignar a otra persona.

El 50% de los estudiantes el año pasado tardó 23 días o menos en hacer la entrega. Si en este plazo no ha habido ningún contacto, es mejor solicitar un cambio para no bloquear el resto del desarrollo, especialmente si la persona que está bloqueada ya ha superado este objetivo.

Información adicional

Se pueden consultar los siguientes temas del curso 0:

Entrega de la práctica

Todo el material para este objetivo se tiene que desarrollar, como siempre, en una rama. Desde esta rama se hará un pull request a la rama principal del repositorio propio del estudiante. Importante: el título de este pull request *tiene que incluir la cadena [IV-22-23] para que puedan filtrar fácilmente los mensajes recibidos. Cuando se hagan mejoras en el PR, el estudiante deberá pedir explícitamente revisiones adicionales con un comentario en el mismo que diga “Listo para revisión”.

Como en este hito el trabajo se hace sobre un repositorio ajeno, esa persona tendrá que revisar el trabajo que se ha enviado en un PR y aceptar (no fusionar). Cuando se haga, se etiquetará a JJ en un comentario donde se diga que está listo para revisión.

A este fichero se subirá (mediante un PR desde una rama) el nombre del proyecto, el autor y un enlace al pull request creado en el repositorio.

A partir de este hito, habrá que especificar ficheros y otros parámetros de configuración para test en un fichero iv.yaml que estará en el directorio principal, escrito en formato YAML. Por ejemplo, este

entidad: camino/a/loquesea.raku

Las claves, tales como en este caso entidad, tendrán un valor que será lo que se examine y se usará en un test para ver si se ha llevado a cabo correctamente alguno de los elementos del hito requeridos. El formato YAML se usa extensivamente en DevOps, y se puede consultar sobre él, por ejemplo, en la Wikipedia. Se puede editar a mano (usando el modo correspondiente del editor o IDE) o, por supuesto, generarse usando alguna biblioteca o utilidad de línea de órdenes.

Como mínimo, y para pasar los tests, esta entrega incluirá, además de lo solicitado en las entregas anteriores:

lenguaje: node.js
entidad: src/Recordatorio.js

Lista de comprobación

Antes de proponer el material de este objetivo para revisión, hazte las siguientes preguntas y, si es posible, contéstalas. Esto debe ir en el cuerpo del PR que se haga en el repo correspondiente.

Sobre la estructura del repositorio

* [ ] ¿He seguido las mejores prácticas en el nombre de las clases y ficheros y
   disposición de los mismos?

Sobre el planteamiento

* [ ] ¿Se han planteado una serie de issues, asignados a las historias de
usuario pertinentes, que clarifiquen qué es lo que necesitan los usuarios e
identifiquen las diferentes partes del problema?
* [ ] ¿Los issues representan un problema, y no una tarea?

Sobre el análisis del problema

* [ ] ¿Se ha documentado qué análisis se ha hecho sobre el dominio para decir lo
   que se ha creado?
* [ ] ¿Se ha documentado por qué se ha elegido que lo creado sea un objeto valor,
   una entidad o un agregado?
* [ ] ¿He propuesto un producto mínimamente viable, que en muchos casos será un solo
   objeto valor que no dependa de ningún otro (y que sea la base de muchos
   otros)?.

Sobre la programación

* [ ] ¿Todos los mensajes de commit explican el cambio, y no se
      limitan a repetir el nombre del fichero que se ha cambiado?
* [ ] ¿Los mensajes de commit siguen el formato estándar y buenas prácticas?
* [ ] ¿Se ha hecho una revisión real del código para comprobar que todos
   los atributos y funciones creadas están respaldadas por una HU?
* [ ] ¿Todos los issues creados están asignados a una HU?
* [ ] ¿Ha asignado el propietario/la propietaria del repositorio todos los
issues planteados al *milestone* correspondiente?
* [ ] ¿Todos los cambios en el código están asignados a un issue al que se
      referencia en un commit? Los issues sobre los que estoy trabajando, ¿han
      sido asignados al primer milestone?
* [ ] ¿Se ha asignado al mismo milestone el PR que se ha hecho?
* [ ] ¿Son los milestones sobre los que estoy trabajando productos
   mínimamente viables? ¿O tengo que solicitar al product manager que
   cree milestones adicionales o precise de qué producto se trata?
* [ ] ¿Se ha comprobado que el código entregado sea sintácticamente
correcto?

Objetivo alcanzado

Los tests automáticos serán un requisito para poder entregar el material evaluable correspondiente a este objetivo, que estará superado si:

  1. Se ha organizado correctamente en el repositorio según las mejores prácticas del lenguaje de programación elegido.
  2. Se han creado una o varias entidades/objetos valor, en el lenguaje de programación elegido, que avancen hacia la implementación de las historias de usuario y el producto mínimamente viable del hito correspondiente.
  3. Los issues están correctamente encuadrados dentro de una HU y del primer hito (el cero), que es el que se está desarrollando ahora.
  4. Como en todos los objetivos, se debe responder a todas las objeciones que se hayan hecho en la corrección del mismo.

En todo caso, y como en todos los objetivos, se tendrá que esperar a que el profesor apruebe el PR en el repositorio del proyecto para considerarlo alcanzado.

Preguntas frecuentemente preguntadas

Estoy trabajando en un repositorio pero no contestan a mis preguntas.

Salvo que se trate de aclaraciones sobre el milestone en el que se enmarca el objetivo o aclaraciones de qué significan las historias de usuario, la persona sobre cuyo repositorio estás trabajando no tiene que contestar a ninguna pregunta. Sólo tiene que evaluar el trabajo que realices cuando hagas el pull request, aprobándolo u orientándolo para que cubra las necesidadesd de los usuarios. No tiene que contestar qué tenía pensado, porque eres quien tiene que plantear los diferentes problemas a partir de las historias de usuario, y comenzar a resolverlo. La modelización, y, en general, el desarrollo, no tiene más diálogo que el que hay sobre la calidad del código, y en ese contexto. Si quien haya creado el repo y las HUs tiene que contestar a cada pregunta sobre cómo hacer algo, acaba antes haciéndolo.

Valoración

El alcanzar este objetivo avanzará, en principio, 15% del apartado correspondiente de la asignatura.

Donde ir desde aquí

Si has terminado, comienza con el siguiente.