Printable Abril
Table of Contents

Planificación de fase

Table of Contents

Planificación de fase

Hitos principales:

  • Octubre: Definición del proyecto, requisitos, casos de uso, riesgos

Al terminar octubre tenemos una idea general de cómo será nuestra aplicación: funcionalidades básicas, planificación sobre cómo llevarla a cabo, límites de hardware, de dispositivos, etc. En definitiva, el ámbito general del proyecto.

  • Noviembre: Investigación principal de tecnologías

Habremos decidido qué lenguaje de programación utilizaremos, al menos para el núcleo del programa, así como las tecnologías de cada uno de los módulos del proyecto, o al menos varias opciones de implementación, para poder elegir más tarde con cual quedarse. Las tecnologías más importantes a investigar son: entorno gráfico que usaremos, tecnologías para el núcleo de copia de seguridad, de base de datos, y de comunicación interna y externa.

  • Diciembre: Prototipo Alpha (prueba de integración)

Se tendrá el núcleo de la aplicación, o al menos ciertos módulos para comenzar a integrar. De este modo tendremos el esqueleto de la arquitectura, con las principales tecnologías investigadas por completo e implementadas para más adelante continuar con funcionalidades menos críticas.

  • Enero: Fase de investigación; procedimiento de integración cerrado.

Subsiguiente prototipo de investigación de tecnologías (comunicación frontend / backend, planificación de tareas), si bien carente de la crítica de backup, restore, eliminación de copias, etc. Finalización del proceso de integración de bases de código distintas, quedando preparadas las metodologias para las fases de desarrollo posteriores.
Los principales riesgos tecnológicos están ya localizados. La arquitectura se ha desarrollado hasta quedar prácticamente cerrada, a falta de algunas apis importantes.

  • Febrero: Repaso de documentación e investigación sobre funcionalidades adicionales

Esta iteración se centrará en documentar los nuevos procesos desarrollados y completar la documentación existente, pero dada la falta de tiempo por los exámenes, se reduce la cantidad de tiempo para el proyecto, con lo que no se esperan grandes avances. Se dedica a la investigación también porque, en nuestra experiencia, los exámenes son época de trastear con las más extrañas tecnologías en los ratos muertos que se debieran aprovechar para estudiar.

  • Marzo: Prototipo Beta (funcionalidad crítica). Replanificación y reevaluación de viabilidad. Reasignación de personal.

Eliminados los riesgos tecnológicos, es necesario replantearse la planificación y la viabilidad de los casos de uso menos importantes para el tiempo existente. Se deberá concluir la construcción de la aplicación y sus funcionalidades críticas, con vistas a poder comenzar cuanto antes el mantenimiento y testeo de esta funcionalidad, que se preve largo; en los tres meses desde Enero la arquitectura está más que fijada y desarrollar debería ser previsible en tiempo y esfuerzo, al contar con prototipos funcionales de todas las tecnologías. Se tratará de avanzar en funcionalidad menos importante (al menos estudiando su viabilidad).
La semana santa dificultará la planificación, en función del personal y su disponibilidad por viajes, prácticas, etc.
Además, se debe tratar de completar lo más posible la documentación, en particular todos los tipos de diagramas UML utilizables en nuestro proyecto, así como identificar patrones de diseño tanto preexistentes en nuestro código pero no explicitados, como susceptibles de ser aplicados.

  • Abril: Beta 2 (funcionalidad decidida completa). Mantenimiento, pruebas de usabilidad con usuario real, optimización en general, pruebas de empaquetado para distribuir.

Completar la funcionalidad ausente en la anterior iteración. Asimismo, preparar el despliegue de la aplicación, y iniciar un proceso de prueba intensiva, lo más automatizada que sea posible y razonable; consumido el margen de tiempo, se debe tratar de testear lo más posible durante el desarrollo de la aplicación -y no exclusivamente en Abril- para conseguir la máxima fiabilidad del programa, lo que es importante para su éxito.

  • Mayo: Release: Empaquetar, y preparar la entrega (diapositivas, vídeo, web, presentación…). Mejorar la calidad todo lo que de tiempo (que será poco por la proximidad de los exámenes).

Perfil de personal

Adri

Administrador de sistemas y hábil en general. Autogestionado. Encargado de la gestión de sistemas del infierno, si se lo propone. Si es fácil, no es para él… C++ -er. Analista en general. Entusiasta donde los haya. Sincero ;). Buen gestor de personal; manejo del látigo eficaz, en particular del de 9 colas, lo que le convierte en el jefe de release ideal.

Carlos

Programador por encargo. Viciado en general. Viajero incansable.

Daniel

Primera baja del proyecto. M.I.A.

David

Databaser. Autogestionado. Programador por encargo bastante rápido; trabaja bajo presión. Asiduo del copy-paste (algo dadaista).

Diana

Analiza tus frases y suelta verdades como puños. Gran consejera. Programadora por encargo.

Eze

Gestor de todo lo gestionable. Maestro en tecnologías varias habidas y por haber. Hijo del bleeding edge (si funciona, actualiza). Capitán diccionario. Analista en general. Arquitecto (le falta la barba blanca solo). Entusiasta pero muy limitado en tiempo.

Fede

Líder nato y relaciones públicas. GNU master. Analista en general. Mejora la moral de la tropa. Hospitalario ^^. Hermano de Eze (por aquello de que también es hijo del bleeding edge). Fuente incansable de ideas a añadir a la apretada agenda.

Jorge

Autogestionado. Programador altamente competente. Tú fast, tú furious.

Mario

Redacta diversos tipos de documentos, observando escrupulosamente las reglas de redacción y ortografía (teniente diccionario, digamos). Programador por encargo. Relajado (paz, hermano).

Rober

Programador por encargo. Mejora notablemente la moral de la tropa. Formateador de cerebros. Currante nato.

Salva

Analista en general. Lead developer estilo ninja (no hace ruido, nadie le ve, pero aparecen sus líneas de código de repente). Master (del universo, digamos). Competente como programador. Entusiasta del proyecto, pero limitado en tiempo. Altamente experimentado. En ocasiones desvaría y hay que meterle en cintura ;) (por ejemplo, con el citado látigo de 9 colas).

Tabas

Programador por encargo. Dbusman y showman en general. Caja de sorprrresas.

Carmen

El nuevo fichaje. Programadora por encargo. Escritora hipermaniática. Friki en sus ratos libres (el resto lo es a tiempo completo)


Planificación iteración Mayo

Tipo de iteración

Elaboración / Transición


Objetivos generales

Dado que nos acercamos ya al final del curso y el tiempo disponible por parte de todos se reducirá bastante para poder estudiar y trabajar en el proyecto, nos planteamos que será poco el desarrollo adicional que podamos hacer, y crearía demasiados riesgos sobre un aspecto tan crítico para nuestro proyecto como la robustez de la aplicación. Por tanto optamos por pulir lo más posible lo que tenemos, preparándonos para un hipotético mantenimiento, y preparando la también importante presentación y la documentación, tanto de cara a la entrega como a preparar entre todos el examen.

Sin menoscabo de esto, es posible que hacia la mitad de la iteración se escinda un pequeño grupo de "fuerzas especiales", como se les denominaba en las charlas de representantes de grupos de otros años, para intentar desarrollar alguna feature extra.

Por tanto, hemos decidido congelar el código y dedicar 2 semanas a documentación y calidad. Una vez finalizadas, nos escindiremos en grupos de presentación, bugfix, features y calidad, probablemente con solapamiento de responsabilidades por nuestro escaso número. Esto lo decidiremos a mitad de iteración, y en función de la disponibilidad prevista del personal.

Calidad y documentación
  • Revisión de calidad del código: Se planifica que cada uno revise el código en el que ha estado trabajando (ya que es la persona mejor cualificada para reescribirlo) y además otra sección adicional, de modo que todo sea revisado por al menos dos personas.
  • Cambiar los términos snapshot y backup por versión en toda la aplicación.
  • Preparar la presentación para la entrega final.
  • UML: patrones presentes en nuestro código
  • Despliegue de la aplicación definitivo y documentación del mismo.
  • Actualizar riesgos.
  • Centralizar apuntes de cara al estudio de la asignatura.
