Análisis del Impacto del Uso de Patrones de Diseño en la Fase de Mantenimiento
Texto completo
(2)
(3) ANÁLISIS DEL IMPACTO DEL USO DE PATRONES DE DISEÑO EN LA FASE DE MANTENIMIENTO. MARTHA JANETH DE LEÓN CORREA Cód 20142099005 IVÓN ROSMERY HOYOS BELTRÁN Cód 20142099042 FABIO ENRIQUE QUINTERO DIAZGRANDOS Cód 20142099017. Proyecto de grado. Director: PhD. Sandro Javier Bolaños Castro. UNIVERSIDAD DISTRITAL FRANCISCO JOSÉ DE CALDAS FACULTAD DE INGENIERÍA ESPECIALIZACIÓN EN INGENIERÍA DE SOFTWARE BOGOTÁ D.C. MAYO 2015.
(4)
(5) ANÁLISIS DEL IMPACTO DEL USO DE PATRONES DE DISEÑO EN LA FASE DE MANTENIMIENTO.
(6)
(7) Agradecimientos. Gracias a todas las personas de la Universidad Distrital Francisco José de Caldas, por su atención y amabilidad en nuestro paso como alumnos. Gracias a los profesores de la especialización por la confianza, apoyo y dedicación en este proceso. Gracias a la Ing. Alexandra Abuchar por su paciencia, motivación y aliento. Gracias especialmente al Ing. Sandro Bolaños por compartir con nosotros su experiencia y conocimiento en la dirección de este proyecto.. I.
(8)
(9) Índice general Agradecimientos. I. 1. DEFINICIÓN DEL TEMA DE INVESTIGACIÓN 1 . PROBLEMA DE INVESTIGACIÓN . . . . . . . . . 1 .1. PLANTEAMIENTO DEL PROBLEMA . . . 1 .2. FORMULACIÓN DEL PROBLEMA . . . . . 1 .3. SISTEMATIZACIÓN DEL PROBLEMA . . .. . . . .. 5 5 5 6 6. 2. OBJETIVOS 1 . OBJETIVO GENERAL . . . . . . . . . . . . . . . . . . . . . . . . . . 2 . OBJETIVOS ESPECÍFICOS . . . . . . . . . . . . . . . . . . . . . . .. 9 9 9. 3. ALCANCES Y LIMITACIONES 1 . ALCANCES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 . LIMITACIONES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 11 11 11. 4. JUSTIFICACIÓN. 13. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. 5. MARCO DE REFERENCIA 15 1 . MARCO TEÓRICO . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1 .1. COMPONENTES DE LOS PATRONES DE DISEÑO . . . . . 15 1 .2. TAXONOMÍA DE UN PATRÓN . . . . . . . . . . . . . . . . . 16 1 .3. CLASIFICACIÓN DE PATRONES . . . . . . . . . . . . . . . . 17 1 .4. CATÁLOGO DE PATRONES . . . . . . . . . . . . . . . . . . . 17 1 .5. REFACTORIZACIÓN . . . . . . . . . . . . . . . . . . . . . . . 51 1 .6. VENTAJAS Y DESVENTAJAS DEL USO DE PATRONES . . 52 1 .7. TÉCNICAS ESTADÍSTICAS PARA EL ANÁLISIS DE DATOS: 52 1 .8. ANÁLISIS DE UNA VARIABLE (Muestra de Datos) . . . . . . 53 2 . MARCO CONCEPTUAL . . . . . . . . . . . . . . . . . . . . . . . . . 55 6. MODELO ARQUITECTÓNICO POR PUNTOS DE VISTA EN ARCHIMATE 59 1 . CAPA DE NEGOCIO . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 1 .1. Punto de vista de la Organización . . . . . . . . . . . . . . . . . 59 III.
(10) 2.. 3.. 4.. 1 .2. 1 .3. 1 .4. 1 .5. CAPA 2 .1. 2 .2. 2 .3. 2 .4. CAPA 3 .1. 3 .2. 3 .3. 3 .4. 3 .5. CAPA 4 .1. 4 .2. 4 .3. 4 .4. 4 .5. 4 .6. 4 .7. 4 .8. 4 .9.. Punto de vista de Cooperación . . . . . . . . . . . . Punto de Vista Función de Negocio . . . . . . . . . . Punto de Vista Procesos del Negocio . . . . . . . . . Punto de Vista del Producto . . . . . . . . . . . . . . DE APLICACIÓN . . . . . . . . . . . . . . . . . . . Punto de Vista de Comportamiento de la Aplicación Punto de Vista de Cooperación de la Aplicación . . . Punto de Vista de Estructura de Aplicación . . . . . Punto de Vista de Uso de la Aplicación . . . . . . . . DE INFRAESTRUCTURA TECNOLÓGICA . . . . Punto de Vista De Infraestructura . . . . . . . . . . . Punto de Vista de Uso de la Infraestructura . . . . . Punto de Vista de Organización e Implementación . . Punto de Vista de Estructura de la Información . . . Punto de Vista de Capas . . . . . . . . . . . . . . . . DE MOTIVACIÓN Y MIGRACIÓN . . . . . . . . . Punto de Vista de Stakeholders . . . . . . . . . . . . Punto de Vista de Realización de objetivos . . . . . . Punto de Vista de Contribución . . . . . . . . . . . . Punto de Vista de Principios . . . . . . . . . . . . . . Punto de Vista de Realización de Requerimientos . . Punto de Vista de Motivación . . . . . . . . . . . . . Punto de Vista del Proyecto . . . . . . . . . . . . . . Punto de Vista de Migración . . . . . . . . . . . . . . Punto de Vista de Migración e Implementación . . .. . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . .. 59 60 62 63 63 63 65 65 66 67 67 67 69 69 70 72 72 73 74 75 76 77 77 78 78. 7. HIPÓTESIS. 81. 8. ASPECTOS METODOLÓGICOS 1 . TIPO DE ESTUDIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 . MÉTODO DE INVESTIGACIÓN . . . . . . . . . . . . . . . . . . . . . 3 . FUENTES Y TÉCNICAS PARA RECOLECCIÓN DE LA INFORMACIÓN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 83 83 83. 9. RECOLECCIÓN Y ORDENAMIENTO DE LA INFORMACIÓN 1 . INFORMACIÓN MATERIA PRIMA PARA LA INVESTIGACIÓN . . 1 .1. DEFINICIÓN DE LA MUESTRA . . . . . . . . . . . . . . . . 1 .2. FUENTES DE INFORMACIÓN SECUNDARIA . . . . . . . . 1 .3. FUENTES DE INFORMACIÓN PRIMARIA . . . . . . . . . . 2 . TABULACIÓN, ORDENAMIENTO Y PROCESAMIENTO DE LA INFORMACIÓN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 .1. TABULACIÓN . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 .2. ORDENAMIENTO . . . . . . . . . . . . . . . . . . . . . . . . .. 87 87 87 88 88. 83. 93 93 93.
(11) 2 .3. 2 .4.. PROCESAMIENTO . . . . . . . . . . . . . . . . . . . . . . . . PRESENTACIÓN DE LOS RESULTADOS . . . . . . . . . . .. 10.ANÁLISIS DE LOS RESULTADOS 1 . IDENTIFICACIÓN DE VARIABLES . . . . . . . . . . . . . . . 2 . VERIFICACIÓN DE PREGUNTAS DE LA INVESTIGACIÓN 3 . VERIFICACIÓN DE OBJETIVOS . . . . . . . . . . . . . . . . 4 . VERIFICACIÓN DE HIPÓTESIS . . . . . . . . . . . . . . . .. . . . .. . . . .. . . . .. . . . .. 93 94 115 115 119 119 119. 11.CONCLUSIONES. 121. 12.RECOMENDACIONES. 123. Bibliografı́a. 125.
(12)
(13) Índice de figuras 5.1. Ejm. Gráfica Desviación Estandar . . . . . . . . . . . . . . . . . . . . . 5.2. Gráfica de Histograma . . . . . . . . . . . . . . . . . . . . . . . . . . .. 53 54. 6.1. PV. de Organización . . . . . . . . . 6.2. PV de Cooperación . . . . . . . . . . 6.3. PV. Función del Negocio . . . . . . . 6.4. PV. Procesos del Negocio . . . . . . 6.5. PV. del Producto . . . . . . . . . . . 6.6. PV Comportamiento de la Aplicación 6.7. PV Cooperación de la Aplicación . . 6.8. PV de Estructura de Aplicación . . . 6.9. PV. Uso de la Aplicación . . . . . . . 6.10. PV. de Infraestructura . . . . . . . . 6.11. PV. Uso de Infraestructura . . . . . . 6.12. PV. Organización e Implementación . 6.13. PV Estructura de Información . . . . 6.14. PV. por Capas . . . . . . . . . . . . 6.15. PV. de Stakeholders . . . . . . . . . 6.16. PV. Realización de Objetivos . . . . 6.17. PV. de Contribución . . . . . . . . . 6.18. PV. de Principios . . . . . . . . . . . 6.19. PV. Realización del Requerimiento . 6.20. PV. Motivación . . . . . . . . . . . . 6.21. PV. del Protecto . . . . . . . . . . . 6.22. PV. de Migración . . . . . . . . . . . 6.23. PV. de Migración e Implementación . 9.1. 9.2. 9.3. 9.4. 9.5. 9.6. 9.7.. . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . .. 60 60 61 62 63 64 65 66 67 68 69 69 70 71 72 73 74 75 76 77 77 78 78. Hoja 1: Encuesta . . . . . . . . . . . . Encuesta: Preguntas Especificación . . Encuesta Preguntas de Desarrollo . . . Encuesta Preguntas de Mantenimiento Tabla de Frecuencias . . . . . . . . . . Diagrama de barras, Encuesta . . . . . Tabla de Frecuencia total . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. 89 90 91 92 95 96 97. VII.
(14) 9.8. Diagrama de Barras - Encuesta Total . . . . . . . . . 9.9. Frecuencia y Desviación Estándar - Pregunta 1 . . . . 9.10. Diagrama de barras y Torta - Pregunta No 1 . . . . . 9.11. Frecuencia y Desviación Estándar - Pregunta No. 2 . 9.12. Diagrama de barras y Torta - Pregunta No 2 . . . . . 9.13. Frecuencia y Desviación Estándar - Pregunta No. 3 . 9.14. Diagrama de barras y Torta - Pregunta No 3 . . . . . 9.15. Frecuencia y Desviación Estándar- Pregunta No. 4 . . 9.16. Diagrama de barras y Torta - Pregunta No 4 . . . . . 9.17. Frecuencia y Desviación Estándar - Pregunta No. 5 . 9.18. Diagrama de barras y Torta - Pregunta No 5 . . . . . 9.19. Frecuencia y Desviación Estándar - Pregunta No. 6 . 9.20. Diagrama de barras y Torta - Pregunta No 6 . . . . . 9.21. Frecuencia y Desviación Estándar - Pregunta No. 7 . 9.22. Diagrama de barras y Torta - Pregunta No 7 . . . . . 9.23. Frecuencia y Desviación Estándar - Pregunta No. 8 . 9.24. Diagrama de barras y Torta - Pregunta No 8 . . . . . 9.25. Frecuencia y Desviación Estándar - Pregunta No. 9 . 9.26. Diagrama de barras y Torta - Pregunta No 9 . . . . . 9.27. Frecuencia y Desviación Estándar - Pregunta No. 10 . 9.28. Diagrama de barras y Torta - Pregunta No 10 . . . . 9.29. Frecuencia y Desviación Estándar - Pregunta No. 11 . 9.30. Diagrama de barras y Torta - Pregunta No 11 . . . . 9.31. Frecuencia y Desviación Estándar - Pregunta No. 12 . 9.32. Diagrama de barras y Torta - Pregunta No 12 . . . . 9.33. Frecuencia y Desviación Estándar - Pregunta No. 13 . 9.34. Diagrama de barras y Torta - Pregunta No 13 . . . . 9.35. Frecuencia y Desviación Estándar - Pregunta No. 14 . 9.36. Diagrama de barras y Torta - Pregunta No 14 . . . . 9.37. Frecuencia y Desviación Estándar - Pregunta No. 15 . 9.38. Diagrama de barras y Torta - Pregunta No 15 . . . . 9.39. Frecuencia y Desviación Estándar - Pregunta No. 16 . 9.40. Diagrama de barras y Torta - Pregunta No 16 . . . . 9.41. Frecuencia y Desviación Estándar - Pregunta No. 17 . 9.42. Diagrama de barras y Torta - Pregunta No 17 . . . . 9.43. Frecuencia y Desviación Estándar - Pregunta No. 18 . 9.44. Diagrama de barras y Torta - Pregunta No 18 . . . . 9.45. Frecuencia - Patrones de Creacionales . . . . . . . . . 9.46. No. proyecto que usaron Patrones Creacionales . . . . 9.47. Frecuencia - Patrones de Estructurales . . . . . . . . 9.48. No. Patrones de Estructurales . . . . . . . . . . . . . 9.49. Frecuendia - Patrones de Comportamiento . . . . . . 9.50. No. Patrones de Comportamiento . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 98 98 98 99 99 99 100 100 100 101 101 101 102 102 102 103 103 103 104 104 104 105 105 105 106 106 106 107 107 107 108 108 108 109 109 110 110 110 111 111 112 112 112.
(15) Especialización en Ingenierı́a de Software 9.51. Frecuencia y Desviación Estándar - Pregunta No. 20 . 9.52. Diagrama de barras y Torta - Pregunta No 20 . . . . 9.53. Frecuencia y Desviación Estándar - Pregunta No. 21 . 9.54. Diagrama de barras y Torta - Pregunta No 21 . . . .. IX. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. 113 113 113 114.
(16) Análisis del impacto del uso de patrones de diseño en la fase de mantenimiento. X.
(17) INTRODUCCIÓN Se necesita de un proceso de mantenimiento para asegurar que un Sistema de Software continúa satisfaciendo los requerimientos de los usuarios. Esta fase es importante y aplicable a los Desarrollos de Software usando cualquier modelo de ciclo de vida del software y lenguaje de programación. Swanson [5] identifica tres tipos de cambios que se pueden realizar para permitir que un sistema de software pueda evolucionar durante el tiempo: (i) correctiva; (ii) perfectivo; (iii) adaptativo. Una operación de mantenimiento correctivo es una modificación reactiva para corregir los problemas descubiertos, mientras que una operación de mantenimiento perfectivo es la necesidad de mejorar el rendimiento o la capacidad de mantenimiento de un sistema de software existente. El proceso de adaptación es mantener utilizable para los usuarios un producto de software en un ambiente cambiante. Para realizar mantenimiento de software, los programadores pasan mucho tiempo leyendo y comprendiendo el código fuente. Este tiempo debe disminuir cuando las opciones de diseño están disponibles. Además, la disponibilidad de opciones de diseño debe apoyar mejor a los programadores para lograr operaciones de mantenimiento eficientes.[1] En cuanto a los sistemas de software orientados a objetos, las opciones de diseño son a menudo implementadas con patrones recurrentes que son conocidos en la literatura como patrones de diseño. Gamma et al. [1] afirma que ”Design patterns can even improve the documentation and maintenance of existing systems by furnishing an explicit specification of class and object interactions and their underlying intent”. A pesar de esto son reconocidos sólo algunos de los estudios empı́ricos que evalúan la eficacia y la eficiencia de los patrones de diseño en el mantenimiento del código fuente [2] [3]. El alcance del proyecto de investigación realizado por estudiantes de la Especialización de Ingenierı́a de Software de la Universidad Distrital Francisco José de Caldas, es realizar una estadı́stica del estado actual del uso de los 23 patrones de diseño de GoF, cuantificar su usabilidad y determinar si estos son una buena práctica, medida desde la perspectiva de evolución y escalabilidad de un programa de software. Para esto se tomará una muestra de 100 proyectos desarrollados en empresas de la ciudad de Bogotá. El estudio de esta investigación es independiente de la metodologı́a de proceso de desarrollo que haya elegido usar cada empresa, en donde se toman como actividades básicas 1.
(18) Análisis del impacto del uso de patrones de diseño en la fase de mantenimiento en el ciclo de desarrollo de software la fase de especificación de los requerimientos, Implementación del diseño y mantenimiento. La materia prima para la investigación se obtendrá de un trabajo de campo, aplicando una encuesta como técnica de recolección de información, en la que los datos serán tabulados, ordenados y procesados usado un método estadı́stico para la presentación de un informe y postulación de recomendaciones que permitan mejorar o simplemente ratificar los procesos que se realizan actualmente en las tres fases del ciclo de vida tomados en esta investigación. Adicional al análisis estadı́stico, se expone un modelamiento de los 25 puntos de vista arquitectónicos con lenguaje Archimate, con el fin de exponer la arquitectura empresarial que debe adoptar una empresa de desarrollo de software que realice la construcción de un servicio web de diagnóstico de evaluación de buenas prácticas basados en la tabulación de información obtenida a través de una encuesta. Este documento plantea en la parte inicial: El problema de investigación, su formulación, su sistematización y Justificación enmarcada en un tipo de investigación especı́fico. En una sección intermedia: Se expone el marco de referencia en cuanto a la teorı́a fuentes primarias y secundarias marco conceptual e hipótesis del trabajo. Posteriormente, se expone un modelamiento de los 25 puntos de vista arquitectónicos con lenguaje archimate y en la parte final de este documento después de tabular, ordenar y procesar la información se una hace una presentación de los resultados obtenidos,bibliografı́a consultada para el proyecto de investigación.. 2.
(19) Especialización en Ingenierı́a de Software. 3.
(20) Análisis del impacto del uso de patrones de diseño en la fase de mantenimiento. 4.
(21) Capı́tulo 1 DEFINICIÓN DEL TEMA DE INVESTIGACIÓN Análisis sobre el impacto del uso de patrones de diseño en la fase de mantenimiento del software.. 1. 1 .1.. PROBLEMA DE INVESTIGACIÓN PLANTEAMIENTO DEL PROBLEMA. Los Analistas y Programadores van desarrollando a diario habilidades para resolver problemas usuales que se presentan en el desarrollo del software, por cada problema que se presenta surgen distintas formas de resolverlo, de las cuales algunas pueden resultar exitosas quizá basadas en métodos que ya se han usado anteriormente, sin embargo, siempre habrán una sola solución que mejor se adapte a la aplicación brindando flexibilidad, robustez y estructura en su diseño y mantenimiento. En 1994, se publicó el libro ”Design Patterns: Elements of Reusable Object Oriented Sofware” escrito por los ahora famosos Gang of four formada por Erich Gamma, Richard Helm, Ralph Johnson y John Vlissides[1]. Ellos se dieron cuenta que recopilando, y documentando las mejores soluciones planteadas por los expertos, se podrı́a compartir con los nuevos desarrolladores de software y ası́ se agilizarı́an y resolverı́an de la mejor manera un problema especı́fico [2]. Para desarrollar aplicaciones robustas y fáciles de mantener, se deben cumplir ciertos lineamientos, es allı́ donde los patrones de diseño ayudan a cumplir muchos de estos principios o reglas para desarrollar aplicaciones de software. Dada nuestra experiencia como profesionales en el área del desarrollo, vemos su uso reducido por falta de conocimiento de la existencia de estos, por desconocimiento de su correcta utilización o porque simplemente se decide no aplicarlos; sin tener en cuenta 5.
(22) Análisis del impacto del uso de patrones de diseño en la fase de mantenimiento que si no se hace, hay que ser conscientes de la razón de no aplicarlos y de sus consecuencias al no utilizarlos ya que no debemos caer nuevamente en una crisis de software en donde el mantenimiento de una aplicación es más costoso que volverlo a hacer, por su código inmantenible que dificulta la gestión y evolución. Adicional a lo anterior, vemos que no se proyecta el uso de una arquitectura de patrones de diseño desde las fases iniciales del proceso de desarrollo de software; dicha proyección inicial, es importante ya que apoya el aumento de la calidad en el proceso de desarrollo del producto obtenido y estandariza el código fuente de una aplicación para facilitar su mantenimiento. Para controlar y evitar esta situación se necesita estudiar a profundidad los patrones de diseño más utilizados configurando un catálogo de patrones que se puedan consultar para la solución de problemas de diseño concretos; además que ayuden a evaluar el esfuerzo y la eficiencia para realizar operaciones de mantenimiento en software en donde fueron aplicados patrones; ya que lo que determina si un programa está bien diseñado es si su mantenimiento es fácil. Por lo anterior como problema de investigación se pretende estudiar el análisis del impacto del uso de patrones de diseño en la fase de mantenimiento e identificar su presencia en las fases de especificación de los requerimientos de software e implementación del diseño de desarrollo, con el fin de determinar buenas prácticas con el uso de patrones, bajo la premisa de que un software sea fácilmente escalado, validado y evolucionado; estas actividades se realizan en la fase de mantenimiento. Para esto se tomará una muestra de proyectos de software, construidos en empresas de la industria de producción de software en Bogotá y empresas de otros sectores que tienen proyectos de desarrollo de software internos.. 1 .2.. FORMULACIÓN DEL PROBLEMA. ¿En las actividades de validación y evolución del software, se reduce el esfuerzo de Programadores en la corrección de errores, con la concepción del uso de patrones de diseño de GoF en las fases iniciales del proceso de software, tales como, especificación e implementación?. 1 .3.. SISTEMATIZACIÓN DEL PROBLEMA. ¿Cuál es el grado de usabilidad de los patrones de GoF actualmente en los proyectos de software? ¿Cuáles son los patrones de diseño de software más utilizados? ¿Se tiene en cuenta desde la fase de especificación el uso de patrones de Diseño de GoF? ¿Los proyectos de software que usan patrones de diseño pueden evolucionar con mayor facilidad que aquellos que no los aplican? 6.
(23) Especialización en Ingenierı́a de Software. 7.
(24) Análisis del impacto del uso de patrones de diseño en la fase de mantenimiento. 8.
(25) Capı́tulo 2 OBJETIVOS 1.. OBJETIVO GENERAL. Evaluar el uso de patrones de GoF como base teórica para evaluar su contribución en el mantenimiento de los programas, como una buena práctica mediante un trabajo estadı́stico que describe el uso de los patrones de diseño de software en una muestra de 100 proyectos de desarrollo construidos por empresas ubicadas en la ciudad de Bogotá.. 2.. OBJETIVOS ESPECÍFICOS Recopilar información sobre los patrones de diseño usando diferente bibliografı́a para definir el marco conceptual base del estudio del proyecto. Diseñar una encuesta como técnica de recolección de datos, para aplicarla a 100 proyectos de desarrollo de software en empresas ubicadas en la ciudad de Bogotá. Analizar los efectos del uso de patrones de diseño en la calidad del software utilizando los datos recolectados en el trabajo de campo para dar respuesta a la hipótesis y formulación de problema planteada en este proyecto. Presentar conclusiones de acuerdo a los resultados de la estadı́stica realizada, mediante la técnica de análisis exploratorio de datos produciendo una representación visual para un amplio entendimiento de la investigación.. 9.
(26) Análisis del impacto del uso de patrones de diseño en la fase de mantenimiento. 10.
(27) Capı́tulo 3 ALCANCES Y LIMITACIONES 1.. ALCANCES. El alcance del proyecto de investigación realizado por estudiantes de la Especialización en Ingenierı́a de Software de la Universidad Distrital Francisco José de Caldas, es realizar un estudio acerca del estado actual del uso de los 23 patrones de diseño de GoF[1] en una muestra de más de 100 proyectos elaborados en empresas que mantengan y/o construyan software en la ciudad de Bogotá, cuantificando su usabilidad con el fin de determinar buenas prácticas con el uso de patrones dado que un software sea fácilmente validado y evolucionado; actividades que se realizan en la fase de mantenimiento. El resultado se obtendrá de un trabajo de campo en donde a través de una encuesta como técnica de recolección de información se pretende dar una aproximación de los pros y contras al utilizarlos, enfocados a la facilidad en la evolución de los sistemas de software en los que se encontró aplicados.. 2.. LIMITACIONES. Este proyecto se limita al estudio de la teorı́a de los 23 patrones de diseño de desarrollo de software de GoF[1] y a la presentación de los resultados de la estadı́stica de los proyectos de una muestra de más de 100 proyectos de empresas que elaboren software en Bogotá, realizada mediante la técnica de análisis exploratorio de datos y gráficas estadı́sticas.. 11.
(28) Análisis del impacto del uso de patrones de diseño en la fase de mantenimiento. 12.
(29) Capı́tulo 4 JUSTIFICACIÓN Es importante llevar a cabo este proyecto porque permite cuantificar el uso de los patrones de diseño de GoF, identificando su participación en las fases iniciales en el proceso de desarrollo, desde la concepción misma de la especificación de los requerimientos, y su afectación en la validación y evolución del proyecto. Esto con el fin de identificar si el uso de los patrones son o no una buena práctica en el proceso de desarrollo de software. Partiendo del hecho de que ninguna solución es perfecta, pues se presentan problemas de flexibilidad, bajo rendimiento y errores comunes en el funcionamiento del servicio de la aplicación, que hacen que el software sea difı́cil de escalar, se hace importante determinar buena prácticas en la construcción para reducir tiempos, eliminar fallas y lograr un producto de calidad a la medida de las necesidades del cliente. En la actualidad los programadores se enfocan explı́citamente a su tarea de programar y dejan a un lado el hecho de que construir software es un proceso de resolución de problemas, que amerita un lenguaje común entre los programadores, ya que conocidos los conceptos se podrá determinar cómo fue diseñado un programa y podrá plantear una solución sin consecuencias negativas en el futuro; facilitando la escalabilidad y evolución de los programas de software. El tipo de investigación de este proyecto es teórica ya que profundiza el enfoque planteado en los patrones de diseño de GoF y pretende avanzar en el conocimiento de los mismos para mejorar su aplicabilidad en el mundo real, reduciendo esfuerzos en el mantenimiento de la aplicación, partiendo de la definición de estos desde la fase inicial de ciclo de vida de software. La fuente primaria de información de este estudio es una encuesta dirigida y aplicada a proyectos de software de diferentes caracterı́sticas, para el análisis de resultados. La investigación de este proyecto, aportará para que la ingenierı́a de software retome su lugar de credibilidad y rompa el mito de que no es posible dar solución efectiva a un error determinado sin consecuencias previstas y controladas minimizando esfuerzo sin sacrificar calidad y rendimiento. 13.
(30) Análisis del impacto del uso de patrones de diseño en la fase de mantenimiento. 14.
(31) Capı́tulo 5 MARCO DE REFERENCIA 1.. MARCO TEÓRICO. 1 .1.. COMPONENTES DE LOS PATRONES DE DISEÑO. Para que una solución sea considerada un patrón debe poseer unos componentes fundamentales: Nombre del patrón: Permite describir en pocas palabras un problema de diseño junto con sus soluciones y consecuencias. Problema: Indica cuándo aplicar el patrón, explica el patrón y su contexto en algunas oportunidades el problema incluye una serie de condiciones que deben darse para aplicar el patrón. Podrı́a incluir diseños especı́ficos de como representar algoritmos como objetos, también, podrı́a definir estructuras de clases u objetos que son sintomáticos de un diseño flexible. Solución : No describe una solución o implementación en concreto, sino que un patrón es más bien como una plantilla que puede aplicarse en diversas situaciones diferentes. El patrón brinda una descripción abstracta de un problema de diseño y cómo lo resuelve una determinada disposición de objetos. Consecuencias: Son los resultados esperados y las ventajas y desventajas de aplicar dicho patrón. Aunque las consecuencias son a menudo no descritas cuando se toman las decisiones de diseño, estas son determinantes a la hora de evaluar diseños alternativos y entender los costos y beneficios de aplicar el patrón. El re-uso es con frecuencia un factor en el diseño orientado a objetos, las consecuencias de un patrón deben incluir el impacto en la flexibilidad, extensibilidad y/o portabilidad de un sistema. 15.
(32) Análisis del impacto del uso de patrones de diseño en la fase de mantenimiento. 1 .2.. TAXONOMÍA DE UN PATRÓN. Nombre del patrón y clasificación: El nombre del patrón transmite la esencia del patrón brevemente, un buen nombre es vital porque este convertirá en parte de nuestro vocabulario de diseño, la clasificación del patrón refleja el propósito de solución del mismo. Intención: Una corta declaración que responda las siguientes preguntas: ¿Que hace el patrón de diseño?, ¿Cuál es su razón de ser e intención?, ¿En particular que problema de diseño o asunto de diseño se aborda? También conocido como: Otros nombres por los que se les conozca a este patrón, si existe alguno. Motivación: Un escenario que ilustre un problema de diseño y como las estructuras de clases y objetos del patrón solucionan el problema, El escenarios le ayudará a entender de forma más abstracta la descripción del patrón. Aplicabilidad: ¿En que situaciones puede ser aplicado el patrón?, ¿Cuáles son los diseños pobres donde el patrón puede ser usado?, ¿Cómo puede reconocer esas situaciones?. Estructura: Una representación gráfica de las clases basado en una técnica de notación de modelado de objetos, también se usan diagramas de interacción para ilustrar la secuencia de solicitudes y colaboraciones entre objetos. Participantes: Clases u objetos participantes en el diseño del patrón y sus responsabilidades. Colaboradores: Cómo los participantes colaboran para llevar a cabo sus responsabilidades. Consecuencias: ¿Cómo el patrón apoya estos objetivos?, ¿Cuáles son las ventajas y desventajas y resultados de aplicar este patrón?. Implementación: ¿Qué trampas, consejos o técnicas deberán ser tenidas en cuenta a la hora de la implementación de un patrón?. Ejemplo de código: En un lenguaje especı́fico o pseudocódigo la forma de ilustrar el cómo se implementarı́a el patrón. Usos conocidos: Ejemplos reales donde el patrón ha sido aplicado, Patrones relacionados: ¿Qué patrones de diseño están cercanamente relacionados a este patrón?, ¿Cuáles son las diferencias importantes entre estos y que patrones pueden ser usados en este patrón?. 16.
(33) Especialización en Ingenierı́a de Software. 1 .3.. CLASIFICACIÓN DE PATRONES. 1. Patrones Arquitectónicos Centrados en la arquitectura del sistema. Definen una estructura fundamental sobre la organización del sistema. Proveen un conjunto predefinido de subsistemas, cuáles son sus responsabilidades y como se interrelacionan. 2. Patrones De Diseño Son esquemas para refinar los subsistemas o componentes de un sistema de software, o sus relaciones. Describen una estructura recurrente y común de componentes comunicantes, que resuelven un problema de diseño dentro de un contexto. Estos se dividen en tres tipos: Patrones de Creación: Abstraen el proceso de creación de instancias de objetos. Ayudan a hacer a un sistema independiente de cómo se crean, se componen y se representan sus objetos. Patrones Estructurales: Tratan con la composición de clases u objetos. Se ocupan de cómo las clases y objetos se utilizan para componer estructuras de mayor tamaño. Patrones de Comportamiento: Caracterizan el modo en que las clases y objetos interactúan y se reparten la responsabilidad. 3. Patrones De Codificación o Modismos ( IDIOMS): Patrones que ayudan a implementar aspectos particulares del diseño en un lenguaje de programación especı́fico.. 1 .4.. CATÁLOGO DE PATRONES. El principal catálogo de patrones de diseño es (Gamma et al, 1995), el cual consta de 23 patrones de diseño agrupados en tres grupos: Patrones Creacionales, Patrones Estructurales y Patrones de Comportamiento. En las siguientes secciones se lista cada uno de ellos.. 1. PATRONES ESTRUCTURALES ADAPTER Propósito: Sirve como un intermediario entre dos clases, convirtiendo las interfaces de una clase para que pueda ser utilizado por otra, es decir, convierte una interfaz de 17.
(34) Análisis del impacto del uso de patrones de diseño en la fase de mantenimiento una clase para que se adapte a lo que el cliente que la usa necesita, permitiendo ası́ que trabajen juntas clases cuyas interfaces son incompatibles. Aplicabilidad: * Desee utilizar un objeto en un entorno que espera una interfaz distinta de la ofrecida. * Desee utilizar un objeto en un entorno que espera una interfaz de la ofrecida por el objeto. * Deba realizar una traducción entre las interfaces de varios objetos. * Quiere crear una clase reutilizable que coopera con clases desvinculadas o imprevistas, es decir clases que no tiene interfaz compatible necesariamente. * Un objeto deba actuar como intermediario para un grupo de clases, y solo es posible saber en tiempo de ejecución que clase será utilizada. Usted quiere usar una clase existente y su interfaz no combina con una que usted tiene. Descripción: Cuando necesito utilizar una clase en un framework sin tener que modificarla para adaptarla al nuevo entorno utiliza este patrón diseñando una clase Adapter que actúe como traductor; esta clase recibe llamadas del entorno y modifica esas llamadas para que sean compatibles con la clase Adaptee. Los entornos tı́picos en los que puede ser útil este patrón incluyen aplicaciones que soportan plug-ins como los editores gráficos, de texto o multimedia. Los navegadores web son otro entorno en el que el patrón Adapter puede ser útil. Implementación: * Framework (framework) Utiliza el Adapter, puede construir el ConcreteAdapter u obtenerlo de alguna forma. * Adapter (Adaptador): Interfaz que define los métodos utilizados por el framework. * ConcreteAdapter (Adaptador concreto): Implementación de la interfaz Adapter: Mantiene una referencia a Adaptee y traduce las llamadas de los métodos del framework en llamadas al Adaptee. Esta traducción puede implicar alguna tarea de encapsulación o modificación de los argumentos y de los tipos de retorno. Otro desafı́o para este patrón es la transferencia de argumentos, debido a que los argumentos recibidos no son siempre compatibles entre l framework y el Adaptee. * Adaptee (Adaptado): Interfaz que define los métodos que serán adaptados. Esta interfaz permite que se cargue dinámicamente el Adaptee especı́fico en tiempo de ejecución. 18.
(35) Especialización en Ingenierı́a de Software * ConcreteAdaptee (Adaptado concreto): Implementación de la interfaz Adaptee. La clase que necesita ser adaptada para que pueda ser utilizada por el framework. Ventajas y Desventajas: * Ofrece una gran oportunidad para la reutilización del código, permitiendo que interactúen dos o más objetos que supuestamente son incompatibles. Sin embargo, es necesario algún tipo de planificación y previsión para poder desarrollar un framework lo suficientemente flexible como para que pueda ser adaptado convenientemente. Este problema tiene dos aspectos diferenciados: la estructura de las llamadas a funciones y los argumentos de traducción. * En caso de que haya una falta de correspondencia funcional entre las llamadas del framework y el Adaptee, el Adapter necesita gestionar los requerimientos de las llamadas del Adaptee, lo cual puede ser realizado mediante la invocación de cualquier método de configuración entes de la llamada al framework. * Otro desafı́o para este patrón es la transferencia de argumentos, debido a que los argumentos recibidos no son siempre compatibles entre l framework y el Adaptee. * Facilidad para redefinir el comportamiento de la clase adaptada. * Inflexibilidad, puesto que un sólo adaptador no puede trabajar con una clase y sus hijos a la vez. COMPOSITE. Propósito: Desarrollar una forma flexible de crear jerarquı́as en estructura de árbol de una complejidad arbitraria, permitiendo a la vez que todos los elementos de la estructura funcionen con una interfaz uniforme, es decir, permite a los clientes tratar uniformemente a los objetos simples y compuestos de una estructura jerárquica recursiva. Aplicabilidad: * Haya un componente modelado como una estructura parte-todo. * La estructura pueda tener cualquier nivel de complejidad y sea dinámica. * Desee tratar uniformemente la estructura del componente, utilizando operaciones comunes en toda la jerarquı́a. * Se necesitan desarrollar aplicaciones con diagramas organizativos, de descomposición de tareas, planificaciones y guiones. 19.
(36) Análisis del impacto del uso de patrones de diseño en la fase de mantenimiento Descripción: Se utiliza el modelo todo-parte, este modelo permite tratar una colección de objetos idénticos (las partes) como una entidad (el todo). Normalmente estas estructuras deben ser flexibles y fáciles de usar, los usuarios deben poder modificar la estructura conforme se ejecuta la aplicación, introduciendo o eliminando partes para adaptarla a sus necesidades. Permite construir objetos complejos mediante composición recursiva de objetos similares. El patrón Composite también permite que los objetos del árbol sean manipulados por un manejador consistente, para requerir todos los objetos hay una superclase o un interfaz común. Permite a los clientes tratar de la misma manera tanto a objetos individuales como a compuestos. El patrón composite soporta estas caracterı́sticas definiendo una estructura de clase que incorpora la extensibilidad; esta estructura se compone de un componente, una hoja y una clase Composite: * El componente base proporciona el modelo principal, el cual define los métodos estándar o las variables que se utilizan en todos los objetos del patrón. * Las clases hoja contienen el comportamiento final. Es decir, representan las partes del Composite, pero no pueden contener otros componentes. * Las clases Composite, o ramas, pueden tener otros componentes, permitiendo la extensibilidad de la estructura compuesta. Implementación: * Component (Componente): Interfaz en la que se definen los métodos disponibles para todas las partes de la estructura. Puede ser implementado como una clase abstracta cuando es necesario proporcionar un comportamiento estándar a todos los subtipos. Normalmente el componente nos es instanciable, sus subclases, o las que lo implementan (nodos), son instanciables y se utilizan para crear una colección o una estructura de árbol. * Composite (Compuesto): Esta clase queda definida por los componentes que alberga, está compuesta por sus componentes. Esta clase soporta un grupo dinámico de objetos Component, y por ello tiene una serie de métodos para insertar y eliminar instancias de Componente de la colección. Los métodos definidos en esta clase se implementan para ejecutar el comportamiento especı́fico del tipo de Composite y llamar al mismo método en todos sus nodos. Las clases Composite también son denominadas ramas o clases contenedor. * Leaf (Hoja): Clase que implementa la interfaz Component y proporciona una implementación para todos los métodos de Component. La diferencia entre una clase leaf y una clase Composite es que leaf no contienen referencias a otros objetos composite. Las clases leaf representan el nivel más bajo de la estructura contenida. 20.
(37) Especialización en Ingenierı́a de Software Ventajas y Desventajas: * Proporciona una potente combinación: una gran flexibilidad en la estructura y una interfaz extremadamente manejable. * Simplifica notablemente al cliente, al no tener éste que distinguir entre objetos simples y compuestos. * Favorece la extensibilidad, ya que es muy fácil añadir nuevos tipos de componentes, tanto simples como compuestos. * La estructura puede ser manejada en cualquier momento llamando a los métodos apropiados de un objeto Composite para insertar o eliminar objetos Component. La modificación de un componente del Composite significa que es posible modificar el comportamiento de los objetos compuestos. * Sin importar la posición actual sobre la estructura, se puede llamar al mismo método en todos los componentes individuales. * El uso de interfaces incrementa aún más la flexibilidad. Las interfaces permiten la construcción de framework utilizando el patrón Composite y facilitan la introducción de los nuevos tipos en tiempo de ejecución. * Otro inconveniente del patrón se deriva de su flexibilidad, al ser tan dinámico el patrón suele ser difı́cil de probar y depurar. Normalmente necesitarı́a una estrategia de prueba con validación más sofisticada y que esté diseñada en torno al concepto jerarquı́a todo-parte. * Requiere un amplio conocimiento de la estructura que se va a modelar o un mecanismo de carga de clases más sofisticadas. * Puede hacer el diseño peligrosamente genérico, dificultando la imposición de restricciones sobre ciertos componentes de la jerarquı́a. DECORATOR Propósito: Proporciona una forma flexible de introducir o eliminar funcionalidades de un componente sin modificar su apariencia externa o su función, es decir, adiciona responsabilidades a un objeto dinámicamente, proporcionando una alternativa flexible a la especialización mediante herencia, cuando se trata de añadir funcionalidades. Aplicabilidad: * Cuando desee hacer cambios dinámicos que sean transparentes a los usuarios, sin las restricciones que implica la creación de subclases, es decir, que adicione responsabilidades a objetos individuales enérgicamente y transparentemente sin afectar otros objetos. 21.
(38) Análisis del impacto del uso de patrones de diseño en la fase de mantenimiento * Se puedan introducir o eliminar capacidades de los componentes en tiempo de ejecución. * Hay caracterı́sticas que varı́en independientemente, que deben ser aplicadas dinámicamente y que pueden ser combinadas arbitrariamente sobre un componente. Descripción: Extiende la funcionalidad de un objeto dinámicamente de tal modo que es transparente a sus clientes, utilizando una instancia de una subclase de la clase original que delega las operaciones al objeto original. Provee una alternativa muy flexible para agregar funcionalidad a una clase. Permite que se puedan introducir o eliminar capas a partir de un objeto base. Cada capa puede proporcionar un comportamiento (métodos) y estados (variables) para ampliar el objeto base. Utilizando este patrón, se pueden encadenar y asociar las capas libremente, permitiendo la creación de comportamientos avanzados a partir de unos bloques simples. Permite construir funcionalidades como un compendio de filtros aplicados a un modelo base. La entrada / salida basada en flujos o los terminales de comunicaciones son algunos ejemplos. Implementación: * Component (Componente): Representa el componente que contiene el comportamiento genérico, puede ser una clase abstracta o una interfaz. * Decorador (Decorador): Define los comportamientos estándar que se esperan en todos los decoradores; puede ser una clase abstracta o una interfaz. También proporciona soporte para contener otros Decorador, es decir, mantiene una referencia a un objeto Component, que puede ser un objeto Component u otro decorador. Definiendo la jerarquı́a de clases Decorador como una subclase de los componentes que se amplı́an, la misma referencia puede ser utilizada para cualquier propósito. * ConcreteDecorator (Decorador concreto): puede ser una o más clases. Cada subclase de Decorador necesita soportar modificaciones (referencia a un componente, más la habilidad de insertar o eliminar esa referencia). Más allá de los requerimientos básicos, cada Decorador puede definir métodos adicionales y/o variables para ampliar el componente. Ventajas y Desventajas: * Ofrece la oportunidad de ajustar y aumentar fácilmente el comportamiento de un objeto en tiempo de ejecución. Además el trabajo relacionado con la programación se hace más sencillo, porque cada clase contiene una parte especı́fica de funcionalidad. En otro caso, habrı́a que programar todos los comportamientos en el propio componente. 22.
(39) Especialización en Ingenierı́a de Software * Tiende a hacer que el comportamiento sea ampliado más fácilmente en el futuro, porque los cambios se pueden introducir mediante la creación de nuevas clases. Dependiendo de su comportamiento produce un gran número de capas. La depuración y verificación del código se hacen más complicadas y la velocidad de un sistema puede reducirse si el patrón no se diseña apropiadamente. * Aporta una mayor flexibilidad que la herencia estática, permitiendo, entre otras cosas, añadir una funcionalidad dos o más veces. * Evita concentrar en lo alto de la jerarquı́a clases ?guiadas por las responsabilidades?, es decir, que pretenden (en vano) satisfacer todas las posibilidades. De esta forma las nuevas funcionalidades se componen de piezas simples que se crean y se combinan con facilidad, independientemente de los objetos cuyo comportamiento extienden. * Un inconveniente es la fragmentación, pues el sistema se llena de gran cantidad de objetos pequeños, lo cual puede dificultar el aprendizaje de su funcionamiento y su depuración, aunque el que lo domine puede adaptarlo fácilmente. PROXI. Propósito: Sirve como un intermediario entre dos clases, convirtiendo las interfaces de una clase para que pueda ser utilizado por otra, es decir, convierte una interfaz de una clase para que se adapte a lo que el cliente que la usa necesita, permitiendo ası́ que trabajen juntas clases cuyas interfaces son incompatibles. Aplicabilidad: * Utilice el patrón Proxy cuando necesite una referencia más elaborada a un objeto que una referencia simple: * Proxy remoto: Cuando necesite un representante local para un objeto en otro espacio de direcciones (JVM). * Proxy virtual: Actúa como un representante y difiere la creación de objetos costosos. * Proxy protector: Establece los derechos de acceso al objeto real. * Cargar un centro persistente en la memoria cuando es mencionado primero. Descripción: Un Proxy es un representante para otro objeto. Para permitir que el Proxy represente al objeto real, tiene que implementar exactamente la misma interfaz que el objeto real, además este maneja una referencia con el objeto real. Esta referencia 23.
(40) Análisis del impacto del uso de patrones de diseño en la fase de mantenimiento es necesaria para poder llamar a los métodos del objeto real en caso de que sea necesario. Los clientes interactúan con el Proxy, pero éste puede delegar la ejecución en el objeto real. El Proxy implementa la misma interfaz que el objeto real, pero puede ejecutar algunas tareas que no puede realizar el objeto real, como son la comunicación remota o la seguridad. El proxy es una especie de escaparte para el objeto representado. Implementación: * Service (Servicio): Interfaz implementada por el proxy y por el objeto real. * ServiceProxy (Proxy del servicio): Implementa la interfaz service y redirige las llamadas de los métodos al objeto real (ServiceImpl) cuando sea apropiado. * ServiceImpl (Implementación del servicio): Implementación real y completa de la interfaz. Este objeto estará representado por el objeto proxy. Ventajas y Desventajas: Las consecuencias de este patrón varı́an considerablemente dependiendo del tipo especı́fico de proxy. * Proxy remoto: La ventaja del proxy remoto es que puede ocultarse la red al cliente. El cliente pensará que tiene un objeto local que hace el trabajo. De hecho, tiene un objeto que envı́a una petición por la red para finalizar el trabajo. No olvide que un inconveniente a este patrón es que, como no sabe que está trabajando sobre una red, podrı́a no estar preparado para las penalizaciones de tiempo que pueden ocurrir. * Proxy virtual: La gran ventaja es que tiene un sustituto con el que interactuar y no tienen que crear el producto real hasta que lo necesite realmente. Además, puede llevar a cabo algunas optimizaciones sobre cuándo y cómo crear el objeto real. * Proxy protector: La gran ventaja de este proxy es que puede establecerse el control de acceso. FACADE Propósito: Proporcionar una interfaz simplificada y unificada de alto nivel para un grupo de subsistemas o un sistema complejo. La fachada satisface a la mayorı́a de los clientes, sin ocultar las funciones de menor nivel a aquellos que necesiten acceder a ellas. Aplicabilidad: 24.
(41) Especialización en Ingenierı́a de Software * Simplificar el uso de los subsistemas complejos proporcionando una interfaz más sencilla sin eliminar las opciones avanzadas. * Reducir el acoplamiento entre los clientes y los subsistemas. Introducir capas en los subsistemas proporcionando fachadas para grupos de subsistemas. Descripción: Simplifica los accesos a un conjunto de objetos relacionados proporcionando un objeto que todos los objetos de fuera del conjunto utilizan para comunicarse con el conjunto. Define una interfaz de más alto nivel que permite usar el sistema más fácil, es decir, proporciona las opciones más básicas de un sistema para que sea más fácil para el cliente y determina que subsistemas debe llamar. Este patrón delega la mayorı́a del trabajo en los subsistemas, aunque también puede cumplir alguna función. La intención de este patrón no es esconder los subsistemas, la intención es proporcionar una interfaz más simple para un conjunto de subsistemas, permitiendo que los clientes más avanzados puedan utilizar las opciones más elaboradas y trabajen directamente con los subsistemas. Implementación: * Facade (Fachada): Clase que utilizan los clientes. Conoce los subsistemas utilizados y sus respectivas responsabilidades. Normalmente, todas las peticiones de los clientes serán delegadas a los subsistemas apropiados. * Subsystem (Subsistema): Son conjuntos de clases. Pueden ser utilizados directamente por los clientes o hacer el trabajo asignado a ellos por el objeto Facade. No conocen el objeto Facade, para los subsistemas el facade solo será otro cliente. Ventajas y Desventajas:. * Proporciona una interfaz más simple para un sistema complejo sin reducir las opciones proporcionadas por el conjunto del sistema. * Al separar al cliente de los componentes del subsistema, se reduce el número de objetos con los que el cliente trata, facilitando ası́ el uso del sistema, protegiendo al cliente de la sobreabundancia de opciones. * Se promueve un acoplamiento débil entre el subsistema y sus clientes, eliminándose o reduciéndose las dependencias. También puede ser utilizado para reducir el acoplamiento entre los subsistemas. * Traduce las peticiones del cliente a los subsistemas que pueden cumplir esas peticiones. Además como el cliente interactúa con el fachada, el funcionamiento interno del sistema puede ser modificado, mientras que el cliente permanece igual. 25.
(42) Análisis del impacto del uso de patrones de diseño en la fase de mantenimiento * No existen obstáculos para que las aplicaciones usen las clases del subsistema que necesiten. De esta forma podemos elegir entre facilidad de uso y generalidad. BRIDGE. Propósito: Dividir un componente complejo en dos jerarquı́as relacionadas: la abstracción funcional y la implementación interna, para que sea más fácil cambiar cualquier aspecto del componente, es decir, separa una abstracción de su implementación para permitir que ambos puedan variar independientemente. Aplicabilidad: Desee flexibilidad entre la abstracción y la implementación del componente, evitando una relación estática entre ambas. Es útil cuando hay una jerarquı́a de abstracciones y la correspondiente jerarquı́a de implementaciones. Los cambios en la implementación no deban ser visibles a los clientes. Identifique múltiples abstracciones e implementaciones de componentes. Es apropiado crear subclases, pero quiere gestionar independientemente los dos aspectos del sistema. Usted quiere evitar una encuadernación permanente entre un concepto abstracto y su puesta en práctica. Esto podrı́a ser el caso, por ejemplo, cuando la puesta en funcionamiento debe ser seleccionada o cambiada en tiempo de ejecución. Descripción: La herencia asocia un componente con un modelo estático, haciendo difı́cil cambiarlo en el futuro. Cambiar un componente es un desafı́o porque tienden a variar conforme se va modificando y utilizando el sistema. Serı́a preferible crear una forma dinámica de modificar aspectos de los componentes según sea necesario. Este patrón resuelve el problema desacoplando los dos aspectos del componente; con dos cadenas de herencia separadas, una dedicada a la funcionalidad y otra a la implementación, con esto es mucho más fácil mezclar y asociar los elementos de cada lado, esto proporciona una flexibilidad general con un menor coste de codificación. Además los requisitos de codificación para el patrón Bridge ofrecen un ahorro general en cuanto al número de clase escritas conforme va incrementándose el número de variaciones. Es decir, más que combinar las abstracciones e implementaciones en muchas clases distintas, el patrón Bridge implementa las abstracciones e implementaciones como clases independientes que se pueden combinar dinámicamente. Es decir, desacopla una abstracción de su implementación y les permite variar independientemente.. Implementación: 26.
(43) Especialización en Ingenierı́a de Software * Abstraction (Abstracción): Define la abstracción funcional de Bridge, proporcionando un comportamiento y una estructura estándar. Contiene una referencia a una instancia de implementación, esa instancia normalmente se fija por medio de un método set (permite que sea modificada en tiempo de ejecución) o a través de un constructor. * RefineAbstraction (Abstracción refinada): Hereda de la clase Abstraction y proporciona un comportamiento adicional o modificado. * Implementation (Implementación): interfaz que representa la funcionalidad utilizada por las instancias de Abstraction. * ConcreteImplementation (Implementación concreta): Implementa la interfaz Implementation, proporciona el comportamiento y la estructura para las clases Implementation. Ventajas y Desventajas:. * Ofrece la posibilidad de compartir las implementaciones de los objetos entre múltiples objetos (Abstracción) y proporciona una mayor flexibilidad cuando se cambian las implementaciones, y los cambios pueden suceder sin que el cliente tenga que tomar parte en ninguna acción. * La separación entre interfaz e implementación permite configurar (y cambiar) esta relación dinámicamente, en tiempo de ejecución (y no de compilación). Además, esta independencia favorece una mejor estructuración en niveles del sistema. La citada independencia de variación repercute en una mayor extensibilidad. * Se favorece el encapsulamiento, al ocultarse a los clientes detalles referentes a la implementación, como la compartición de implementaciones. * Cuando se diseña una aplicación que utiliza este patrón, es importante definir apropiadamente qué responsabilidades pertenecen a las abstracciones funcionales y cuáles a la clase de implementación interna, y ası́ mismo, lo que representa el modelo base de su implementación. Porque un problema común que puede experimentar al utilizar el patrón proviene del desarrollo de la implementación alrededor de una o dos posibles variaciones. El peligro es que el desarrollo futuro del patrón revelará que algunos de los supuestos elementos del comportamiento principal realmente representan variaciones especı́ficas basadas en la abstracción y/o la implementación. FLYWEIGHT. 27.
(44) Análisis del impacto del uso de patrones de diseño en la fase de mantenimiento Propósito: Mejorar la eficiencia a la hora de mantener una gran cantidad de objetos ?granularidad?, usando la idea de la compartición, es decir, reduce el número de objetos detallados de muy bajo nivel en un sistema mediante la compartición de objetos. Un Flyweight es un objeto compartido que puede ser usado en diferentes contextos simultáneamente, de forma transparente, indistinguible. El concepto clave aquı́ es la distinción entre el estado intrı́nseco (información independiente del contexto del objeto, almacenada en el mismo y que favorece su compartición) y el estado extrı́nseco (información que depende y varı́a con el contexto donde se use el objeto, no puede ser compartida y se la proporciona el cliente que lo usa, a través de la fábrica) del objeto compartido. Aplicabilidad: * Aplicación utiliza muchos objetos idénticos o casi idénticos. Para todos los objetos casi idénticos, las partes diferentes pueden ser separadas de las partes similares, permitiendo la compartición de las partes comunes. Los grupos de objetos casi idénticos pueden ser reemplazados por un objeto compartido una vez que las partes diferentes del estado han sido eliminadas. La aplicación necesita diferenciar entre los objetos casi idénticos en su estado original. Utilice el patrón solo cuando es fácil identificar y extraer los datos externos de los objetos, y cuando el número de estados diferentes está limitada. Descripción: Este patrón ha sido pensado para reducir el número de objetos en una aplicación, y lo logra compartiendo los objetos. El objeto compartido es utilizado por varios clientes y es indistinguible de un objeto que no está compartido. Los clientes que manejan el objeto compartido son los responsables de proporcionar y/o calcular la información del contexto. La información es pasada al objeto compartido solo cuando es necesario. Como los objetos son compartidos, un cliente no debe crear un objeto de este tipo directamente, sino obtenerlos por medio de una fábrica (Abstract Factory), esta fábrica asegura la forma apropiada de compartir los objetos. Además no todos los objetos ni las clases implementación tienen por qué ser compartidos; este patrón permite la compartición de objetos pero no es imprescindible. Permite a un programa evitar el coste de múltiples instancias que contienen la misma información compartiendo una única instancia. Soporta la representación de un gran número de objetos pequeños de una manera eficiente. Implementación: * Flyweight (Peso ligero): Interfaz que define los métodos que pueden ser utilizados por los clientes para pasar el estado externo a los objetos Flyweight. 28.
(45) Especialización en Ingenierı́a de Software * ConcreteFlyweight (Peso ligero concreto): Implementa la interfaz Flyweight, y tiene la capacidad de almacenar datos internos. Los datos internos tienen que ser representativos para todas las instancias en las que se necesita el Flyweight. * Flyweight Factory (Fábrica de pesos ligeros): Responsable de crear y manejar los objetos Flyweight. La fábrica puede crear todos los objetos Flyweight al lanzar la aplicación o esperar hasta que son realmente necesarios. * Client (Cliente): Responsable de crear y proporcionar el contexto para los objetos Flyweight. La forma de obtener una referencia a un objeto Flyweight es por medio de FlyweightFactory. Ventajas y Desventajas: Reduce el número de objetos que hay que gestionar; esto puede ahorrar mucho espacio, tanto en memoria como en los dispositivos de almacenamiento, en caso de que sean objetos persistentes. Se ahorra más espacio aún si la información de contexto para los objetos flyweight se calcula en vez de tenerla almacenada. Sin embargo, esto nos lleva al inconveniente de este patrón: el costo en tiempo de ejecución. En lugar de almacenar muchos objetos, los clientes tienen que calcular el contexto y proporcionar esa información a los objetos flyweight. Los flyweight utilizan esta información para calcular/proporcionar funciones. Si se manejan menos objetos y se implementan correctamente, se incrementa el rendimiento. Observe que si hay poca información de contexto y el objeto flyweight es grande, el ahorro puede ser significativo. En los inconvenientes, se introducen costos en tiempo de ejecución asociados a las transferencias, búsquedas y/o computación del estado extrı́nseco (y su almacenamiento).. HALF-OBJECT PLUS PROTOCOL. Propósito: Proporcionar una única entidad que reside en uno o más espacios de direcciones. Aplicabilidad: * Un objeto tiene que residir en dos espacios de direcciones diferentes y no puede ser dividido. Parte de las funciones deben ser ejecutadas de forma remota pero algunos métodos tienen que ser invocados localmente. * Hay que aplicar optimizaciones, como mantener una caché o combinar múltiples peticiones en una única transacción de red, de alguna forma transparente al usuario. 29.
(46) Análisis del impacto del uso de patrones de diseño en la fase de mantenimiento Descripción: El patrón HOPP crea un objeto que implementa las interfaces remotas necesarias y que contenga una referencia al stub original del objeto remoto. Los métodos que deben comportarse normalmente (enviados al objeto remoto) son redirigidos al stub. Los métodos que deben ser ejecutados localmente son manejados por la nueva clase. El nombre HOPP procede del hecho de que el cliente del objeto dividido recibe la mitad del objeto. Esta mitad también contiene el protocolo para comunicarse con la otra mitad, de ahı́ que se llame Protocolo Plus de mitades de objetos Implementación: * HOPP: Interfaz en la que se definen los métodos que están disponibles para el cliente del HOPP. Ambas mitades del objeto HOPP implementan esta interfaz. * LocalHOPP (HOPP local): Clase que implementa la interfaz HOPP. Algunos de los métodos son ejecutados localmente, otros son redirigidos al objeto RemoteObjectProxy. * RemoteObjectProxy (Proxy remoto): Redirige todas las peticiones a la otra mitad del objeto en el otro espacio de direcciones. Este proxy encapsula el protocolo que comunica las dos mitades del objeto. * RemoteOject (Objeto remoto): Esta mitad del objeto HOPP contiene todos los métodos que se ejecutan remotamente. * Client (Cliente): Llama a todos los métodos de la interfaz HOPP. Las llamadas a estos métodos son transparentes para el cliente, sin importar si se está utilizando un proxy remoto, un HOPP o un objeto local. Ventajas y Desventajas:. * Permite tener un objeto que reside en dos espacios de direcciones, sin demasiada sobrecarga. Para los clientes que utilizan una parte del HOPP, es transparente, pues no saben si el objeto reside en uno o más espacios de direcciones, de tal forma que el cliente piensa que está utilizando un objeto local, aún alguna parte de él no lo sea. * También se puede implementar a la inversa, haciendo que el cliente piense que está utilizando un proxy remoto, cuando realmente está utilizando un HOPP que contienen un proxy remoto. Esto tiene la ventaja de que algunos de los métodos que son pensados para ser invocados remotamente, ahora son ejecutados localmente. * Permite optimizaciones concretas para cada objeto. Cada mitad del HOPP puede determinar cuándo y cómo desea comunicarse con la otra mitad. Esta estrategia de comunicación puede mejorar el rendimiento al reducir el 30.
(47) Especialización en Ingenierı́a de Software número de llamadas realizadas por la red sin afectar al código del cliente de ninguno de los extremos. El inconveniente de este patrón es que alguna de la funcionalidad tiene que estar duplicada. Esto es necesario porque cada mitad debe tener suficiente funcionalidad para manejar los objetos locales 2. PATRONES CREACIONALES SINGLETON Propósito: Permite tener una única instancia de la clase singleton en el sistema, a la vez que se permite que todas las clases tengan acceso a esa instancia. Aplicabilidad: * El patrón Singleton se utiliza cuando se quiere tener solo una instancia de una clase pero que deba estar disponible globalmente. Descripción: Este patrón asegura que se crea un máximo de una instancia en la JVM (Máquina virtual de Java). Para asegurar que tiene el control sobre la instanciación, el constructor se hace privado. Se crea el método estático getInstance () para acceder a una instancia de la clase, esta instancia se crea de manera única. La referencia al patrón se almacena como un atributo privado estático de la clase singleton para llamadas futuras. Implementación: Para implementar el patrón Singleton necesita: * Singleton (Único): Proporciona un constructor privado, mantiene una referencia estática a la única PATRONES DE COMPORTAMIENTO: instancia de la clase, y proporciona un método estático de acceso para devolver una referencia a la única instancia. El resto de la implementación de la clase Singleton es completamente normal. El método estático de acceso puede tomar decisiones sobre qué tipo de instancia crear, basándose en las propiedades del sistema los parámetros pasados al método de acceso. Ventajas y Desventajas: Es la única clase que puede crear una instancia de sı́ misma. Aunque no se puede tener ninguna instancia sin utilizar el método estático proporcionado. * No necesita pasar la referencia a todos los objetos que acceden al singleton. 31.
(48) Análisis del impacto del uso de patrones de diseño en la fase de mantenimiento * Puede presentar problemas de acceso en aplicaciones concurrentes dependiendo de cómo se haya realizado la implementación. ABSTRACT FACTORY Propósito: Proporciona un contrato para crear familias de objetos relacionados o dependientes sin tener que especificar su clase concreta Aplicabilidad: * El cliente debe ser independiente del proceso de creación de los productos. * La aplicación debe considerarse con una o más familias de productos. * Es necesario crear los objetos como un conjunto, de forma que sean compatibles. * Desea proporcionar una colección de clases y únicamente quiere revelar sus contratos y sus relaciones, no sus implementaciones. Descripción: Este patrón es útil cuando una aplicación necesita utilizar varios recursos o sistemas operativos, porque se desea que este tipo de aplicaciones sean los suficientemente flexibles como para ser capaces de utilizar distintos recursos sin tener que reescribir el código de la aplicación cada vez que se introduce un recurso nuevo. Una forma efectiva de resolver este problema es definir un creador de recursos genéricos, el patrón Abstract Factory. La fábrica tiene uno o más métodos de creación, que pueden ser llamados para producir recursos genéricos o productos abstractos. Implementación: Para implementar el patrón Abstract Factory necesita los siguientes elementos: * AbstractFactory (Fábrica Abstracta): Clase o interfaz que define los métodos de creación de los productos abstractos. * AbstractProduct (Producto Abstracto): Clase abstracta o interfaz que describe el comportamiento general de los recursos utilizados por la aplicación. * ConcreteFactory (Fábrica concreta): Clase derivada de la fábrica abstracta. Implementa los métodos para crear uno o más productos concretos. * ConcreteProduct (Producto concreto): Clase derivada del producto abstracto, que proporciona una implementación para un recurso o entorno operativo especı́ficos. Ventajas y Desventajas: Ayuda a incrementar la flexibilidad general de una aplicación. Esta se manifiesta tanto en tiempo de ejecución como en tiempo de compilación. 32.
(49) Especialización en Ingenierı́a de Software * Puede simplificar la comprobación del resto de la aplicación. * Para ver las ventajas del patrón hay que definir la interfaz genérica cuidadosamente, de lo contrario puede resultar difı́cil, o incluso imposible, generar algunos de los productos concretos deseados. FACTORY METHOD. Propósito: Permite definir un método estándar para crear un objeto, además del constructor propio de la clase, si la decisión del objeto a crear es delegada en las subclases. Aplicabilidad: * Desea crear un framework extensible. * Desea que sea una subclase, en vez de su superclase, la que decida qué tipo de objeto hay que crear. * Sabe cuándo crear un objeto, pero no conoce el tipo del objeto. * Necesita algunos constructores sobrecargados con la misma lista de parámetros, lo cual no está permitido en Java. En vez de eso, se utilizan varios métodos de fabricación con distinto nombre. Descripción: Este patrón se denomina Factory Method porque crea o fabrica objetos cuando lo necesita. Cuando se empieza a escribir una aplicación se tiene idea de qué tipo de componentes se utilizan y sus respectivas operaciones. Esta flexibilidad puede ser alcanzada utilizando interfaces para estos componentes, aunque el problema de las interfaces es que no se pueden crear objetos; se necesita una clase que las implemente para obtenerlo. En vez de escribir una clase, se puede extraer la funcionalidad del constructor e introducirla en un método, es método es el Método Fábrica. Esto produce un objeto concreto (ConcreteConcreator) cuya responsabilidad es crear los objetos adecuados y crea instancias de una implementación (ConcreteProduct) de una interfaz (Product). Implementación: Para implementar el patrón Factory Method necesita: * Product (Producto): Interfaz de los objetos creados por la fábrica. * ConcreteProduct (Producto concreado): Clase que implementa Product. Los objetos de esta clase son creados por el ConcreteCreator. * Creador (Creador): Interfaz en la que se definen los métodos de fabricación (FactoryMethod) 33.
(50) Análisis del impacto del uso de patrones de diseño en la fase de mantenimiento * ConcreteCreator (Creador concreto): Clase que hereda de Creator y proporciona una implementación para FactoryMethod. Puede devolver cualquier objeto que implemente la interfaz Product. Ventajas y Desventajas:. * Una gran ventaja es que el PIM (Gestor de Información Personal) puede ser muy genérico, solo necesita saber cómo solicitar el editor de un elemento; además hace que este sea más modular, facilitando la introducción de nuevos tipos de información que pueden ser gestionados sin modificar el corazón del propio programa. * El inconveniente de este patrón es el hecho de que, para añadir un nuevo tipo de producto, debe introducir una nueva clase implementación y cambiar un ConcreteCreator que ya existe, o crear una nueva clase que implemente la interfaz Product. BUILDER. Propósito: Simplifica la creación de objetos complejos definiendo una clase cuyo propósito es construir instancias de otra clase. Aunque puede haber más de una clase en el producto, el patrón Builder genera un producto principal porque siempre debe existir una clase principal. Aplicabilidad: Utilice el patrón builder si una clase: * Tiene una estructura interna compleja (especialmente si tiene un conjunto variable de objetos relacionados). * Tiene atributos dependientes entre sı́. * Utiliza otros objetos del sistema que serı́an difı́ciles, o poco convenientes, de obtener durante la creación. Descripción: Está relacionado con la construcción de objetos complejos, posiblemente de diferentes fuentes. Para implementar este patrón se crea una clase (objeto Builder o constructor) responsable de la construcción. El objeto constructor coordina la combinación del objeto producto: creación de recursos, almacenamiento de resultados intermedios y dotación de estructura funcional para la creación. Además el objeto constructor puede adquirir recursos del sistema para la generación del objeto producto. 34.
(51) Especialización en Ingenierı́a de Software. Implementación: Para implementar el patrón Builder necesita: * Director (Director): Tiene una referencia a una instancia de AbstractBuilder. Esta clase llama los métodos de creación de su instancia concreta de AbstractBuilder para tener todas las partes necesarias y poder ası́ construir el objeto. * AbstractBuilder (Constructor abstracto): Interfaz que define los métodos disponibles para crear las distintas partes del producto. * ConcreteBuilder (Constructor concreto): Clase que implementa la interfaz AbstractBuilder. Esta clase implementa todos .los métodos necesarios para crear un objeto Product real. La implementación de los métodos sabe cómo procesar la información del Director y cómo construir las respectivas partes de un producto. Esta clase además tiene un método getproduct, método de creación que me devuelve una instancia de Product. * Product (Producto): Objeto resultante. Puede definir el producto como una interfaz o una clase. Ventajas y Desventajas:. * Facilita la gestión del flujo de control durante la creación de objetos complejos. Hay un alto grado de acoplamiento entre el objeto Builder, su producto y cualquier otro delegado para la creación utilizado durante la construcción de objetos. Los cambios que suceden en el producto creado por el Builder a menudo generan modificaciones tanto para el objeto Builder como para sus delegados. PROTOTYPE. Propósito: Facilita la creación dinámica al definir clases cuyos objetos pueden crear copias de sı́ mismos. Aplicabilidad: * Utilice el patrón Prototype cuando desee crear un objeto que sea una copia del objeto existente. Descripción: En este patrón hay un objeto utilizado como base para crear una nueva instancia 35.
(52) Análisis del impacto del uso de patrones de diseño en la fase de mantenimiento con los mismos valores. Como proporciona un comportamiento de creación basada en un estado ya existente, es posible que los programas lleven a cabo operaciones como la copia dirigida por el usuario, al tiempo que permite inicializar los objetos a un estado que ha sido establecido durante el uso del sistema. Esto suele ser preferible a inicializar el objeto con algún conjunto de valores genéricos. Implementación: Para implementar el patrón Prototype necesita: * Prototype (Prototipo): Proporciona un método de copia. Ese método devuelve una instancia de la misma clase con los mismos valores que la instancia Prototype original. La nueva instancia puede ser una copia profunda o superficial del original. Ventajas y Desventajas: Es bastante útil porque permite que los sistemas generen una copia de un objeto, con variables ya establecidas a un valor significativo, en vez de depender de algún estado básico definido en el constructor. Una consideración clave para este patrón es la profundidad de la copia: * Una copia superficial solo duplica los elementos de alto nivel de una clase; esto proporciona una copia más rápida, pero que no siempre resulta apropiada. Como las referencias se copian desde el original a la copia, aún se refieren a los mismos objetos. Los objetos de bajo nivel son compartidas entre las copias del objeto, por lo que el cambio en uno de los objetos afecta a todas las copias. * Las operaciones de copia profunda no solo duplican los atributos de altonivel, sino también los objetos de alto nivel. Esto suele llevar más tiempo y puede ser muy costoso para objetos con una estructura compleja. Esto asegura que los cambios. 3. PATRONES DE COMPORTAMIENTO CHAIN OF RESPONSABILITY Propósito: Evitar acoplar al receptor de una solicitud con el receptor. Encadena los objetos receptores y pase la demanda a lo largo de la cadena hasta que un objeto lo maneje. Aplicabilidad: * Más de un objeto puede manejar una solicitud. No se sabe quién manejará la solicitud. 36.
Figure
Documento similar
En un estudio clínico en niños y adolescentes de 10-24 años de edad con diabetes mellitus tipo 2, 39 pacientes fueron aleatorizados a dapagliflozina 10 mg y 33 a placebo,
• Descripción de los riesgos importantes de enfermedad pulmonar intersticial/neumonitis asociados al uso de trastuzumab deruxtecán. • Descripción de los principales signos
que hasta que llegue el tiempo en que su regia planta ; | pise el hispano suelo... que hasta que el
Abstract: This paper reviews the dialogue and controversies between the paratexts of a corpus of collections of short novels –and romances– publi- shed from 1624 to 1637:
En junio de 1980, el Departamento de Literatura Española de la Universi- dad de Sevilla, tras consultar con diversos estudiosos del poeta, decidió propo- ner al Claustro de la
E Clamades andaua sienpre sobre el caua- 11o de madera, y en poco tienpo fue tan lexos, que el no sabia en donde estaña; pero el tomo muy gran esfuergo en si, y pensó yendo assi
[r]
SVP, EXECUTIVE CREATIVE DIRECTOR JACK MORTON