Features
  • Asistente inicial de la aplicación.
  • Porcentajes y estimaciones de tiempo en la aplicación para proporcionar feedback.
  • Ordenar por columnas la lista de snapshots.
  • Caducar -> Exportar a CD
  • Mover el directorio del backup finalizado.
  • Empaquetado definitivo de la aplicación (instalador, etc).
  • Precacheo del árbol en el GUI para mayor eficiencia.
  • Refactor watcher: hacerlo independiente de inotify.

Reparto de trabajo

Revisión de calidad
  • Salva - GUI + apuntes junto a Eze.
  • Jorge - GUI
  • Fede - Watcher
  • Rober - Watcher
  • Mario - snapshot-manager
  • Tabas - snapshot-manager
  • Adri - base de datos
  • David - Cron
  • Carlos - consola
  • Diana - hará una revisión general siguiendo el UML
  • Carmen - hará una revisión general siguiendo el UML
  • Eze - la documentación
Features
  • Wizard - Carlos
  • Porcentajes - Tabas y Fede
  • Ordenar por columnas - Carlos y Rober
  • Centralizar apuntes - Eze, Salva
  • Caducar -> Exportar a CD - Salva y Fede (Si da tiempo)
  • Mover el directorio del backup - Adri
  • Empaquetado - Eze
  • Precacheo del arbol en el GUI - Tabas
  • Refactor watcher: hacerlo independiente de inotify

Estimaciones de tiempo

  • 9 de mayo: Primera entrega.
  • 19 de mayo: Nueva organización para preparar la entrega final. Empaquetado listo. Congelado final de código salvo grupo de "fuerzas especiales".
  • 22 de mayo: Última entrega antes de la final.
  • finales de mayo / principios de Junio: Reunión un día común para preparar el examen.

Seguimiento

Ver seguimiento-mayo


Seguimiento Abril

Objetivos cumplidos

Hemos conseguido un seguimiento más individualizado de objetivos para tener más información sobre el rendimiento del personal. Además, el bugtracker ha sido de gran ayuda para dejar constancia de los fallos que íbamos encontrando y asignarles responsables de mejora, así como para seguir su progreso. En general hemos seguido avanzando en el desarrollo de la aplicación (con features importantes como el borrado de versiones y mover el directorio de backups), solucionando casi todos los problemas de rendimiento que teníamos presente.

El trabajo individual en el código de cada uno ha sido:

  • Carlos:
    • Bugfix treeview: al borrar un archivo, aparecía un icono de carpeta. Se ha cambiado y aparece un icono de salvado en disco (16/04/08).
    • Bugfix treeview: que no se comprima cuando se refresca la ventana (19/04/08).
    • Pop ups informativos (con Tabas) (20/04/08)
    • Bugfix treeview: mantener la selección cuando refresca (21/04/08).
    • Bugfix treeview: orden de las carpetas y archivos (23/04/08).
  • Robs:
    • Ventana porcentajes iniciada.
    • Ventana preferencias: cambio botones (09/04/08).
    • Añadir licencia y copyright en la ayuda (11/04/08).
    • Implementar la ayuda (con Diana) (23/04/08).
    • Testing: consola (23/04/08).
    • Cuestionario(s) para las pruebas (24/04/08 y 09/05/08).
  • Mario:
    • Consola.
  • Fede:
    • Añadidos dos campos en la base de datos (junto con Salva) (01/04/08).
    • Borrar snapshots (junto con Salva) (15/04/08).
    • Redefinido el concepto de "snapshot" por "versión" (17/04/08).
    • Bugfix: cambiada la ruta de las carpetas (no era lo bastante informativa) (18/04/08)
  • Diana:
    • Investigacion de los paquetes de traducción al español (20/04/08)
    • Implementación de la ayuda (con Robs) (23/04/08)
  • David:
    • Mantenimiento de la base de datos (todo el mes).
    • Investigación: Pylint para calidad del código (18/04/08).
    • Puesta en orden de las licencias en el código de la aplicación (22/04/08).
  • Jorge:
    • Expresiones regulares: patrones de exclusión (16/04/08).
    • Refactor del watcher (en progreso).
    • Mover el directorio de backups en progreso junto con Adrián.
  • Salva:
    • Añadidos dos campos en la base de datos (junto con Fede) (01/04/08)
    • Borrar snapshots (junto con Fede) (15/04/08).
  • Tabas:
    • Status bar (18/04/08).
    • Bugfix: Ventana de debug (18/04/08).
    • Drag and drop (de fuera a dentro) (10/04/08).
    • Bugfix: funciones D-Bus para la consola (07/04/08).
    • Boton derecho systray (07/04/08).
    • Selección múltiple para borrar varias versiones ("snapshots") y para restore (19/04/08)
    • Boton derecho (19/04/08) NOTA: Esto necesita mas aclaración.
    • Pop ups informativos (con Carlos) (20/04/08)
    • Investigación: threads y D-Bus.
  • Carmen:
    • Documentación: Revisión (11/04/08 - aprox).
    • Revisión de la planificación (work in progress).
    • Subir bugs (work in progress).
  • Adri:
    • Base de datos (thread safe, backoff, sanitizing inputs…) (20/04/08).
    • Gestión del bugtracker (durante todo el mes) y de releases.
    • Bugfix: varios (durante todo el mes).
  • Ezequiel:
    • Documentacion: Meter tutoriales en el printable (22/04/08)
    • Investigacion: imagen de QEmu para probar el despliegue sobre virtualización (25/04/08).
    • Documentación: Revisión en progreso.
    • Documentación: evaluación del Software Capability Model.
Objetivos no alcanzados.

En general, hemos gozado de menos tiempo del deseable para dedicarle al proyecto debido a entregas para otras asignaturas. Por tanto, no hemos tenido tiempo de investigar la sincronización con discos externos, y no creemos que sea factible realizarlo en condiciones dado que en adelante gozaremos de menos tiempo aún.

  • Mario: Testing: consola
  • Robs: Ventana de porcentajes.
  • Diana: UML - Tareas en cola:
    • Ayudar con la revisión del wiki: actualizar la arquitectura (poner nuevos pantallazos de UML).
  • David: Traducción. Informe de Pylint. - Tareas en cola:
    • Ayudar a Diana con el UML.
    • Documentación:
      • Revisión de los cambios hechos a la planificación de fase (con la historia de revisiones de la página).
      • Actualizar las tablas de riesgos iniciales con los que han ido apareciendo en todos los seguimientos (tanto los nuevos, como los que se han acabado por confirmar y demás).
  • Carmen: Planificación: Seguimiento de fechas: contabilizar si se han cumplido plazos y explicitar qué no se ha cumplido y por qué en el seguimiento de abril.
    • Investigación: IDE Eric para depuración y generación automática del UML.
    • Documentación: revisión del wiki (encontrar erratas e inconsistencias en la documentación).
    • Calidad: leer el código
  • Ezequiel:
    • Calidad: finalizar la documentación.
    • Software: investigar las versiones y el empaquetado.
    • Documentación: Documento de despliegue.
    • Documentación: Documentación de proceso del wiki.
  • Fede: Refactoring
  • Salva: Refactoring
  • Jorge: Refactor en Watcher.
Riesgos reducidos
  • Mantenimiento: merced al trabajo en progreso de refactorización y mejora general de la calidad del código, la aplicación será mucho más legible y mantenible.
Nuevos riesgos
  • Problemas con empaquetado se vuelven críticos.
  • Bugs que aparezcan en el software de cierta importancia se vuelven más críticos también, ya que queda poco tiempo para arreglarlos.
  • Que la aplicación se nos queda corta respecto a lo planeado es ya un hecho.
Tiempo real empleado

Todo el mundo hemos dedicado bastante tiempo a la asignatura, pero conforme avanzan las fechas han ido apareciendo entregas -con cuya dificultad no contábamos correctamente- para otras asignaturas que nos han privado de mucho tiempo que hubiera hecho falta para alcanzar plenamente los objetivos planteados para esta iteración, y limitarán notablemente el alcance de la siguiente y última.

Conclusiones

La iteración ha cundido menos de lo deseable, un riesgo previsto, y por tanto nos vemos obligados a reducir más las features que estarán en la entrega final de lo que quisiéramos. Sin embargo el proceso está ya bastante pulido, al haber incorporado el bugtracker y el director de releases (Adrian), y por tanto cualquier desarrollo extra que nos de tiempo a hacer será de alta productividad (al ya tener toda la arquitectura fijada, el proceso de control de configuración y de integración de bases de código, etc), lo que nos permitirá desarrollos intensivos de última hora de considerarlo conveniente.


Releases

Entrega 24/04/2008

Resumen

Esta tercera entrega ha resultado de gran utilidad aunque no se hayan recogido tantas encuestas como en la anterior, ya que nos muestra qué debemos corregir con gran exactitud y qué debemos incorporar para que sea mas fácil de usar. También notamos algo de mejoría en algunos aspectos de la encuesta.

Información
  • Entregada mediante VNC.
  • Número de encuestas recibidas: 17.
Interfaz Gráfica
  1. ¿Es fácil de usar?:
    Nota media aproximada: entre 7 y 8.
  2. Diseño:
    1. Orden de los menús:
      Nota media aproximada: 7 y 8
      Observaciones: Los usuarios permanecen en desacuerdo sobre el orden de los botones, prefieren eliminar al final y hacer versión al principio.
      # Estilo de los menús/botones:
      Nota media aproximada: 8
      # Claridad de la vista en árbol:
      Nota media aproximada: entre 7 y 8
      # Icono de la aplicación:
      Se repiten los comentarios de la anterior encuesta: se ve poco o mal aunque tiene buena acogida.
    2. Tipos de iconos (del sistema o propios):
      No se ponen de acuerdo y hay opiniones para todos los gustos, aunque los iconos del sistema no desagradan.
  3. ¿Es completa o queda funcionalidad por cubrir?:
    Nota media aproximada: entre 7 y 8 .
    Ahora parece que la gente entiende que la funcionalidad se acerca más a lo que esperan.
  4. ¿La vista de los archivos es clara?:
    Nota media aproximada: entre 7 y 8
  5. ¿Son suficientes los datos mostrados acerca de cada archivo?:
    Nota media aproximada: 8
    Observaciones: Aún queda gente que piensa que la información es insuficiente.
  6. Buscar la versión de un fichero:
    En general encuentran bien la versión del archivo que buscan pero siguen demandando un sistema de búsqueda.
  7. ¿Poner descripción sobre la versión?:
    Siguen opinando que sería útil si la descripción la introdujera el usuario.
  8. ¿Se podrían usar etiquetas en lugar de descripciones?:
    División de opiniones, algunos creen que es incompatible con las descripción mientras que otro piensas que ambas opciones vendrían bien.
  9. En el treeview ¿deben aparecer solo los archivos versionados o el árbol de directorios completo?:
    Las respuestas siguen siendo diferentes, como en la anterior encuesta.
  10. ¿Uso de botón derecho para añadir un archivo a la vigilancia?:
    Esta opción sigue recibiendo un gran apoyo.
  11. Uso del botón derecho:
    En general ha gustado mucho que haciendo click con el botón derecho se puede ordenar una eliminación, restauración o nueva versión de un archivo o una carpeta.
  12. ¿Idioma (Ingles/Castellano/el del sistema)?:
    Como en la encuesta anterior muchos indican que lo prefieren en castellano, aunque también señalan que lo adecuado es que esté en el idioma del sistema.
  13. ¿La ayuda es completa?:
    En general opinan que sí, pero casi todos señalan que se podría completar un poco más.
Funcionalidad
  1. ¿Exportar?
    Los encuestados siguen viendo muy útil que la aplicación de la opción de exportar a un dispositivo externo.
Consola

La ayuda de la consola ha gustado aunque alguno indica que es demasiado densa. En cuanto a la funcionalidad encuentran útil poder borrar todas las versiones de un archivo en un intervalo de fechas dado, o indicar varias fechas.


Entrega 09/05/2008

Resumen

La cuarta entrega no ha resultado de mucha utilidad debido al escaso número de encuestas que hemos recibido de la gente que lo ha probado, pero aún así nos sirve para saber si hemos ido por el camino correcto.

Información
  • Entregada mediante sesión remota.
  • Número de encuestas recibidas: 4.
Interfaz Gráfica
  1. ¿Crees que esta mejor que en anteriores entregas? ¿Cuánto mejor?:
    Coinciden en que está mejor aunque varían en la cantidad de mejoría. Obtenemos un 7 de media.
  2. ¿Qué te parece la traducción? Comenta los fallos que encuentres:
    En general están contentos con que la aplicación esté en castellano.
    Observaciones: ¿Que sería mas correcto: "Guardar versión actual" o "Guardar estado actual"?
  3. ¿Te parece intuitiva la nueva nomenclatura?:
    Todos coinciden en que es más fácil hablar de versiones que de backups o snapshots.
  4. ¿Notas un mejor rendimiento?:
    Mas o menos notan que ha mejorado algo pero no saben decir qué exactamente.
  5. ¿Te parece mas informativa la lista de versiones? ¿La información es mas clara?:
    En esta pregunta discrepan, unos encuentran información útil y otros no saben que significa exactamente o no se acuerdan de que había antes.
  6. ¿Echas en falta alguna opción desde el interfaz?:
    Solo una persona indica que se debería poder crear archivos y carpetas desde la aplicación.
  7. ¿Poner descripción sobre la versión?:
    Una amplia mayoría piensa que sí.
  8. ¿Resulta útil la información que muestran los globitos? ¿Molestan demasiado?:
    En general la consideran útil y que no molesta demasiado. Ello confirma la usabilidad de esta característica
  9. ¿Tal y como esta el proyecto lo usarías?:
    3 de los encuestados dicen que sí, un 75%.
Consola

Coinciden en que es buena idea tener algo distinto a la GUI aunque se usaría poco. También comentan que estaría bien que estuviera en castellano.

Otras observaciones en la encuesta

En la ventana de preferencias comentan que el botón aplicar debería aparecer desactivado y que se debería activar cuando se realice algún cambio.


Evaluación del Software Capability Maturity Model

Introducción

El Capability Maturity Model es un modelo de la madurez de los procesos de una organización, para evaluar las capacidades efectivas de desarrollo que tendrá dicha organización y poder predecir con mayor precisión sus éxitos en futuros desarrollos, mejorando al tiempo los puntos débiles de dichos procesos. Aunque ha sido sustituido recientemente por el Capability Maturity Model Integration, por estar muy extendido y sernos requerido haremos el estudio de nuestra organización respecto al original.

Referencia: apuntes de la asignatura, y wikipedia.


Nivel 1

Objetivos

Los procesos en el nivel 1, el punto de partida, están generalmente indocumentados y son implícitos, o bien no se siguen por parte del personal por desconocimiento u otras razones. Aunque es posible el desarrollo exitoso de proyectos, nada garantiza futuros éxitos.


Nivel 2: repetible

Objetivos

La base del nivel 2 del Software Capability Maturity Model, el cual debemos alcanzar necesariamente como requisito del curso, es que el proceso sea repetible, esto es: que el proceso seguido de creación del producto o proyecto permita generar futuros productos de un modo similar, convirtiendo su resultado en algo repetible y no fruto de la casualidad.

Aunque en el nivel 2 la disciplina de procesos pueda no ser rigurosa, se intenta seguir los procesos existentes siempre, incluso en situaciones de presión (entregas, exámenes, etc).

Es importante reseñar que en este nivel aún hay un importante riesgo de exceder las estimaciones de coste y de tiempo en futuros proyectos, al no existir revisiones de los procesos que los mejoren (y a las estimaciones).

Áreas clave de proceso

Gestión de requisitos
  1. Tenemos requisitos y especificación de lo que queremos, para saber hacia dónde orientamos el desarrollo y el trabajo que queda.
  2. Los planes, productos y actividades se mantienen consistente con esa especificación, aunque nos falta un proceso más definido de revisión (que no se requiere para nivel 2).
Planificación de proyecto
  1. Las estimaciones están documentadas y son reales. Se basan en alcanzar un compromiso entre estimaciones bottom-up (lo que los desarrolladores estiman que van a poder hacer, dados sus compromisos) y top-down (lo que consideramos imprescindible de la aplicación que debe estar en cualquier caso), y de momento funcionan con bastante exactitud, habiéndonos mantenido fieles al plan de fase y a la estimación de alcance durante las últimas iteraciones.
  2. Las planificaciones donde se detallan los compromisos del personal están documentadas en los planes de iteración y fase.
  3. El personal se lee los planes y está al corriente de los mismos. Es debido a que la planificación la realizamos siempre con el máximo número posible de miembros del personal, avisando además por lista de correos cuando se actualiza para que la gente sea consciente de sus obligaciones y planificaciones para el siguiente mes, por ejemplo si no pudieron estar presentes en la planificación.
Seguimiento de proyecto
  1. El seguimiento se contrasta con las planificaciones anteriores al realizar la siguiente, imprescindible para saber qué queda por hacer de lo que debiera estar hecho, además de para permitirnos estimar mejor los tiempos de desarrollo.
  2. Se toman acciones correctivas; al hacer los nuevos planes de iteración se tiene en cuenta qué ha fallado y por qué, y de ser necesario (complejidad inesperada, problemas de personal, etc) se replanifica.
  3. Si hay cambios en las responsabilidades, son de mutuo acuerdo por todo el mundo y por las partes. Es debido a que somos todos conscientes de que somos un grupo reducido de personal, y no hay otro modo de sacar el proyecto adelante.
Subcontratas

No aplicable para nuestro caso.

  1. El contratista elige subcontratas cualificadas.
  2. Ambos están de acuerdo con sus compromisos.
  3. Mantienen comunicación.
  4. El contratista comprueba si la subcontrata cumple los compromisos adquiridos.
Garantías de calidad
  1. Hay planificadas actividades de control de calidad desde las últimas iteraciones, así como procesos automáticos de revisión de la misma mediante pylint.
  2. Se verifica objetivamente que todo cumple los estándares, procedimientos y requisitos desde las últimas iteraciones (centradas en esto mismo).
  3. Los individuos afectados son informados de las actividades de calidad y los resultados. Cuando se detectan problemas de calidad se advierten al responsable, y además hay responsables definidos de cada área.
  4. Cuando se falla algo en calidad y no se sabe resolver se decide desde arriba qué hacer. Contamos con cierta jerarquía y proceso de decisión, aunque algo horizontal, que nos funciona por el escaso número de jefes que tenemos.
SCM (Gestión de configuración de software)

Se entiende por configuración de proyecto al conjunto de documentos y material relativo al proyecto en un momento (especificación, diseño, código y pruebas); la gestión de dicha configuración se refiere por tanto al mecanismo de control de cambios (sea de requisitos, de documentación, de código, etc).

  1. Hay. Existe control de código y de su migración entre versiones más o menos inestables (parecido a los baselines). Hay baselines, responsable de releases y de su mantenimiento, y un proceso de testeo manual para decidir cuándo establecemos un nuevo baseline (generalmente, tras la entrega de un baseline y los últimos bugfixes para dejarlo realmente estable).
  2. Existen versiones del software más o menos establecidas, una por release, que pueden obtenerse individualmente.
  3. Los cambios al software están controlados. En nuestro caso, solo están controlados los de código y documentación con control de versiones, no los de arquitectura (pero estos últimos no han sido necesarios, y pueden considerarse como parte de la documentación).
  4. Los grupos afectados están informados del estado y el contenido de los baselines. Antes de cada release se deja claro qué pretendemos que esté, y mientras trabajamos sobre ella mantenemos información sobre el estado de la misma para saber qué problemas son responsabilidad de cada quién.

Nivel 3: definido

Objetivos

En este nivel el proceso de desarrollo no solo es repetible sino que está claramente definido y establecido, y es susceptible de mejorar. Los procesos existentes se usan para conseguir consistencia, y se personalizan para cada proyecto (en nuestro caso, el modelo de desarrollo seguido sería válido para cualquier otro proyecto solo cambiando temas de grupos concretos encargados de subsistemas).

Áreas clave de proceso

Foco del proceso
  1. El desarrollo del proceso y sus mejoras subsiguientes están coordinadas a través del grupo. Aunque el proceso de mejora de procesos sea algo informal y que responda a cómo observamos, algo intuitivamente y poco cuantitativamente, que se comporta el mismo. Los procesos se discuten entre varias personas siempre, y se descartan cuando no son efectivos para el proyecto para poder agilizar nuestro desarrollo.
  2. Identificar ventajas / inconvenientes de cada proceso es algo que ya hacemos por tanto.
  3. Si bien gozamos de poco tiempo, se planifican mejoras del proceso a cada iteración conforme se detectan aspectos que pueden optimizarse en el mismo, o nuevas necesidades que cubra un nuevo proceso.
Definición de procesos
  1. Existe un proceso de desarrollo y se mantiene según detectamos problemas en el mismo (por ejemplo, la decisión de un repositorio donde estabilizar las releases sin aceptar features nuevas).
  2. Pendiente Se obtiene y distribuye información sobre el uso de este proceso (solo informalmente).
Formación
  1. Hay planificadas actividades de formación del personal, centralizadas en los tutoriales.
    1. Justificadas por el uso de tecnologías nuevas para todo el grupo (como el propio control de revisiones o el lenguaje de programación usado), que, investigadas por un grupo o individuo, son luego explicadas al resto del personal.
    2. Justificadas asimismo por la incorporación de personal al grupo.
  2. Se provee de materiales de educación para la formación del personal relativo a la gestión del software (por ejemplo bazaar para el control de versiones).
  3. Los individuos en el grupo de ingeniería del software también reciben formación adecuada (mediante otros tutoriales como sqlite, así como formación horizontal entre compañeros, y las clases propiamente dichas de la asignatura).
Gestión integrada de software
  1. El proceso de desarrollo de software es una versión a medida del estándar de desarrollo (debido a que el estándar ha surgido en paralelo al proceso concreto).
  2. Pendiente el proceso relativo al proyecto se planifica y gestiona sobre el estándar. No es posible dado que no hemos contado con un estándar predefinido del que partir antes de definir nuestros procesos, si bien teníamos ideas sobre "mejores prácticas" a seguir como el control de versiones en todas partes, o la gestión de releases.
Coordinación entre grupos
  1. Pendiente (parcial) Los requisitos del cliente son aceptados por todos los grupos. Si bien los requisitos se discutieron al inicio, los requisitos del cliente pueden estar algo olvidados por parte de los grupos de trabajo, y necesitar nuevo consenso.
  2. Los compromisos de los distintos grupos están acordados entre todos (ya que se planifica también entre todos).
  3. Los propios grupos identifican, siguen y resuelven los problemas entre ellos.
Peer review ("revisión entre iguales").
  1. Hay planificadas revisiones por parte de otros grupos del trabajo de cada uno para la última iteración, como parte de la mejora de calidad.
  2. Los defectos en el software son identificados, seguidos en el bugtracker y eliminados.

Nivel 4: gestionado

Objetivos

En este nivel se controlan con diversas métricas los procesos seguidos, para conseguir adaptarlos a los proyectos concretos sin desviarse significativamente de los objetivos.

Áreas clave de proceso

Gestión cuantitativa de procesos
  1. Pendiente Hay planificadas actividades de gestión cuantitativa de procesos.
  2. Pendiente Se controla cuantitativamente el rendimiento de los determinados procesos de desarrollo.
  3. Pendiente se conocen cuantitativamente las capacidades de desarrollo del grupo.
Gestión de calidad del software
  1. Hay planificadas actividades de gestión de la calidad del software (orientadas hacia el mantenimiento).
  2. Pendiente Hay definidos objetivos medibles en la calidad, y también sus importancias relativas.
  3. Pendiente Se cuantifica el progreso seguido hacia esos objetivos.

Nivel 5: optimizado

Objetivos

Llegados al último nivel, el objetivo es encontrar mejoras aplicables a los procesos (que ya son medibles merced al nivel 4). En particular, es posible mediante adaptaciones de los procesos no desviarse de las planificaciones y costes estimados.

Áreas clave de proceso

Prevención de defectos
  1. Pendiente Hay planificadas actividades de prevención de defectos.
  2. Las causas más comunes de defectos son identificadas (aparte de mediante la experiencia del trabajo común, mediante herramientas que detectan causas comunes como copy-paste).
  3. Se eliminan sistemáticamente dichas causas.
Gestión de cambios tecnológicos
  1. Pendiente Se planifica la incorporación de cambios tecnológicos.
  2. Las nuevas tecnologías son evaluadas para determinar su efecto sobre calidad y productividad. En nuestro grupo de desarrolladores hay bastantes que siempre experimentan con últimas tecnologías de por sí, así que encontrar algunas que sean aplicables al proyecto es casi natural.
  3. Las tecnologías nuevas apropiadas se incorporan a lo largo de la organización. Para ello ayudan dichos "early-adopters", habiendo localizado ya los problemas más comunes con las mismas durante su uso de las tecnologías.
Gestión de cambios en los procesos

Nos es posible obtener alta puntuación en este campo por ser un grupo pequeño y flexible de desarrolladores.

  1. Se planifican cambios continuos a los procesos.
  2. Toda la organización participa en la mejora de los procesos.
  3. Se mejoran continuamente los procesos, tanto el estándar como los de los proyectos.

Tutorial de pylint

Table of Contents

Instalación de Pylint

Para ayudarnos a comprobar que se usa correctamente el estándar de código acordado al principio del desarrollo de la aplicación usaremos Pylint, disponible en http://pydev.sourceforge.net/pylint.html . Esta herramienta permite identificar dónde no se sigue el estándar fácilmente, y además se puede incluir en el entorno de desarrollo de manera que revise el código según se programa.

Para instalarlo basta con abrir el gestor de paquetes synaptic (sistema->Administración), buscar pylint y marcar para instalar.

Nuestro estándar

Pylint viene configurado por defecto con el estándar que usaron los desarrolladores de la herramienta, por lo que tendremos que configurar el nuestro.

Para esto vamos a la consola y escribimos pylint —generate-rcfile > standard.rc; esto nos creará un fichero de texto llamado standard.rc que en principio contendrá el estándar por defecto, sobre este fichero podremos modificar las opciones para que se ajuste a lo que deseemos.

El fichero con nuestro estándar se distribuirá, junto con la documentación del UML del proyecto y las instrucciones para generar la documentación de doxygen, en la carpeta doc de las fuentes.

Configuración de Eclipse

Para empezar tenemos que estar usando un proyecto en python 2.5, si hace falta cambiar el interprete:

  1. Window->preferences->Pydev->Interpreter - Python
  2. En python intepreters se quita lo que haya (sino es la versión 2.5) y se añade /usr/bin/python2.5 (alternativamente python2.5-dbg).

Para que eclipse pase pylint de forma automática tendremos que ir a window->preferences->Pydev->Pylint, en esta ventana:

  1. Marcamos el cuadradito Use Pylint.
  2. Le indicamos donde esta el archivo lint.py (en principio en /usr/share/pycentral/pylint/site-packages/pylint/lint.py). Si no lo encuentra, en una consola podemos buscarlo con locate lint.py.
  3. Marcamos como errores FATAL severity, ERRORS severity y CONVENTIONS severity y como warnings WARNINGS severity y REFACTOR severity. De esta forma no perderemos información y no tendremos errores inútiles.
  4. Por último en el cuadro de texto de arguments to pass escribimos —rcfile=directorio-donde-este-standard.rc

Una vez realizado esto aceptamos y hacemos un clean del projecto (Project->clean) y se pasará automaticamente pylint. Puede que tarde un poco, sobretodo con proyectos grandes.

Ejecución desde consola

Para aquellos que no usan eclipse y prefieren otros editores, pylint se puede ejecutar desde consola. Basta con que pongáis pylint —rcfile=directorio-donde-este-el-fichero-standard.rc directorio-del-fichero-a-examinar


UML

Table of Contents

Definición

Lenguaje Unificado de Modelado (UML1, por sus siglas en inglés, Unified Modeling Language) es el lenguaje de modelado de sistemas de software más conocido y utilizado en la actualidad. Es un lenguaje gráfico para visualizar, especificar, construir y documentar un sistema de software. UML ofrece un estándar para describir un "plano" del sistema (modelo), incluyendo aspectos conceptuales tales como procesos de negocios y funciones del sistema, y aspectos concretos como expresiones de lenguajes de programación, esquemas de bases de datos y componentes de software reutilizables.

Lista de diagramas de clase

Diagrama de clases general

En este diagrama aparecen representadas todas las clases de la aplicación, incluso algunas que no han sido desarrolladas por estar fuera del alcance.
class-backend-daemon.png

Diagrama de clases de GUI

En este diagrama aparecen representadas todas las clases de la interfaz gráfica del usuario (GUI).

class-gui-sin-flechas.png

Diagrama de clases del backend

En este diagrama aparecen representadas todas las clases que forman parte del backend (que incluye a los módulos Watcher, SnapshotManager, Logger y Database).

class-backend-daemon2.png

Diagrama de componentes

En él se muestran los componentes que forman la aplicación.

component-diagram.png

Diagrama de estado

Diagrama de estados del demonio HDLorean. En él se muestran los distintos estados en que se puede encontrar la aplicación.

state-diagram.png

Diagrama de despliegue

Diagrama de despliegue de la aplicación. Se muestran los distintos equipos que estarían implicados en el proceso, los clientes y el servidor.

deployment-diagram.png

Lista de diagramas de actividad

Diagrama de actividad de añadir carpeta a indexar.

El usuario elige una carpeta para añadir a las ya vigiladas. El caso para un archivo sería similar.

activity-añadirCarpInd.png

Diagrama de actividad de eliminar una carpeta indexada

El usuario elige una dejar de vigilar una carpeta previamente añadida. El caso para un archivo sería similar.

activity-eliminarCarpInd.png

Diagrama de actividad de excluir una carpeta a indexar.

El usuario elige una carpeta para excluir de las vigiladas. El caso para un archivo sería similar.
Es útil para el caso en que se ha añadido una carpeta de la cual se quiere vigilar casi todo su contenido excepto una parte, que sería lo excuído.

activity-excluirCarpInd.png

Diagrama de actividad de borrar una versión.

El usuario elige borrar una versión.

activity-deleteOne.png

Diagrama de actividad de restaurar una versión sin sobreescribir.

El usuario elige restaurar una versión sin borrar la actual.

activity-restWithoutOver.png

Diagrama de actividad de crear una versión.

El usuario, cron o inotify crean una versión en ese momento.

activity-makeSnapshot.png

Diagrama de actividad de preferencias.

El usuario decide cambiar una preferencia. Este es el caso general.

activity-preferences.png

Lista de diagramas de secuencia

Diagrama de secuencia de makeSnapshot cuando lo llevan a cabo cron o inotify.

Cron o inotify detectan un evento que les indica que deben crear una versión.

sequence-cron-inotifySnapshot.png

Diagrama de secuencia de makeSnapshot cuando lo lleva a cabo el usuario.

El usuario elige crear una nueva versión.

sequence-userSnapshot.png

Diagrama de secuencia de getPeriodically.

El usuario da al botón preferencias. La aplicación crea está ventana, para lo cual necesita recuperar los datos almacenados en el fichero de configuración. Este es un caso genérico.

sequence-getPeriodically.png

Diagrama de secuencia de setPeriodically.

El usuario elige cambiar la periodicidad con que se harán las copias de seguridad. Ha de modificarse, por tanto, el fichero de configuración. En este caso, también habrá que actualizar el crontab.

sequence-setPeriodically.png

Diagrama de secuencia de setEveryChange.

El usuario elige crear una nueva versión cada vez que se produzcan cambios (activar inotify). Es el caso genérico de cambiar una preferencia.

sequence-setEveryChange.png

Diagrama de secuencia de restWithoutOverwrite.

El usuario elige recuperar una versión sin borrar la actual.

sequence-restWithoutOver.png

Diagrama de secuencia de scheduler.

Scheduler es el planificador del programa. Atendiendo a varios aspectos de la configuración elige el momento idóneo para llevar a cabo los distintos procesos del sistema, como puede ser crear nuevas versiones.

sequence-scheduler.png

Patrones de diseño

Table of Contents


Definición

En Ingeniería del Software, un patrón de diseño2 es una solución a un problema de diseño. Para que una solución sea considerada un patrón debe poseer ciertas características. Una de ellas es que debe haber comprobado su efectividad resolviendo problemas similares en ocasiones anteriores. Otra es que debe ser reutilizable, lo que significa que es aplicable a diferentes problemas de diseño en distintas circunstancias.

Lista de patrones de diseño

Base de datos como Adapter

Nombre del patrón: Adapter.
Clasificación del patrón: Estructural.
Intención: Se utiliza para transformar una interfaz en otra, de tal modo que una clase que no pudiera utilizar la primera, haga uso de ella a través de la segunda.
Convierte la interfaz de una clase en otra interfaz que el cliente espera. Adapter permite a las clases trabajar juntas, lo que de otra manera no podrían hacerlo debido a sus interfaces incompatibles.
También conocido como: Wrapper.
Motivación: Se pretendía usar pySqlite para gestionar las bases de datos, para lo cual se ha tenido que crear un adaptador que se adecue a las necesidades del programa.
Aplicabilidad: Este patrón se usa cuando:

  • Se desea usar una clase existente, y su interfaz no se iguala con la necesitada.
  • Cuando se desea crear una clase reutilizable que coopera con clases no relacionadas, es decir, las clases no tienen necesariamente interfaces compatibles.

Así, se han podido usar las tecnologías antes mencionadas, adaptándolas para que fuese posible trabajar con ellas en la aplicación.

Estructura:

database-diagram

Participantes:
Target: Journal y History. Define la interfaz específica del dominio que Client usa.
Client: Colabora con la conformación de objetos para la interfaz Target.
Adaptee: PySqlite. Define una interfaz existente que necesita adaptarse.
Adapter: DatabaseWrapper. Adapta la interfaz de pySqlite a Journal y History.
Colaboraciones: Client llama a las operaciones sobre una instancia Adapter. De hecho, el adaptador llama a las operaciones de Adaptee que llevan a cabo el pedido.
Implementación: Se ha creado una nueva clase que será el Adaptador (DatabaseWrapper), que extienda del componente existente (pySqlite) e implemente la interfaz obligatoria. De este modo, se tiene la funcionalidad que deseada y se cumple la condición de implementar la interfaz.

Del mismo modo se puede decir que Journal y History adaptan DatabaseWrapper para que un cliente, ya sea Watcher, Scheduler, o SnapshotManager, puedan hacer uso de él.

SnapshotManager como Abstract Factory

Nombre del patrón: Abstract Factory.
Clasificación del patrón: Creacional.
Intención: Crear diferentes familias de objetos.
Motivación: El patrón de diseño Abstract Factory aborda el problema de la creación de familias de objetos que comparten toda una serie de características comunes en los objetos que componen dichas familias.
Desde un principio, el equipo de desarrollo supo que se centraría en una factoría concreta, xDelta3, pero la intención de incluir nuevas familias, por ejemplo ZFS y LVM motivó a desarrollar este diseño para facilitar este futuro acoplamiento.
Aplicabilidad:

  • El uso de este patrón está recomendado para situaciones en las que se tiene una familia de productos concretos y se preveé la inclusión de distintas familias de productos en un futuro.
  • Un sistema debe ser independiente de cómo se crean, componen y representan sus productos.
  • Un sistema debe ser configurado con una familia de productos entre varias.
  • Una familia de objetos producto relacionados está diseñada para ser usada conjuntamente y es necesario hacer cumplir esa restricción.
  • Se quiere proporcionar una biblioteca de clases producto y sólo se quiere revelar sus interfaces y no sus implementaciones.

Participantes: La estructura del patrón Abstract Factory es la siguiente:
Client: SnapshotManager. Sólo conoce la clases abstracta, IstorageWrapper, de los componentes.
AbstractFactory: Define métodos abstractos para crear instancias de clases Producto concretas.(IStorageWrapper)
ConcreteFactory: Implementan los métodos definidos por la superclase AbstractFactory para crear instancias de clases Producto concretas.
Métodos de creación de los productos genéricos en la interfaz de la fábrica (makeSnapshot, recoverSnapshot, recoverBackups…) que retornan una versión en un momento dado.
Son cada uno de los distintos wrappers (xDelta3Wrapper, LVMWrapper, ZFSWrapper) para crear el objeto de la tecnología pertinente.
Colaboraciones: Normalmente, una instancia de la clase ConcreteFactory es creada en tiempo de ejecución. Esta fábrica crea objetos de Producto concretos teniendo en cuenta una implementación particular. Para crear objetos de Producto diferentes, los clientes deberían usar una fábrica concreta distinta.
Al instanciar SnapshotManager se elige por parámetro la factoría a utilizar.
La clase abstracta AbstractFactory (IstorageWrapper) difiere la creación de objetos Producto a su subclase ConcreteFactory (los distintos wrappers).
Consecuencias:

  • Aísla clases concretas: Este patrón ayuda a controlar los productos que una aplicación crea porque encapsula la responsabilidad y el proceso de creación de objetos y aísla a los clientes de las implementaciones.
  • Se puede cambiar de familia de productos : Para cambiar de productos se debe cambiar de fábrica concreta.
  • Promueve la consistencia entre productos: Cuando los productos son diseñados para trabajar en conjunto, es importante que en una aplicación se utilicen objetos de una familia a la vez.
  • Desventaja: es difícil dar cabida a nuevos tipos de productos. Para crear nuevos tipos de productos es necesario crear una nueva fábrica concreta e implementar todas las operaciones que ofrece la superclase AbstractFactory.

Como conclusión se puede decir que este patrón está aconsejado cuando se prevé la inclusión de nuevas familias de productos, pero puede resultar contraproducente cuando se añaden nuevos productos o cambian los existentes.
Usos conocidos: Creación de familias de interfaces gráficos en las cuales los elementos (productos) del interfaz se mantienen constantes (por ejemplo labels, botones, cajas de texto …) pero el dibujado de dichos elementos puede delegarse en distintas familias (por ejemplo QT, GTK, etc) de forma que, en función de la fábrica seleccionada obtenemos unos botones u otros.
Patrones relacionados: Cuando se usa en conjunción con Singleton se crea una única fábrica, de modo que no habrá usos inconsistentes de los productos en el programa.
En este caso se usará el patrón Monostate en lugar del Singleton.

SnapshotManager como Façade

Nombre del patrón: Façade.
Clasificación del patrón: Estructural.
Intención: El patrón de diseño façade sirve para proveer de una interfaz unificada sencilla que haga de intermediaria entre un cliente y una interfaz o grupo de interfaces más complejas.
Motivación:

  • Crear un intermediario y realizar llamadas a la biblioteca sólo o, sobre todo, a través de él.
  • Crear una API intermedia, bien diseñada, que permita acceder a la funcionalidad de las demás.
  • Un objetivo de diseño general es minimizar la comunicación y dependencias entre subsistemas. Un modo de lograrlo es introducir un objeto fachada que proporciona una interfaz unificada a la funcionalidad del subsistema.

Aplicabilidad: Úsese el patrón Façade cuando se desee:

  • Proporcionar una interfaz simple para un subsistema complejo, evitando así que la mayoría de clientes tengan que conocer todas las clases internas del subsistema.
  • Desacoplar un subsistema de sus clientes y otros subsistemas, promoviendo así la independencia entre subsistemas (y, por tanto, la portabilidad).

Participantes:
Façade: IstorageWrapper, sabe qué clases del subsistema son las responsables de llevar a cabo cada petición. Delega las peticiones de los clientes a los objetos apropiados del subsistema.
Clases del subsistema: Los distintos wrapper, que implementan la funcionalidad del subsistema.
Colaboraciones: IstorageWrapper es un interfaz que hace que los wrappers tengan una fachada común.
Consecuencias:

  • Reduce el número de objetos con el que tienen que tratar los clientes, haciendo que el subsistema sea más fácil de usar.
  • Promueve un bajo acoplamiento entre el subsistema y los clientes.
    • Permite variar sus componentes sin que los clientes se vean afectados.
    • Ayuda a estructurar en capas un sistema.

Implementación: Reducir el acoplamiento entre cliente y subsistema: Haciendo que el Façade sea una clase abstracta o una interfaz.
O configurándolo con diferentes objetos del subsistema.
Clases del subsistema públicas o privadas: Sería útil hacer que determinadas clases del subsistema fueran privadas, aunque pocos lenguajes lo permiten.
Patrones relacionados: Adapter.

SnapshotManager como Adapter

Nombre del patrón: Adapter.
Clasificación del patrón: Estructural.
Intención: Se utiliza para transformar una interfaz en otra, de tal modo que una clase que no pudiera utilizar la primera, haga uso de ella a través de la segunda.
Convierte la interfaz de una clase en otra interfaz que el cliente espera. Adapter permite a las clases trabajar juntas, lo que de otra manera no podrían hacerlo debido a sus interfaces incompatibles.
También conocido como: Wrapper.
Motivación: Se quería usar xDelta3, ZFS y LVM para crear las versiones, para lo cual se ha tenido que crear un adaptador para cada una de ellas, de forma que cumplan la funcionalidad requerida.
Aplicabilidad: Este patrón se usa cuando:

  • Se desea usar una clase existente, y su interfaz no se iguala con la necesitada.
  • Cuando se desea crear una clase reutilizable que coopera con clases no relacionadas, es decir, las clases no tienen necesariamente interfaces compatibles.

De esta forma, se han podido usar las tecnologías antes mencionadas, adaptándolas para que fuese posible trabajar con ellas en la aplicación.
Participantes:
Target: IStorageWrapper. Define la interfaz específica del dominio que Client usa.
Client: Colabora con la conformación de objetos para la interfaz Target. (SnapshotManager)
Adaptee: xDelta3, ZFS y LVM. Definen las interfaces existentes que necesitan adaptarse.
Adapter: xDelta3Wrapper, ZFSWrapper, LVMWrapper. Adaptan la interfaz de xDelta3, ZFS y LVM respectivamente.
Colaboraciones: Client llama a las operaciones sobre una instancia Adapter. De hecho, el adaptador llama a las operaciones de Adaptee que llevan a cabo el pedido.
Implementación: Crear una nueva clase que será el Adaptador, que extienda del componente existente e implemente la interfaz obligatoria. De este modo se tiene la funcionalidad deseada y se cumple la condición de implementar la interfaz.
Patrones relacionados: Façade.

SnapshotManager como Monostate

Nombre del patrón: Monostate.
Clasificación del patrón: Creacional.
Intención: Asegura que todas las instancias tengan un estado común.
Motivación: Se accede a las versiones desde distintos puntos, y el estado ha de ser el mismo para todas.
Aplicabilidad: Se utiliza cuando se debe tener el mismo estado independientemente del acceso.
Participantes:
Monostate: SnapshotManager.
Colaboraciones:
Consecuencias:
Implementación:
Patrones relacionados: Abstract Factory, Singleton.

Estructura del módulo SnapshotManager:

snapshotManager-diagram

ConfigFileManager como Singleton

Nombre del patrón: Singleton.
Clasificación del patrón: Creacional.
Intención: Garantizar que una clase sólo tenga una instancia y proporcionar un punto de acceso global a ella
Motivación: Se accede a la configuración del programa desde distintos puntos, y siempre hemos de referirnos a la misma instancia.
Aplicabilidad: Se utiliza cuando deba haber exactamente una instancia de una clase y deba ser accesible a los clientes desde un punto de acceso conocido.
Las situaciones más habituales de aplicación de este patrón son aquellas en las que dicha clase controla el acceso a un recurso físico único o cuando cierto tipo de datos debe estar disponible para todos los demás objetos de la aplicación.
Estructura: Código que implementa el patrón, controlando una única instancia:

    def __new__(self,watcher=None):
        # if the class has not been instanciated before do it
        # else return instance.
        if self.__instance is None:
            self.__configFilePath = os.getenv("HOME")+"/.hdlorean/config.cfg"
            self.__instance = object.__new__(self)
 
        if watcher is not None:
            self.__watcher = watcher
        return self.__instance

Participantes:
Singleton: ConfigFileManager, define un método instancia que permite que los clientes accedan a su única instancia. Instancia es un método de clase estático.
Colaboraciones: Los clientes acceden a una instancia de un Singleton exclusivamente a través de un método instancia de éste.
Consecuencias:
  • Acceso controlado a la única instancia.
  • Espacio de nombres reducido: no hay variables globales.
  • Puede adaptarse para permitir más de una instancia.

Implementación: El patrón Singleton se implementa creando en una clase un método que crea una instancia del objeto sólo si todavía no existe alguna. Para asegurar que la clase no puede ser instanciada nuevamente se regula el alcance del constructor (con atributos como protegido o privado).
Patrones relacionados: Abstract Factory, Monostate.

Demonio hdloreand como Singleton

Nombre del patrón: Singleton.
Clasificación del patrón: Creacional.
Intención: Garantizar que una clase sólo tenga una instancia y proporcionar un punto de acceso global a ella
Motivación: Se accede a la configuración del programa desde distintos puntos, y siempre hemos de referirnos a la misma instancia.
Aplicabilidad: Se utiliza cuando deba haber exactamente una instancia de una clase y deba ser accesible a los clientes desde un punto de acceso conocido.
Las situaciones más habituales de aplicación de este patrón son aquellas en las que dicha clase controla el acceso a un recurso físico único o cuando cierto tipo de datos debe estar disponible para todos los demás objetos de la aplicación.
Estructura: Código que implementa el patrón, controlando una única instancia:

    def __new__(self):
        if self.__instance is None:
            self.__instance = object.__new__(self)
            db = Journal.Journal()
            db.createTable()
            self.__watcher = Watcher.Watcher()            
            self.__scheduler = Scheduler.Scheduler()
            bp = BackendProxy.BackendProxy(self.__watcher,self.__scheduler,self.__instance)
            self.__cfm = ConfigFileManager.ConfigFileManager()
        return self.__instance

Participantes:
Singleton: hdloreand es el demonio de la aplicación, define un método instancia que permite que los clientes accedan a su única instancia. Instancia es un método de clase estático.
Colaboraciones: Los clientes acceden a una instancia de un Singleton exclusivamente a través de un método instancia de éste.
Consecuencias:
  • Acceso controlado a la única instancia.
  • Espacio de nombres reducido: no hay variables globales.
  • Puede adaptarse para permitir más de una instancia.

Implementación: El patrón Singleton se implementa creando en una clase un método que crea una instancia del objeto sólo si todavía no existe alguna. Para asegurar que la clase no puede ser instanciada nuevamente se regula el alcance del constructor (con atributos como protegido o privado).
Patrones relacionados: Abstract Factory, Monostate.

PyInotifyHandler como Adapter

Nombre del patrón: Adapter.
Clasificación del patrón: Estructural.
Intención: Se utiliza para transformar una interfaz en otra, de tal modo que una clase que no pudiera utilizar la primera, haga uso de ella a través de la segunda.
Convierte la interfaz de una clase en otra interfaz que el cliente espera. Adapter permite a las clases trabajar juntas, lo que de otra manera no podrían hacerlo debido a sus interfaces incompatibles.
También conocido como: Wrapper.
Motivación: El equipo quería usar Inotify para gestionar los eventos que ocurren sobre un archivo vigilado. Se investigó su uso y se decidió utilizar el módulo pyInotify, incluído en python.
Aplicabilidad: Este patrón se usa cuando:

  • Se desea usar una clase existente, y su interfaz no se iguala con la necesitada.
  • Cuando se desea crear una clase reutilizable que coopera con clases no relacionadas, es decir, las clases no tienen necesariamente interfaces compatibles.

Estructura:

pyinotifyhandler-diagram

Participantes:
Target: PyinotifyHandler. Define la interfaz específica del dominio que Client usa.
Client: Watcher. Colabora con la conformación de objetos para la interfaz Target.
Adaptee: PyInotify. Define una interfaz existente que necesita adaptarse.
Adapter: Pyinotifyhandler. Adapta la interfaz del pyInotify.
Colaboraciones: Client llama a las operaciones sobre una instancia Adapter. De hecho, el adaptador llama a las operaciones de Adaptee que llevan a cabo el pedido.
Implementación: Python tiene el módulo pyInotify, el cual nos ofrece una manera genérica y abstracta para manipular las funcionalidades de inotify. Se ha creado una nueva clase, Pyinotifyhandler, que prepara las estructuras de datos y configura inotify para que la aplicación, (Watcher en particular) pueda gestionar los eventos de forma acorde al objetivo del programa.

El sistema de paso de mensajes DBUS como Mediator

Nombre del patrón: Mediator.
Clasificación del patrón: De comportamiento.
Intención: Definir un objeto que encapsule como interactúa un conjunto de objetos.
Motivación: Cuando muchos objetos interactúan con otros objetos, se puede formar una estructura muy compleja, con objetos con muchas conexiones con otros objetos. En un caso extremo cada objeto puede conocer a todos los demás objetos. Para evitar esto el patrón Mediator encapsula el comportamiento de todo un conjunto de objetos en un solo objeto.
Aplicabilidad: Usar el patrón Mediator cuando:

  • Un conjunto grande de objetos se comunica de una forma bien definida, pero compleja.
  • Reutilizar un objeto se hace difícil por que se relaciona con muchos objetos.
  • El comportamiento de muchos objetos que esta distribuido entre varias clases, puede resumirse en una o varias por subclasificación.

Participantes:
Mediator (BackendProxy y FrontendProxy): Implementa el comportamiento cooperativo entre los colegas (como se comunican entre ellos). Además los conoce y mantiene. Debido a las peculiaridades de DBUS, FrontendProxy recibe las peticiones de GUI y UI y se las transmite a BackendProxy, que es el encargado de enviarla al colega destinatario.
Colleagues: Cada colega conoce su mediador, y usa a este para comunicarse con otros colegas.
Colaboraciones: Los colegas envían y reciben requerimientos (requests) de un objeto mediador. El mediador implementa como se comunican los colegas.
Consecuencias: El patrón Mediator tiene los siguientes beneficios y desventajas:

  • Desacopla a los colegas: el patrón Mediator promueve bajar el acoplamiento entre colegas. Se puede variar y reutilizar colegas y mediadores independientemente .
  • Simplifica la comunicación entre objetos: Los objetos que se comunican de la forma "muchos a muchos" puede ser remplazada por una forma "uno a muchos" que es menos compleja y más elegante. Además esta forma de comunicación es más fácil de entender.
  • Abstrae como los objetos cooperan: Haciendo a la mediación un concepto independiente y encapsulándolo en un objeto permite enfocar como los objetos interactúan. Esto ayuda a clarificar como los objetos se relacionan en un sistema.
  • Centraliza el control: El mediador es el que se encarga de comunicar a los colegas, este puede ser muy complejo, difícil de entender y modificar.

Implementación:
Omitir la clase abstracta Mediator. No es necesario crear una clase abstracta Mediador cuando los objetos solo trabajan con un mediador. El acoplamiento abstracto de dicha clase permite que los objetos trabajen con diferentes subclases Mediator y viceversa.
Comunicación Objeto y Mediador. Los objetos se comunican su mediador cuanto tiene lugar un evento. Las clases de objetos cada vez que cambian su estado envían notificaciones al mediador. El mediador responde propagando los efectos de dichos eventos a los otros objetos.
Otra forma define al Mediador una interfaz de notificación especializada que permite a los objetos ser mas directos en su comunicación.
Usos conocidos: La arquitectura de Smalltalk/V para Windows usan objetos parecidos a mediadores entre los útiles de los diálogos.
Patrones relacionados: Un patrón muy parecido a éste es el Façade que se diferencia en que abstrae un sistema de objetos proporcionado una interfaz mas conveniente, utilizando un protocolo unidireccional (Fachada realiza solo peticiones a las clases del subsistema pero no a la inversa), mientras que el Mediator usa un protocolo mutidireccional.
Con el patrón Observer los objetos pueden comunicarse con el mediador.

El sistema de paso de mensajes DBUS como Observer

Nombre del patrón: Observer.
Clasificación del patrón: De comportamiento.
Intención: Definir una dependencia entre un objeto y un conjunto de ellos, de modo que los cambios en el primero se vean reflejados en los otros.
También conocido como: Spider.
Motivación: Frontend ha de recibir señales desde el backend que nos informen de que ha habido un cambio en algún archivo vigilado y así refrescar el treeview de GUI, por ejemplo.
Aplicabilidad: Se usa en casos en que se desea desacoplar la clase de los objetos clientes del objeto, aumentando la modularidad del lenguaje, así como evitar bucles de actualización (espera activa o polling).
Participantes:
Sujeto: Mantiene una lista de observadores y proporciona una interfaz para su gestión.
Observador: Define una interfaz para actualizar los objetos que deben reflejar los cambios en el sujeto.
Observador concreto: Mantiene una referencia a una sujeto concreto, almacenando parte de su estado e implementado la interfaz de Observador.
Colaboraciones: El Sujeto notifica a sus observadores de los cambios que sufre. Los observadores concretos solicitan a su sujeto los datos necesarios para mantener la consistencia con su nuevo estado.
Consecuencias:

  • Permite reutilizar sujetos y observadores por separado.
  • Permite añadir nuevos observadores sin modificar al sujeto o a otros observadores.
  • Que el sujeto no informe a sus observadores de qué cambio ha sufrido permite mantener el acoplamiento en un nivel bajo, puesto que el observador sólo pide los datos del estado del sujeto que le interesan.
  • Aunque el observador no esté interesado en ciertos cambios del sujeto será notificado de ellos.
  • Se pueden realizar implementaciones con observadores que coordinan información sobre varios sujetos.
  • Los cambios en el sujeto pueden ser solicitados por objetos que no son observadores.

Implementación: El backend generará una señal que recibirá el frontend, que previamente se había suscrito a ella.
Usos conocidos: Este patrón suele observarse en los marcos de interfaces gráficas orientados a objetos, en los que la forma de capturar los eventos es suscribir 'listeners' a los objetos que pueden disparar eventos.

El sistema de paso de mensajes DBUS usando Proxys

Nombre del patrón: Proxy.
Clasificación del patrón: Estructural.
Intención: Proporciona un representante o sustituto de otro objeto para controlar el acceso a éste.
Motivación: La interfaz gráfica y la consola necesitan interaccionar con el demonio de la aplicación. Para ello se crea un sustituto de los distintos objetos a los que se ha de acceder.
Aplicabilidad:

  • Un proxy remoto proporciona un representante local de un objeto remoto.
  • Un proxy virtual crea objetos costosos sólo cuando es necesario.
  • Un proxy de protección controla el acceso al objeto original.
  • Una referencia inteligente es un sustituto de un simple puntero que realiza alguna acción adicional:
    • Contar el número de referencias al objeto original.
    • Cargar un objeto persistente en memoria cuando es referenciado por vez primera.
    • Bloquea el acceso al objeto real para que no sea modificado por otro objeto.

Participantes:
Client: Elemento que desea acceder al objeto.
Proxy: Mantiene una referencia para acceder al objeto original.
* Proporciona una interfaz idéntica a la del Subject.
* Controla el acceso al objeto y puede encargarse de crearlo, borrarlo…
BackendProxy proporciona un representante de distintos objetos reales.
Subject: Define el objeto real representado por el Proxy. Watcher, Scheduler, SnapshotManager.
Colaboraciones: Client accede a Subject a través de Proxy.
Patrones relacionados: Singleton.

BackendProxy y FrontendProxy como Singleton

Las clases BackendProxy y FrontendProxy están implementadas con el patrón Singleton para que se use siempre la misma instancia.

Estructura del sistema de paso de mensajes entre backend y frontend:

dbus-diagram

HDLogger como Adapter

Nombre del patrón: Adapter.
Clasificación del patrón: Estructural.
Intención: Se utiliza para transformar una interfaz en otra, de tal modo que una clase que no pudiera utilizar la primera, haga uso de ella a través de la segunda.
Convierte la interfaz de una clase en otra interfaz que el cliente espera. Adapter permite a las clases trabajar juntas, lo que de otra manera no podrían hacerlo debido a sus interfaces incompatibles.
También conocido como: Wrapper.
Motivación: Se quería hacer un módulo de logger para centralizar la recogida de información relevante para la depuración de problemas. Para ello se ha decidido adaptar el módulo de logger de python.
Aplicabilidad: Este patrón se usa cuando:

  • Se desea usar una clase existente, y su interfaz no se iguala con la necesitada.
  • Cuando se desea crear una clase reutilizable que coopera con clases no relacionadas, es decir, las clases no tienen necesariamente interfaces compatibles.

De esta forma, se han podido usar las tecnologías antes mencionadas, adaptándolas para que fuese posible trabajar con ellas en la aplicación.
Estructura:

hdlogger-diagram

Participantes:
Target: HDLogger. Define la interfaz específica del dominio que Client usa.
Client: Colabora con la conformación de objetos para la interfaz Target. Son todas aquellas clases que hacen uso del logger.
Adaptee: librería logging de Python. Define la librería que ha de adaptarse.
Adapter: HDLogger. Adaptan el logger de python.
Colaboraciones: Client llama a las operaciones sobre una instancia Adapter. De hecho, el adaptador llama a las operaciones de Adaptee que llevan a cabo el pedido.
Implementación: Crear una nueva clase que será el Adaptador, que extienda del componente existente e implemente la interfaz obligatoria. De este modo se tiene la funcionalidad deseada y se cumple la condición de implementar la interfaz.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License