LIBRO PARA LA ASIGNATURA ANALISIS DE SISTEMAS AUTORES JUAN CARLOS GUEVARA BOLAÑOS Y LUIS FELIPE WANUMEN SILVA GRUPO DE INVESTIGACION METIS LINEA DE INGENIERIA DE SOFTWARE ENFOQUE PRÁCTICO DE MODELAMIENTO BASADO EN UML CON JAVA EN DONDE SE INCLUYEN ALGUNOS PATRONES DE DISENO. UNIVERSIDAD DISTRITAL FRANCISCO JOSE DE CALDAS FACULTAD TECNOLÓGICA SISTEMATIZACIÓN DE DATOS BOGOTÁ D.C. 2008 TABLA DE CONTENIDO TABLA DE CONTENIDO _________________________________________________ 2 CONVENCIONES _______________________________________________________ 10 NOTAS ACLARATORIAS ________________________________________________ 11 1. EL CRONOGRAMA EN RUP ___________________________________________ 12 2.1. LAS FASES Y LOS FLUJOS DE RUP _________________________________ 13 2.2. FASE DE INICIACION EN RUP ______________________________________ 16 2.3. FASE DE ELABORACION EN RUP __________________________________ 18 2.4. FASE DE CONSTRUCCION EN RUP _________________________________ 20 2.5. FLUJO DE TRANSICION EN RUP ___________________________________ 21 2. CONSIDERACIONES AL REALIZAR SU PROYECTO DE GRADO ___________ 32 2.1. SOBRE LAS FUNCIONES QUE DEBEN REALIZAR LOS PASANTES EN LOS PROYECTOS DE GRADO ______________________________________________ 32 2.2. CONSIDERACIONES SOBRE LAS PALABRAS QUE DEBE INCLUIR EL DOCUMENTO DE GRADO O PROYECTO DE SOFTWARE _________________ 32 2.3. SOBRE LA INTRODUCCION DE LA TESIS ___________________________ 34 2.4. SOBRE El RESUMEN DE LA TESIS __________________________________ 34 2.5. SOBRE EL TITULO DE LA TESIS ____________________________________ 36 2.6. PLANTEAR OBJETIVOS GENERALES Y ESPECIFICOS ________________ 36 2.7. OTRAS COSAS SOBRE LOS OBJETIVOS ESPECIFICOS ________________ 38 2.8. ALGUNOS EJEMPLOS DE OBJETIVOS Y SUS CORRECCIONES _________ 40 2.9. CUIDADOS AL PLANTEAR EL ALCANCE DEL PROYECTO ____________ 41 2.10. COSAS HA TENER EN CUENTA EN EL PLANTEAMIENTO DEL PROBLEMA _________________________________________________________ 42 2.11. EJEMPLO DESGLOSADO DE DESCRIPCION DEL PROBLEMA _________ 45 2.12. COSAS SOBRE LAS DELIMITACIONES _____________________________ 47 2.13. SOBRE EL ALCANCE Y LAS DELIMITACIONES _____________________ 47 2.14. COSAS SOBRE EL RIESGO ________________________________________ 48 2.15. SOBRE EL MARCO TEORICO. _____________________________________ 48 2.16. COSAS HA TENER EN CUENTA SOBRE EL MARCO HISTORICO ______ 48 2.17. COSAS SOBRE EL MARCO CONCEPTUAL __________________________ 49 2.18. COSAS SOBRE EL MARCO REFERENCIAL __________________________ 49 2.19. COSAS SOBRE LOS COSTOS DEL PROYECTO _______________________ 49 2.20. COSAS SOBRE LA FACTIBILIDAD OPERATIVA DEL PROYECTO _____ 49 2.21. COSAS SOBRE LA METODOLOGIA ________________________________ 49 2.22. COSAS HA TENER EN CUENTA EN EL MODELAMIENTO ____________ 50 2.23. TALLER PROPUESTO PARA MEJORAR LA FASE DE PLANEACION DEL PROYECTO __________________________________________________________ 51 2.24. TALLER PROPUESTO PARA PENSAR EN OBJETOS __________________ 54 2.25. ALGUNAS COSAS DE COMO PLANTEAR EL TITULO DE UN PROYECTO RELACIONADO CON SOFTWARE ______________________________________ 55 2.26. LISTA DE ALGUNOS ARTEFACTOS DE ENTREGA EN PROYECTOS DE TECNOLOGÍAS DE LA INFORMACIÓN _________________________________ 66 2.27. COSAS SOBRE COMO COMENZAR CON LOS REQUERIMIENTOS ____ 120 2.28. ALGUNOS EJEMPLOS DE REQUERIMIENTOS ______________________ 123 2.29. ALGUNAS ACTIVIDADES QUE PUEDEN SER NECESARIAS PARA LA REALIZACIÓN DE UN PROYECTO ____________________________________ 126 2.30. ALGUNAS PERSONAS QUE PUEDES NECESITAR PARA TU PROYECTO DE SOFTWARE _____________________________________________________ 132 2.31. ALGUNOS MOTORES PARA TU PROYECTO DE SOFTWARE _________ 136 2.32. ALGUNOS SOFTWARE QUE TE AYUDAN A REALIZAR LAS PRUEBAS DE TU SOFTWARE _____________________________________________________ 137 2.33. ALGUNOS FRAMEWORKS PARA EL DESARROLLO DE TU PROYECTO DE SOFTWARE _____________________________________________________ 140 2.34. ALGUNAS METODOLOGÍAS DE DESARROLLO DE SOFTWARE ______ 142 2.35. ALGUNAS DEFINICIONES ÚTILES PARA TU GLOSARIOS DE TÉRMINOS ___________________________________________________________________ 143 3. LA COHESIÓN Y EL ACOPLAMIENTO ENTRE CLASES Y OBJETOS _______ 145 3.1. GENERALIDADES SOBRE LA COHESIÓN __________________________ 145 3.2. COHESIÓN CASUAL _____________________________________________ 147 3.3. COHESIÓN LÓGICA ______________________________________________ 148 3.4. COHESIÓN TEMPORAL __________________________________________ 149 3.5. COHESIÓN DE PROCEDIMIENTO __________________________________ 150 3.6. COHESIÓN DE COMUNICACIÓN __________________________________ 152 3.7. COHESIÓN SECUENCIAL _________________________________________ 152 3.8. COHESIÓN FUNCIONAL __________________________________________ 153 3.9. ACOPLAMIENTO ________________________________________________ 153 3.10. TALLER PROPUESTO ___________________________________________ 153 4. GENERALIDADES DE UML___________________________________________ 155 4.1. DIAGRAMAS DE CASOS DE USO __________________________________ 155 4.2. DIAGRAMAS DE ACTIVIDADES ___________________________________ 156 4.3. DIAGRAMAS DE CLASES _________________________________________ 156 4.4. DIAGRAMAS DE INTERACCION___________________________________ 158 4.5. DIAGRAMAS DE ESTADO ________________________________________ 158 4.6. DIAGRAMAS DE COMPONENTES _________________________________ 158 4.7. DIAGRAMAS DE DESPLIEGUE ____________________________________ 158 5. MODELANDO CON UML _____________________________________________ 159 5.1. MODELAMIENTO DEL DOMINIO DEL PROBLEMA __________________ 159 5.2. MODELAMIENTO DE LA SOLUCION DEL PROBLEMA _______________ 160 5.3. MODELAMIENTO DE LA CODIFICACION DEL PROBLEMA ___________ 160 6. MODELOS UML EN LOS FLUJOS DE TRABAJO RUP _____________________ 161 6.1. DIAGRAMAS USADOS EN EL FLUJO DE MODELADO DEL NEGOCIO __ 162 6.2. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO REQUERIMIENTOS 163 6.3. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO ANALISIS Y DISENO ___________________________________________________________________ 164 6.4. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO IMPLEMENTACION 165 6.5. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO DESPLIEGUE _____ 166 6.6. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO PRUEBAS ________ 168 7. EL LENGUAJE OCL __________________________________________________ 170 7.1. OCL Y MOF _____________________________________________________ 170 7.2. UML Y OCL _____________________________________________________ 170 7.3. EVOLUCION DE OCL ____________________________________________ 171 7.4. COSAS QUE SE PUEDEN HACER CON OCL _________________________ 172 7.5. OCL Y LOS REQUISITOS _________________________________________ 172 7.6. CONCLUSIONES SOBRE OCL _____________________________________ 172 7.7. BIBLIOGRAFIA SOBRE OCL ______________________________________ 172 8. SOBRE LOS CASOS DE USO EN UML 2.0 _______________________________ 174 8.1. IDENTIFICAR ACTORES Y CASOS DE USO _________________________ 174 8.2. TIPOS DE RELACIONES ENTRE LOS CASOS DE USO ________________ 177 8.3. IDENTIFICAR RELACIONES TIPO <<EXTENDS>> ___________________ 178 8.4. ERRORES COMUNES CON RELACIONES TIPO <<EXTENDS>> ________ 182 8.5. RELACIONES DE GENERALIZACION SIN ESTEREOTIPO _____________ 184 8.6. IDENTIFICAR RELACIONES TIPO <<USES>> O <<INCLUDE>> ________ 189 8.7. EJEMPLO DE RELACION TIPO <<USES>> O <<INCLUDE>> __________ 191 8.8. CASO ESPECIAL DE RELACION TIPO <<USES>> O <<INCLUDE>> ____ 192 8.9. DOCUMENTACION DE CASOS DE USO ____________________________ 193 9. MODELAMIENTO UML Y SU IMPLEMENTACIÓN EN JAVA ______________ 201 9.1. DEFINICIÓN DE RELACIONES ____________________________________ 201 9.2. GENERALIZACIÓN VS HERENCIA ________________________________ 202 9.3. EL ACCESO PRIVADO ____________________________________________ 204 9.4. EL ACCESO PROTECTED _________________________________________ 208 9.5. ACCESO A LOS ATRIBUTOS: PRIVATE, PROTECTED O PUBLIC ______ 211 9.6. ASOCIACIONES _________________________________________________ 211 9.7. LAS AGREGACIONES ____________________________________________ 213 9.8. RELACIONES DE DEPENDENCIA __________________________________ 215 9.9. HERENCIA MÚLTIPLE EN JAVA ___________________________________ 217 10. ESTEREOTIPOS DE LAS CLASES EN UML 2.0 _________________________ 218 10.1. LAS CLASES CON ESTEREOTIPO VIEW ___________________________ 218 10.2. LAS CLASES CON ESTEREOTIPO TABLE __________________________ 218 10.3. LAS CLASES CON ESTEREOTIPO SERVICE ________________________ 219 10.4. LAS CLASES CON ESTEREOTIPO RESOURCE ______________________ 219 10.5. OTROS ESTEREOTIPOS DE CLASES ______________________________ 220 11. DIAGRAMAS DE CLASE Y CONCEPTOS ______________________________ 224 11.1. CASO 1: CUANDO NO SE PUEDE COLOCAR ESPECIFICADOR DE ACCESO A UNA CLASE ______________________________________________ 224 11.2. ASOCIACIONES CON CARDINALIDAD FINITA _____________________ 226 11.3. ASOCIACIONES CON CARDINALIDAD INFINITA __________________ 227 11.4. CLASES TIPO UTILITY __________________________________________ 229 11.5. LAS CLASES UTILITARIAS NO PUEDEN ESTAR CONTENIDAS EN OTRAS ___________________________________________________________________ 231 11.6. LAS AGREGACIONES ___________________________________________ 233 11.7. EN LAS AGREGACIONES UN TODO NO PUEDE SER UNA PARTE DE SI MISMO _____________________________________________________________ 236 11.8. CICLO ILEGAL DE AGREGACION ENTRE DOS INSTANCIAS DE DISTINTA CLASE ___________________________________________________ 237 11.9. DIAGRAMAS DE CLASES DE EJEMPLOS __________________________ 239 12. P.O.O. EN JAVA Y CLASES ABSTRACTAS _____________________________ 243 12.1. LAS CLASES ABSTRACTAS ______________________________________ 243 12.2. CASO 1: SOBRE LAS CLASES ABSTRACTAS ______________________ 244 12.3. CASO 2: SOBRE LAS CLASES ABSTRACTAS _______________________ 244 12.4. CASO 3: SOBRE LAS CLASES ABSTRACTAS _______________________ 245 12.5. CASO 4: SOBRE LAS CLASES ABSTRACTAS _______________________ 246 12.6. CASO 5: SOBRE LAS CLASES ABSTRACTAS _______________________ 247 12.7. CASO 6: SOBRE LAS CLASES ABSTRACTAS _______________________ 248 12.8. CASO 7: SOBRE LAS CLASES ABSTRACTAS _______________________ 250 12.9. CASO 8: SOBRE LAS CLASES ABSTRACTAS _______________________ 251 13. P.O.O. EN JAVA Y LAS INTERFACES _________________________________ 253 13.1. LAS INTERFACES DEBEN INICIALIZAR SUS ATRIBUTOS ___________ 254 13.2. EN LAS INTERFACES NO ES OBLIGATORIO MODIFICADORES DE ATRIBUTOS ________________________________________________________ 255 13.3. EL MODIFICADOR DE ATRIBUTO POR DEFECTO ES PUBLIC EN LAS INTEFACES_________________________________________________________ 255 13.4. EL MODIFICADOR DE ATRIBUTO PROTECTED NO ESTA PERMITIDO EN LAS INTERFACES ___________________________________________________ 256 13.5. EL MODIFICADOR DE ATRIBUTO PRIVATE NO ESTA PERMITIDO EN LAS INTERFACES ___________________________________________________ 256 13.6. UNA INTERFAZ NO PUEDE SER INSTANCIADA DIRECTAMENTE ____ 257 13.7. UNA CLASE NO INTERFAZ PUEDE IMPLEMENTAR UNA CLASE INTERFAZ __________________________________________________________ 258 13.8. UNA CLASE INTERFAZ NO PUEDE IMPLEMENTAR UNA CLASE INTERFAZ __________________________________________________________ 259 13.9. UNA CLASE INTERFAZ PUEDE EXTENDER DE UNA CLASE INTERFAZ ___________________________________________________________________ 260 13.10. UNA CLASE NO INTERFAZ PUEDE IMPLEMENTAR VARIAS CLASES TIPO INTERFAZ _____________________________________________________ 261 13.11. UNA CLASE INTERFAZ PUEDE EXTENDER DE VARIAS CLASES TIPO INTERFAZ __________________________________________________________ 263 13.12. UNA CLASE NO INTERFAZ NO PUEDE EXTENDER DE UNA CLASE TIPO INTERFAZ __________________________________________________________ 264 13.13. NO SE PUDE MODIFICAR VARIABLE DE UNA CLASE TIPO INTERFAZ ___________________________________________________________________ 265 13.14. CLASE QUE IMPLEMENTE CLASE TIPO INTERFAZ DEBE DEFINIR SUS MÉTODOS __________________________________________________________ 268 14. SOBRE LAS CLASES Y ATRIBUTOS TIPO FINAL _______________________ 271 14.1. LOS ATRIBUTOS FINAL DEBEN ESTAR INICIALIZADOS ____________ 272 14.2. ATRIBUTOS FINAL Y CLASES NO FINAL __________________________ 273 14.3. RECUPERACION DE ATRIBUTOS FINALES ________________________ 274 14.4. ASIGNACION DE VALORES A LOS ATRIBUTOS TIPO FINAL ________ 275 14.5. CREACION DE METODOS TIPO FINAL ____________________________ 277 14.6. TALLER PROPUESTO SOBRE CLASES Y ATRIBUTOS TIPO FINAL ___ 279 15. CASOS VARIADOS SOBRE CLASES INTERFACE, FINALES Y ABSTRACTAS _____________________________________________________________________ 280 15.1. CASO 1: _______________________________________________________ 280 15.2. CASO 2: _______________________________________________________ 280 15.3. CASO 3: _______________________________________________________ 281 15.4. CASO 4: _______________________________________________________ 281 15.5. CASO 5: _______________________________________________________ 283 15.6. CASO 6: _______________________________________________________ 283 15.7. CASO 7: _______________________________________________________ 284 15.8. CASO 8: _______________________________________________________ 285 15.9. CASO 9: _______________________________________________________ 285 15.10. TALLER ______________________________________________________ 286 16. EL POLIMORFISMO PARECE NO SER EXLUSIVO DE LA HERENCIA NI DE LA ORIENTACION A OBJETOS _____________________________________________ 287 16.1. UNA DEFINICION MÁS FORMAL _________________________________ 287 16.2. UN EJEMPLO DE NO POLIMORFISMO ____________________________ 288 16.3. UN EJEMPLO DE POLIMORFISMO ________________________________ 289 16.4. TALLER PROPUESTO SORE POLIMORFISMO ______________________ 290 17. REDEFINICIÓN Y ANULACION DE METODOS EN LA HERENCIA ________ 291 17.1. ANULACION POR EXTENSION ___________________________________ 292 17.2. ANULACION POR RESTRICCION _________________________________ 292 17.3. ANULACION POR OPTIMACIÓN _________________________________ 292 17.4. INVALIDACION POR CONVENIENCIA ____________________________ 292 17.5. TALLER SOBRE REDEFINICION DE METODOS EN LA HERENCIA ___ 292 18. TODO A CERCA DE CLASES _________________________________________ 294 18.1. TIPOS DE CLASES ______________________________________________ 294 18.2. VARIABLES Y METODOS DE INSTANCIA _________________________ 295 18.3. AMBITO DE UNA VARIABLE ____________________________________ 295 18.4. METODOS Y CONSTRUCTORES __________________________________ 296 18.5. FINALIZADORES _______________________________________________ 297 18.6. ALCANCE DE OBJETOS Y RECICLADO DE MEMORIA ______________ 297 19. EJERCICIO DEL PIRATA RESULADO DE LA PRIMERA ITERACION CON RUP _____________________________________________________________________ 299 19.1. PLANTEAMIENTO DEL ENUNCIADO _____________________________ 299 19.2. ESTABLECIMIENTO DE FRASES IMPORTANTES. __________________ 299 19.3. ESTABLECIMIENDO DE CLASES _________________________________ 300 19.4. PROGRAMA EN JAVA ___________________________________________ 301 19.5. EJECUCIÓN DEL PROGRAMA: ___________________________________ 306 20. EJERCICIO DEL AVION _____________________________________________ 309 20.1. DIAGRAMA DE CLASE __________________________________________ 309 20.2. EXPLICACIÓN DE LA IMPLEMENTACIÓN _________________________ 310 20.3. EJECUCIÓN DEL PROGRAMA ____________________________________ 318 21. LA CLONACION DE OBJETOS _______________________________________ 321 21.1. COPIA DE OBJETOS LIMITADA __________________________________ 321 21.2. COPIAR OBJETOS CON INTERFAZ CLONEABLE ___________________ 331 21.3. LA INTERFAZ CLONEABLE ABARCA SUBOBJETOS ________________ 334 22. CLASES TIPO OBSERVER Y OBSERVABLE ___________________________ 339 22.1. ESTRUCTURA DE LAS CLASES OBSERVABLES ____________________ 339 22.2. ESTRUCTURA DE LAS CLASES OBSERVER _______________________ 340 22.3. CREACION DE OBJETOS DE TIPO OBSERVER Y OBSERVABLE ______ 340 22.4. VINCULACION DEL OBJETO OBSERVABLE AL OBJETO OBSERVER _ 341 22.5. UN EJEMPLO COMPLETO CON OBSERVER Y OBSERVABLE ________ 341 22.6. PREGUNTAS SOBRE OBSERVER Y OBSERVABLE __________________ 345 23. COMO DELEGAR CLASES ___________________________________________ 346 23.1. PLANTEAMIENTO TEORICO DE LA DELEGACION _________________ 346 23.2. EJERCICIO PRÁCTICO SOBRE DELEGACION ______________________ 349 23.3. PREGUNTAS SOBRE DELEGACION _______________________________ 352 24. SERIALIZACION DE OBJETOS _______________________________________ 353 24.1. SERIALIZAR UN OBJETO COMPLETAMENTE ______________________ 353 24.2. SERIALIZAR UN OBJETO COMPLETAMENTE EN JAVA _____________ 355 24.3. ATRIBUTOS TRANSIENTES EN LA SERIALIZACION _______________ 360 24.4. LA SERIALIZACION Y EL DIAGRAMA DE ESTADOS _______________ 364 24.5. TALLER PROPUESTO SOBRE SERIALIZACION _____________________ 368 25. EJERCICIOS QUE TIENEN DIAGRAMAS DE SECUENCIA _______________ 374 25.1. MODELAMIENTO DE DETENCION SINCRONICA DE MULTIPLES HILOS CON UN EJEMPLO. __________________________________________________ 374 25.2. IMPLEMENTACION DE DETENCION SINCRONICA DE MULTIPLES HILOS CON UN EJEMPLO. __________________________________________________ 386 26. INTRODUCCION A LOS PATRONES DE SOFTWARE ____________________ 392 26.1. PATRONES CON FUNCIONALIDAD DE CREACIÓN _________________ 392 26.2. PATRONES CON FUNCIONALIDAD ESTRUCTURAL ________________ 392 26.3. PATRONES CON FUNCIONALIDAD DE COMPORTAMIENTO ________ 392 27. EXPLICACION DETALLADA DE LOS PATRONES ______________________ 393 27.1. EJEMPLO PRÁCTICO DE APLICACIÓN DE FACTORY _______________ 393 27.2. EJEMPLO MAS ELABORADO USANDO FACTORY __________________ 396 28. PATRON DE CREACION SINGLETON _________________________________ 400 28.1. PARTE TEORICA DEL PATRON SINGLETON _______________________ 400 28.2. PARTE PRACTICA DEL PATRON SINGLETON _____________________ 401 28.3. OBSERVACIONES AL EJERCICIO DE SINGLETON __________________ 402 29. PATRON ITERATOR ________________________________________________ 404 29.1. DESCRIPCION __________________________________________________ 404 29.2. APLICABILIDAD _______________________________________________ 404 CONTROLADOR ______________________________________________________ 406 VISTA _______________________________________________________________ 406 29.3. IMPLEMENTACION DE LA SOLUCION ____________________________ 407 29.4. OBSERVACIONES GENERALES AL EJERCICIO DESARROLLADO ____ 419 29.5. TALLER PROPUESTO SOBRE EL EJERCICIO. ______________________ 421 30. PATRON ADAPTADOR _____________________________________________ 423 30.1. DEFINICION DEL PATRON ADAPTADOR __________________________ 423 30.2. UN EJEMPLO QUE USA EL PATRON ADAPTADOR _________________ 423 30.3. ESTRUCTURA GENERAL DEL PATRON ADAPTADOR ______________ 426 30.4. OTRAS APLICACIONES DEL PATRON ADAPTADOR ________________ 428 31. PAQUETES Y DIAGRAMA DE PAQUETES _____________________________ 429 31.1. LOS JAR Y LOS PAQUETES ______________________________________ 430 31.2. PAQUETES ANIDADOS __________________________________________ 433 32. FLUJO DE PRUEBAS ________________________________________________ 434 32.1. FUNCIONAMIENTO DE JUNIT____________________________________ 434 32.2. CONSTRUCCION DE LA CLASE QUE VAMOS A PROBAR ___________ 435 32.3. CONSTRUCCION DE CASO DE PRUEBA PARA CLASE LISTA ________ 438 32.4. ELABORACION DEL PROGRAMA QUE EJECUTA LA PRUEBA _______ 442 32.5. EJECUCION DEL TESTRUNNER __________________________________ 442 33. SOBRE LA CALIDAD DEL SOFTWARE ________________________________ 449 33.1. MODELOS DE CALIDAD_________________________________________ 449 33.2. MODELO SPICE ________________________________________________ 452 33.3. NORMA ISO 9000-2000___________________________________________ 452 33.4. NORMA ISO 90003 ______________________________________________ 453 33.5. NORMA ISO/IEC TR 15504 _______________________________________ 453 33.6. ESTANDAR ISO 9126 ____________________________________________ 454 33.7. MODELOS CMMI _______________________________________________ 455 33.8. TALLER PROPUESTO DE CALIDAD _______________________________ 457 34. LOS SISTEMAS DE CONTROL DE VERSIONES _________________________ 458 34.1. LOS CVS Y EL PROCESO DE DESARROLLO UNIFICADO ____________ 458 34.2. LA GESTION DE CONFIGURACIONES Y LOS CVS __________________ 459 34.3. CONTENIDO DE LA UNIDAD ____________________________________ 460 34.4. CONCRETANDO LO QUE ES UN CVS _____________________________ 460 34.5. TIPOS DE SISTEMAS DE CONTROL DE VERSIONES ________________ 460 34.6. LOS CVS Y LA INGENIERÍA DE SOFTWARE _______________________ 461 34.7. SISTEMAS PARA GESTIONAR LOS CVS ___________________________ 462 34.8. OTROS SISTEMAS QUE APOYAN A LOS CVS ______________________ 463 34.9. CARACTERISTICAS QUE DEBE TENER UN BUEN CONTROL DE VERSIONES ________________________________________________________ 464 34.10. EL FUTURO DE LOS CVS _______________________________________ 465 34.11. CONCLUSIONES SOBRE LOS CVS _______________________________ 466 34.12. BIBLIOGRAFIA DE LA UNIDAD _________________________________ 467 34.13. INFOGRAFIA DE LA UNIDAD ___________________________________ 467 35. ARQUITECTURA CENTRADA EN MODELOS __________________________ 470 35.1. INTRODUCCIÓN A MDA ________________________________________ 470 35.2. PALABRAS CLAVE _____________________________________________ 470 35.3. INTRODUCCION A MDA ________________________________________ 470 35.4. ¿MDA UN ENFOQUE DE DESARROLLO O ESTANDAR DE DESARROLLO? ___________________________________________________________________ 470 35.5. ¿MDD O MDA? _________________________________________________ 471 35.6. ¿ACASO NO TRABAJAMOS CON MODELOS DESDE HACE MUCHO TIEMPO? ___________________________________________________________ 471 35.7. REALMENTE: ¿QUÉ ES LO NUEVO? ______________________________ 472 35.8. ¿TODO CON MODELAMIENTO NO ES ACASO UNA UTOPIA? ________ 472 35.9. ¿QUÉ SE PODRÍA HACER CON LOS MODELOS? ____________________ 473 35.10. LOS MODELOS DEBEN SER: ¿DEPENDIENTES O INDEPENDIENTES DE LA PLATAFORMA? __________________________________________________ 473 35.11. ¿QUÉ SON LOS MODELOS DEPENDIENTES DEL SISTEMA? ________ 474 35.12. ¿SE DEBEN AUTOMATIZAR LAS TRANSFORMACIONES? __________ 474 35.13. ¿QUÉ LENGUAJES USARÁ MDA? ________________________________ 474 35.14. ¿QUÉ INTERPRETACIONES HAY DE MDA? _______________________ 475 35.15. CONCLUSIONES SOBRE MDA __________________________________ 475 35.16. BIBLIOGRAFIA SOBRE MDA ____________________________________ 477 36. BIBLIOGRAFIA ____________________________________________________ 478 36.1. BIBLIOGRAFIA SOBRE PROCESOS DE DESARROLLO Y RUP ________ 478 36.2. BIBLIOGRAFIA SOBRE MODELAMIENTO CON UML _______________ 478 36.3. BIBLIOGRAFIA SOBRE IMPLEMENTACIONES CON UML ___________ 479 37. ANEXO 1: CORRECCIONES HECHAS A PROYECTOS DE GRADO ________ 480 37.1. ALGUNAS CORRECCIONES PASADAS A ALGUNOS PROYECTOS DE GRADO: CARTA 1 ___________________________________________________ 480 37.2. ALGUNAS CORRECCIONES PASADAS A ALGUNOS PROYECTOS DE GRADO: CARTA 2 ___________________________________________________ 481 38. ANEXO 2: COSAS HA TENER EN CUENTA EN LOS PROYECTOS DE GRADO _____________________________________________________________________ 483 38.1 SI EL PROYECTO QUE SE VA A REALIZAR ES SOBRE APLICACIONES MOVILES Y ES DE TECNOLOGÍA EN SISTEMATIZACIÓN DE DATOS. _____ 483 38.2. SI EL PROYECTO QUE SE VA A REALIZAR ES SOBRE APLICACIONES MOVILES Y ES DE INGENIERÍA EN REDES DE COMPUTADORES O INGENIERÍA EN TELEMÁTICA. _______________________________________ 484 38.3. SI VAS A REALIZAR UN PROYECTO SOBRE APLICACIONES CON AGENTES MOVILES REQUIERES _____________________________________ 484 39. ANEXO 3: PREGUNTAS SOBRE LO VISTO EN CLASE DE ANALISIS DE SISTEMAS CON EL PROFESOR LUIS FELIPE WANUMEN __________________ 487 39.1. CUESTIONARIO 1: SOBRE GENERALIDADES RUP Y UML ___________ 487 39.2. RESPUESTAS SOBRE CUESTIONARIO 1 ___________________________ 489 INDICE ALFABETICO __________________________________________________ 490 LO QUE SE LLEVA DEFINITIVO ESTA EN VERDE EL RESTO EN ROJO ______ 492 CONVENCIONES En el presente documento se hacen ejemplos tratando de lograr que la ejecución del mencionado por parte del lector / estudiante sea lo mas fácil posible y para lograr este cometido se hacen ejemplos en donde casi siempre se usa una clase llamada “MyApp” que es la que contiene a otras clases y los conceptos que se explican se revelan partiendo de lo que existe al interior de dicha clase y no de la relación de la clase “MyApp” con las otras clases, esta relación de contención es simplemente para facilitar la compilación de los ejercicios en un solo archivo y no tener que usar varios archivos, para no complicar la ejecución de los ejercicios. A veces se usan cuadros que no corresponden exactamente con la diagramación UML, caso en el cual se hará la correspondiente aclaración, y cuando se usen diagramas UML también se indicara ello en el nombre de la figura. Se usa mucho la frase “en forma similar a la siguiente” para referirse a los resultados de la compilación de un programa o para la forma como se podría implementar una determinada solución y deja muy en claro que esto depende para el primer caso del compilador usado y para el segundo del estilo del programador. Se usa mucho la frase “amigo lector / estudiante”, pero no para excluir el resto de personas, sino para referirse a cualquier persona que lea el presente material. NOTAS ACLARATORIAS El presente material en su totalidad es inédito y cualquier parecido con otros existentes es pura coincidencia. De otra parte no se responde por danos en las maquinas locales por la ejecución de rutinas o código mostrado en el presente material. Algunas unidades tematicas tienen el formato de un articulo y esto es debido a que para estos temas la estructura de articulo de investigación se adapta perfectamente al tema tratado. 1. EL CRONOGRAMA EN RUP Una de las preocupaciones de los estudiantes de Ciencias Tecnológicas e Ingenierías relacionadas con la Informática es el hecho de hacer buenos cronogramas en sus proyectos de desarrollos informáticos. Estos cronogramas deben ser acordes con las metodologías. En esta sección se muestra a continuación el diagrama que aparece en todos los documentos que hablan de RUP y con base en el se planteara como deducir un posible cronograma que tenga algo de coherencia con dicho diagrama. Para comenzar veamos primero el diagrama que aparece siempre y en todo documento de RUP: D Diagrama tomado de unas diapositivas elaboradas por “Maria Fernanda Diaz” y “Margarita Cardozo Galvis”. 2.1. LAS FASES Y LOS FLUJOS DE RUP El anterior diagrama se encuentra con otras formas como la siguiente: Diagrama tomado del libro “El lenguaje Unificado de Modelado”. Addison Wesley Iberoamericana, Madrid, 1999. ISBN: 84-7829-028-1. Pag 29. Con lo cual podemos ver que a pesar de lo diferentes que parecen los dos anteriores diagramas, en realidad muestran lo mismo. Y muestran que en RUP existen dos tipos de flujos, tal como se muestra a continuación: FLUJOS DE RUP Flujos de trabajo de proceso Flujos de trabajo de soporte Diagrama elaborado por Luis Felipe Wanumen Silva. Los flujos de trabajo de proceso son los flujos que se documentan y se acostumbran a presentar con diversos diagramas para documentar un sistema y en muchas Universidades colombianas se acostumbra a entregar solamente esta parte documentada como constancia del proceso de Ingeniería de Software aplicado al desarrollo del proyecto. Podríamos pensar en la siguiente analogía: Las labores de un docente universitario son: 1. Dictar clases 2. Participar en proyectos institucionales 3. Investigar 4. Preparar clase 5. Atender estudiantes 6. Orientar pasantias y tesis 7. Participar en comités institucionales 8. Apoyar actividades de extensión de la universidad 9. Sacar tiempo para escribir sus materiales de clase. 10. Sacar tiempo para comer y alimentarse bien. 11. Sacarle tiempo a la familia y al descanso. 12. Analizar sus experiencias docentes vividas para mejorar en algunos aspectos. Claro, al amigo lector / estudiante, se estará preguntando: ¿Cómo es que sacarle tiempo para comer y alimentarse bien es una de las labores de un docente?: La respuesta es sencilla y se puede responder con otra pregunta: ¿Qué pasa si el docente no se alimenta, podrá continuar con su labor como docente durante mucho tiempo, no se verá afectado su desarrollo profesional?. La respuesta es: “Se requiere que el docente ejecute estas tareas para tener un buen desempeño laboral”. Pues bien, en este caso esta tarea es una labor que no es tan necesario documentar, pero que si es necesario ejecutar para que se puedan dar las otras labores. Tenemos pues una subclasificación de actividades de soporte, tal como muestra el siguiente diagrama: FLUJOS DE RUP Flujos de trabajo de proceso Flujos de trabajo de soporte Flujos de trabajo de soporte relevantes para documentar Flujos de trabajo de soporte NO relevantes para documentar Pues bien, según lo explicado anteriormente, los flujos de soporte deben ejecutarse, para que se puedan ejecutar los flujos de proceso. La pregunta que viene es: ¿Se pueden ejecutar mal los flujos de soporte?. ¿Se puede un docente alimentar mal?. La respuesta es: “Lo puede hacer, pero esto poco a poco deteriorara el rendimiento del profesional como docente”. En pocas palabras, estamos diciendo que un flujo de soporte ayuda para que los flujos de proceso se realicen bien o mal, dependiendo la forma como se realicen los flujos de soporte Para explicar otro concepto importante, seguiremos con nuestra analogía: ¿Es posible que un docente dicte sus clases sin elaborar sus propios materiales de clase?. La respuesta es: “Si”, no es necesario que se hagan materiales de clase, se pueden usar las guias elaboradas por otros autores. Viene entonces la otra pregunta: ¿Si se llegase a realizar algún material de clase por parte del docente, este material serviría como documentación del proceso de enseñanza?. La respuesta es “Si”. Otra pregunta es: ¿El realizar manuales de clase por parte del docente no mejoraría el dominio que tiene el docente sobre la materia y no mejoraría el proceso enseñanza-aprendizaje?. La respuesta es “Claro que si porque mejoraría la calidad del proceso”. Entonces tenemos que los flujos de soporte son muy útiles para medir la calidad de los flujos de proceso. En pocas palabras los flujos de modelado del negocio, requisitos, análisis, diseño, implementación, pruebas y despliegue son de buena calidad cuando se les realiza una buena gestión de configuración, gestión de proyecto y se tienen en cuenta metodológicamente las variables de ambiente que intervienen en la elaboración del sistema. El resumen de lo dicho anteriormente se puede esquematizar mediante el siguiente diagrama: FLUJOS DE RUP Flujos de trabajo de proceso Dan calidad a los flujos de proceso Flujos de trabajo de soporte Flujos de trabajo de soporte relevantes para documentar LOS FLUJOS DE TRABAJO EN RUP Flujos de trabajo de soporte NO relevantes para documentar Los flujos de trabajo en RUP según lo dicho hasta el momento están clasificados en flujos de proceso y en flujos de soporte, en cada flujo de estos se encuentran más subflujos que se resumen en la siguiente tabla: FLUJOS DE PROCESO Modelado del negocio Requisitos Análisis y Diseño Implementación Pruebas Despliegue FLUJOS DE SOPORTE Gestión del cambio y configuraciones Gestión del proyecto Entorno De otra parte es interesante observar que las fases de RUP son las mostradas en el siguiente diagrama: Iniciación Elaboración Construcción FASES DE RUP Transición 2.2. FASE DE INICIACION EN RUP Y en cada una de estas fases se pueden presentar los flujos anteriormente mencionados. Por ejemplo en la fase de iniciación podrían presentarse flujos de modelamiento del negocio, de análisis, de diseño e incluso de implementación, pero los dos últimos flujos se presentan en esta fase en un grado bajo o casi escaso, por no decir casi nulo. Decimos entonces que podemos incluir los flujos de análisis y diseño e implementación en la fase de iniciación, pero destinando pocos recursos de tiempo, presupuestales y demás para este tipo de flujos en dicha fase, con lo cual elaboramos la siguiente tabla: FASE . FASE DE INICIACION 22% FLUJOS DE TRABAJO NEGOCIOS Y MODELAMIENTO PORCENTAJE 9,00% REQUERIMIENTOS 5,00% ANALISIS Y DISEÑO IMPLEMENTACION TEST PRUEBAS DESPLIEGUE CONFIGURACION Y MANTENIMIENTO 1,00% 1,00% 0,00% 0,00% 2,00% ADMINISTRACION AMBIENTE 2,00% 2,00% En donde queda claro que los flujos de análisis y diseño e implementación tienen una importancia pequeña cuando se realizan dentro de la fase de iniciación. En el ejemplo de la tabla anterior a estos flujos se les da una importancia de 1% a cada uno, e incluso se puede notar que a los flujos de test y despliegue se les da ninguna importancia. Para la elaboración de la anterior grafica nos basamos en la observación detallada de la parte que se señala con un cuadro grueso de color rojo en el siguiente dibujo: 2.3. FASE DE ELABORACION EN RUP La tabla de la sección anterior la podemos elaborar para las demás fases y obtenemos la tabla de la fase de elaboración siguiente: FASE . FASE DE ELABORACION 22% FLUJOS DE TRABAJO PORCENTAJE NEGOCIOS Y MODELAMIENTO 4,00% REQUERIMIENTOS 4,00% ANALISIS Y DISEÑO 5,00% IMPLEMENTACION TEST PRUEBAS 2,00% 1,00% DESPLIEGUE CONFIGURACION Y MANTENIMIENTO 1,00% 2,00% ADMINISTRACION 2,00% AMBIENTE 1,00% Que es muy coherente con lo expuesto en el diagrama inicial de RUP: En donde se puede verificar que los flujos de pruebas y de despliegue son los que menos importancia tienen en esta fase y por eso se les da una importancia de 1%, debido a que en la grafica anterior aparece muy delgada la linea, pero de todas formas aparece. De otra parte es importante ver que el flujo de diseño es el mas importante en la fase de elaboración, razón por la cual se le da una importancia de 5, en tanto que a los flujos de requerimientos y modelado del negocio se le da una importancia de 4. Obviamente estos valores son una cuestión subjetiva, producto de observar el grafico y calcular al “ojo” un valor de importancia para cada flujo basado en el área que se le alcanza a ver a cada flujo en cada fase (“La cual en el grafico se ve como una montaña”). 2.4. FASE DE CONSTRUCCION EN RUP Continuando con nuestro proceso, y teniendo en cuenta que la fase de construcción de RUP esta dada por el cuadro grueso de color mostrado a continuación: Podriamos pensar que un buen cronograma para la fase construccion acorde con el anterior diagrama es el siguiente: Podríamos proponer el siguiente cronograma para la fase de construcción de un sistema de información: FASE . FASE DE CONSTRUCCION 30% FLUJOS DE TRABAJO PORCENTAJE NEGOCIOS Y MODELAMIENTO 2,00% REQUERIMIENTOS ANALISIS Y DISEÑO 2,00% 4,00% IMPLEMENTACION TEST PRUEBAS DESPLIEGUE CONFIGURACION Y MANTENIMIENTO 10,00% 2,00% 1,00% 5,00% ADMINISTRACION 3,00% AMBIENTE 1,00% En donde los valores de importancia son tomados en forma arbitraria, pero basándonos en las áreas de las montañas del diagrama RUP en la fase de construcción. 2.5. FLUJO DE TRANSICION EN RUP En forma análoga a la construcción de las fases anteriores, nos proponemos mostrar una propuesta de cronograma para la fase de transición. Veamos: FASE . FASE DE TRANSICION 26% FLUJOS DE TRABAJO PORCENTAJE NEGOCIOS Y MODELAMIENTO 0,00% REQUERIMIENTOS ANALISIS Y DISEÑO IMPLEMENTACION 1,00% 1,00% 4,00% TEST PRUEBAS 3,00% DESPLIEGUE 11,00% CONFIGURACION Y MANTENIMIENTO 5,00% ADMINISTRACION 1,00% La cual esta basada en la fase de transición que esta señalada en el siguiente grafico de RUP, mediante un cuadro grueso de color rojo: Y ahora bien, con todo lo expuesto hasta el momento creo que ha llegado el momento de comenzar a definir actividades para cada uno de los flujos expuestos en las anteriores tablas, de tal forma que el numero y el tipo de actividades asociadas a cada fase sean medianamente proporcionales a la importancia que hemos dado en las anteriores tablas. Para esto tenemos que comenzar por averiguar y hacer listados preliminares de las posibles actividades que pueden ir en cada flujo de trabajo y después de realizar todo este trabajo, se puede decir que para nuestro cronograma propuesto tenemos que las actividades con los flujos correspondientes para cada una de las fases y colocándoles la duración en días para cada flujo son las que se muestran a continuación: CRONOGRAMA BASADO EN RUP PLANTILLA FASE . FLUJOS DE TRABAJO PORCENTAJE ACTIVIDAD DIAS Modelo de Dominio Establecimiento de viabilidad del sistema Establecimiento de factibilidad Técnica del sistema Establecimiento de factibilidad Operativa del Sistema Establecimiento de factibilidad Legal del Sistema NEGOCIOS Y MODELAMIENTO 9,00% Modelo de procesos 27 Definición de actores Lista preliminar de casos de uso Documentación de las excepciones de los casos de uso Documentación de descripción de casos de uso FASE DE INICIACION 22% Depuración de los casos de uso REQUERIMIENTOS 5,00% Modelo de casos de Uso 15 ANALISIS Y DISEÑO 1,00% Lista preliminar de clases 3 IMPLEMENTACION 1,00% Definición de las características de la herramienta 3 TEST PRUEBAS 0,00% DESPLIEGUE 0,00% 0 0 Creación de casos de uso de prueba CONFIGURACION Y MANTENIMIENTO 2,00% Montaje de un servidor de pruebas 6 Administración del personal Administración de recursos ADMINISTRACION AMBIENTE 2,00% Administración de recursos de computo 6 2,00% Adquisición del espacio de trabajo 6 FASE . FLUJOS DE TRABAJO PORCENTAJE ACTIVIDAD NEGOCIOS Y MODELAMIENTO 4,00% REQUERIMIENTOS 4,00% ANALISIS Y DISEÑO IMPLEMENTACION 5,00% 2,00% TEST PRUEBAS DESPLIEGUE 1,00% 1,00% CONFIGURACION Y MANTENIMIENTO 2,00% FASE DE ELABORACION 22% ADMINISTRACION AMBIENTE 2,00% 1,00% Depuración del Modelo De Dominio Depuración del modelo de procesos Diagnostico de viabilidad del sistema Depuración de actividades de los actores Depuración de requerimientos funcionales Depuración de requerimientos no funcionales Documentación de casos de uso Depuración de la lista de casos de uso Depuración del diagrama final de casos de uso Elaboración del Diagrama de secuencia Elaboración del Diagrama de colaboración Elaboración del diagrama de estados Elaboración de diagrama de actividad Diagrama de actividades Elaboración del diagrama de componentes inicial Creación de clases de prueba Pruebas basadas en objetos Elaboración del diagrama de despliegue inicial Creación de casos de uso de prueba Montaje de un servidor de pruebas Administración del personal Administración de recursos Administración de recursos de computo Adquisición del espacio de trabajo DIAS 12 12 15 6 3 3 6 6 3 FASE . FLUJOS DE TRABAJO PORCENTAJE ACTIVIDAD DIAS NEGOCIOS Y MODELAMIENTO 2,00% Corrección de políticas con respecto a la misión y visión 6 REQUERIMIENTOS 2,00% Depuración de casos de uso extendido 6 Elaboración de diagramas de clase final Elaboración de diagramas de actividad finales ANALISIS Y DISEÑO Elaboración de diagramas de secuencia finales Elaboración de diagramas de colaboración finales FASE DE CONSTRUCCION 30% 4,00% Elaboración de diagramas de estado finales 12 IMPLEMENTACION 10,00% Elaboración de diagrama de componentes final 30 TEST PRUEBAS 2,00% Pruebas basadas en escenarios 6 DESPLIEGUE 1,00% Elaboración de diagrama de despliegue final 3 Establecimiento de un modelo de pruebas Montaje de un servidor de pruebas Montaje de un servidor de control de escenarios Montaje de un servidor de control de versiones de software Pruebas del servidor CVS Montaje de un servidor de subversiones CONFIGURACION Y MANTENIMIENTO 5,00% Montaje de un servidor de pruebas 15 Administración del personal ADMINISTRACION AMBIENTE Administración de recursos 3,00% Administración de recursos de computo 9 1,00% Mejoras locativas a la estructura física de trabajo 3 FASE . FLUJOS DE TRABAJO PORCENTAJE ACTIVIDAD DIAS NEGOCIOS Y MODELAMIENTO 0,00% 0 REQUERIMIENTOS 1,00% Depuración de casos de uso extendido Depuración del modelo de análisis y colocación de etiquetas 1,00% OCL 3 ANALISIS Y DISEÑO 3 Creación de módulos de interfaz de usuario Creación de módulos de lógica del negocio IMPLEMENTACION 4,00% Creación de módulos de acceso a datos 12 Pruebas basadas en escenarios Pruebas unitarias de clase Pruebas de acoplamiento Pruebas de cohesión TEST PRUEBAS 3,00% Pruebas de concurrencia 9 Empaquetamiento de componentes de lógica de aplicación 11,00% DESPLIEGUE Empaquetamiento de componentes de acceso a datos Empaquetamiento de componentes de interfaz grafica Distribución de paquetes en los distintos nodos 33 Establecimiento de un modelo de pruebas Montaje de un servidor de pruebas Montaje de un servidor de control de escenarios Montaje de un servidor de control de versiones de software Pruebas del servidor CVS CONFIGURACION Y MANTENIMIENTO 5,00% Montaje de un servidor de subversiones 15 Montaje de un servidor de pruebas Administración del personal FASE DE TRANSICION 26% Administración de recursos ADMINISTRACION 1,00% Administración de recursos de computo 3 Observe amigo lector / estudiante que hay flujos que son transversales a todas las fases y tienen mas o menos la misma duración en todas las fases y lo mas interesante del asunto es que dichos flujos son precisamente los flujos de soporte que estábamos mencionando al comienzo de esta sección. PREGUNTAS QUE VERIFICAN LO APRENDIDO 1. Cual de las siguientes afirmaciones son FALSAS (Si es que hay varias falsas): a. El cronograma es independiente de la metodología usada. b. El cronograma en RUP, esta compuesto por los flujos de iniciación, elaboración, construcción y transición. c. En la fase de elaboración el flujo de implementación es el más importante. d. En la fase de elaboración el flujo de análisis y diseño es el más importante. e. No todas las afirmaciones anteriores son falsas f. todas las afirmaciones de la a) a la e) son falsas g. todas las afirmaciones de la a) a la e) son verdaderas. 2. Cual de las siguientes afirmaciones son FALSAS (Si es que hay varias falsas): a. La gestión del proyecto es un flujo de proceso que se debe tener en cuenta únicamente durante las fases de inicio y elaboración b. Una primera clasificación de los flujos en RUP es: Flujos de proceso y flujos de soporte. c. La forma en que se realicen los flujos de soporte es decisoria a la hora de observar la calidad con la que se presentan los flujos de proceso. 3. Cual de las siguientes afirmaciones son FALSAS (Si es que hay varias falsas): a. Los dos flujos de análisis y diseño mostrados en el diagrama de RUP clásico son dos flujos que hacen parte de los flujos de proceso y que se toman separadamente en dicho diagrama con el animo de resaltar que una cosa es el análisis y otra el diseño. 4. Para el caso de las afirmaciones que son falsas en el anterior cuestionario amigo lector / estudiante escriba la razón por la que son falsas mediante la elaboración de una afirmación que sea verdadera y que controvierta la afirmación falsa. A parte de la construcción de esta afirmación se debe hacer una composición de una justificación que respalde dicha afirmación. (Este punto vale lo mismo que todos los anteriores puntos reunidos, es decir este punto es medio parcial si lo contesta bien y si no lo contesta bien es medio parcial que haz perdido. También es el único punto que se califica por respuesta completa y conjunta bien contestada junto con la justificación y la afirmación que el lector / estudiante componga). Recordad que una pregunta o se responde bien o se responde mal, porque decir que una pregunta tiene dos falsas, cuando en realidad tiene tres falsas es no acertar con la respuesta. De otra parte decir que algo es falso cuando lo es, pero dar una justificación errónea bien sea falsa o cierta de la afirmación es no acertar con la respuesta a la pregunta. RESPUESTAS A PREGUNTAS DE LA SECCION 1. Las afirmaciones A, B, C, F y G son falsas 2. La afirmación A es falsa 3. La afirmación A es falsa 4. La justificación de las afirmaciones falsas son: Afirmación 1A “El cronograma es independiente de la metodología usada” Respuesta: “El cronograma es DEPENDIENTE de la metodología usada” Justificación: Es falsa porque de acuerdo a la metodología se plantea el cronograma, por ejemplo si la metodología es una metodología basada en las pruebas como en el caso de la metodología XP, se tienen que hacer en todo momento pruebas de todo y para el caso de RUP, una metodología que le da gran importancia a los requerimientos, vemos pues que aun cuando el proyecto a avanzado se deja la posibilidad que se sigan haciendo revisiones y ajustes a los requerimientos con el animo de lograr en la mejor medida que al sistema se le puedan corregir errores antes de tener el producto final. De otra parte las metodologías lineales deben reflejar esta linealidad en los cronogramas, en tanto que las metodologías iterativas como RUP, deben reflejar esta iteratividad en el cronograma. Afirmación 1B “El cronograma en RUP, esta compuesto por los flujos de iniciación, elaboración, construcción y transición”. Respuesta: “El cronograma en RUP, NO esta compuesto por los flujos de iniciación, elaboración, construcción y transición”. Justificación: Iniciación, elaboración, construcción y transición son fases y no flujos en RUP. Afirmación 1C “En la fase de elaboración el flujo de implementación es el más importante”. Respuesta: “En la fase de elaboración el flujo de implementación NO es el más importante”. Justificación: “En la fase de elaboración el flujo de análisis y diseño es el más importante”. Afirmación 1F “Todas las afirmaciones de la a) a la e) son falsas”. Respuesta: “Las afirmaciones A, B, C, F y G son falsas”. Justificación: “En la fase de elaboración el flujo de análisis y diseño es el más importante” y esta afirmación esta en el numeral D, con lo cual todas las afirmaciones de la a) a la e) no son falsas. Afirmación 2A: “La gestión del proyecto es un flujo de proceso que se debe tener en cuenta únicamente durante las fases de inicio y elaboración” Respuesta: “La gestión del proyecto es un flujo de SOPORTE que no solamente se debe tener en cuenta en las fases de inicio y elaboración” Justificación: La gestión del proyecto no es un flujo de proceso, sino un flujo de soporte. El flujo de gestión del proyecto hace parte de una de las mejores practicas en forma implícita (“en forma implícita, ya que las mejores practicas son: Administración de requerimientos, desarrollo iterativo, modelamiento visual, verificación de la calidad, arquitecturas con componentes y control de cambios”) y algunas de estas mejores 6 practicas están presentes en la gestión de un proyecto. Afirmación 3A: “Los dos flujos de análisis y diseño mostrados en el diagrama de RUP clásico son dos flujos que hacen parte de los flujos de proceso y que se toman separadamente en dicho diagrama con el animo de resaltar que una cosa es el análisis y otra el diseño” Respuesta: “Los dos flujos de análisis y diseño mostrados en el diagrama de RUP clásico son UN solo flujo que hace parte de los flujos de proceso y que se toman conjuntamente para efectos del diagrama de resumen de la metodología RUP” Justificación: El flujo se llama: Flujo de análisis y diseño y es que sean dos flujos por separado. Esta afirmación se puede corroborar observando detenidamente los diagramas que simplifican la explicación de la metodología RUP. 2. CONSIDERACIONES AL REALIZAR SU PROYECTO DE GRADO 2.1. SOBRE LAS FUNCIONES QUE DEBEN REALIZAR LOS PASANTES EN LOS PROYECTOS DE GRADO Las funciones deben ser acordes con lo expuesto en el Convenio Revisar la fecha, horario, verificandolo con el convenio. Preferiblemente observar si de las siguientes funciones faltan algunas para que sean incluidas en sus anteproyectos de grado de pasantias: Funciones relacionadas con la funcionalidad del sistema. Funciones relacionadas con la elaboracion de documentos que se entregaran a la empresa. Funciones relacionadas con la elaboracion de documentos que se entregaran a la U. Funciones de gestion necesarias para la realizacion del proyecto, como por ejemplo “configuracion de los servidores”, que es una funcion que se debe hacer algunas veces para que el sistema pueda ser implantado. Tener en cuenta de comprometerse a cosas que se puedan hacer por los pasantes y que no dependan de terceros, no comprometerse con la generacion de datos propios del desarrollo y puesta en funcionamiento del sistema, por ejemplo no comprometerse con cosas como: “Entregar el sistema academico con los datos de las notas del ano actual”. Porque esto involucra que a parte de realizar el sistema tambien se van a poner de secretarios a digitar las notas que los profesores entreguen para lograr generar los boletines de calificaciones. 2.2. CONSIDERACIONES SOBRE LAS PALABRAS QUE DEBE INCLUIR EL DOCUMENTO DE GRADO O PROYECTO DE SOFTWARE Es importante que tenga en cuenta a la hora de plantear el proyecto de grado que no se deben colocar palabras como las mostradas en la siguiente tabla: PALABRAS NO RAZON POR LA QUE UNA PALABRA PERMITIDAS NO SE PERMITE Etc, entre otros. Deja entrever que existen otros elementos Yo pienso que Dios es En los documentos de tesis Bueno y de investigación se colocan afirmaciones respaldadas por una comunidad o un grupo de personas relativamente influyente como para ser aceptada por lo menos por un gremio. Yo puedo concluir Deja entrever que la conclusión es subjetiva. PROPUESTA PARA REEMPLAZARLA Es mejor omitir la palabra y no colocar una palabra que signifique lo mismo. Una alternativa es decir cosas como: Las comunidades cristianas en todas sus expresiones entre las que figuran los católicos, evangélicos y ecuménicos expresan en sus diferentes acepciones de la biblia que Dios es un ser infinitamente Bueno. Con todo lo anterior se puede concluir que… Realice revisiones ortográficas del documento de anteproyecto y proyecto definitivo antes de entregarlo a quienes lo revisan. Otras palabras que es importante no incluir en el documento de tesis o en el anteproyecto se muestran en las siguientes tablas: Palabra o frase que hay que sacar de una Las causas del fenómeno X son: tesis Razón por la que se debe sacar Basura, uno no puede identificar todas las causas de algún fenómeno, recuerde que hay muertos que no hacen ruido. La siguiente frase queda un poco mejor en Entra las causas mas visibles del la tesis fenómeno X podemos citar: Palabra o frase que hay que sacar de una Para mi… tesis Razón por la que se debe sacar Recuerde que el pensamiento individual o personal (experimental) no tiene validez La siguiente frase queda un poco mejor en Podemos encontrar que.. la tesis Palabra o frase que hay que sacar de una Lo dijo fulanito o “sutangano” tesis Razón por la que se debe sacar El hecho que lo halla dicho alguien muy importante no quiere decir que sea la verdad, cuantas veces al mejor panadero se le quema el pan. La siguiente frase queda un poco mejor en Los siguientes autores coinciden en la tesis afirmar que 2.3. SOBRE LA INTRODUCCION DE LA TESIS Don de se encuentra la síntesis de los capítulos (Cuáles son los aportes a la persona y al profesional?), debe tener para un que, un para que y un como. 2.4. SOBRE El RESUMEN DE LA TESIS En forma pragmática un resumen es un texto que tiene en pocas palabras la descripción del contenido de otro texto. Según un curso impartido por el Doctor Jorge Luis Olaya Rodríguez un resumen debe poder responder a las siguientes preguntas: Cual es el tema principal del texto Donde y como se desarrolla el tema? Cuales son los temas secundarios del tema A? Las ideas principales y secundarias están relacionadas entre si? Cual es la conclusión del texto A? UN EJEMPLO DE UN RESUMEN En el presente documento se muestra el proceso de desarrollo seguido para la realización de un sistema multinivel sobre recursos humanos. Se desarrolla en la empresa RSN computación usando la metodología RUP e implementando una aplicación multinivel que esta disponible a los usuarios vía Internet. Para la realización del sistema se hizo necesario apropiarse de conocimientos sobre selección y contratación de personal con la colaboración de un profesional en el área de la sicología. Nota: La palabra sicología la real academia la ha establecido y la han cambiado con respecto a la palabra psicología. 2.5. SOBRE EL TITULO DE LA TESIS Si usted amigo estudiante esta pensando en hacer un sistema de información debe saber que hay varios tipos de sistemas de información, a saber1: Los sistemas de información pueden clasificarse en transaccionales, de apoyo a las decisiones y estratégicos. Los transaccionales, se caracterizan porque a través de ellos se automatizan las tareas y procesos operativos, se puede integrar gran cantidad de información institucional para ser utilizada posteriormente por los funcionarios de nivel operativo de la organización en la toma de decisiones. Los de apoyo a las decisiones, por su naturaleza misma apoyan la toma de decisiones repetitivas y no estructuradas, generalmente son desarrollados por el usuario final, proporcionan información de soporte para los mandos intermedios y la alta gerencia en el proceso de toma de decisiones. Los estratégicos, su función principal no es apoyar la automatización de los procesos operativos ni proporcionar información para apoyar la toma de decisiones, son desarrollados para uso interno, para lograr ventajas competitivas a través de su implantación y uso apoyando al nivel alto de la organización. 2.6. PLANTEAR OBJETIVOS GENERALES Y ESPECIFICOS Existen en Ingeniería de Software algo llamado “métricas de software” que son métricas que intentan medir el software de acuerdo a ciertas características, por ejemplo existen métricas de acoplamiento, de complejidad, de tamaño, de suficiencia, de cohesión, de primitivismo, de volatilidad, de similitud, por mencionar algunas, y aunque son muchas las métricas que los ingenieros de software han desarrollado, también son muchas las que no se han podido desarrollar debido básicamente a las características de los sistemas. Por ejemplo no se han podido desarrollar métricas de amigabilidad, por cuanto la amigabilidad es algo subjetivo que varia de un usuario a otro, es decir, podemos encontrarnos con dos usuarios de un mismo sistema y a uno de ellos le parece que el software es bastante amigable y fácil de usar en tanto al otro no le parece y es mas, le podría parecer que es poco amigable. Con todo lo anterior y teniendo en cuenta que los objetivos de un proyecto deben ser medibles, podemos afirmar que no se deben colocar en los objetivos palabras que no correspondan con métricas que permitan evaluar el logro de mencionado objetivo, dado que se estarían colocando objetivos no medibles y si no es medible, no debe ser objetivo. Pensando en esta situación se muestran a continuación algunos objetivos que no parecen ser objetivos en el sentido estricto de la palabra. 1 Esta clasificacion fue tomada de http://www.virtual.unal.edu.co/cursos/enfermeria/2002847/lecciones/tematica4/subtema4-8.html OBJETIVO QUE NO RAZON POR LA CUAL PARECE SER OBJETIVO NO PARECE SER OBJETIVO Construir el sistema Aunque es posible medir el operativo mas pequeño. tamaño del software por ejemplo usando las métricas de cantidad de funciones, cantidad de líneas de código, es bastante ambicioso este objetivo por cuanto es posible que salga en unos anos otras tecnologías que permitan construir sistemas operativos mas pequeños y en este momento se tendrían problemas con el cumplimiento del objetivo. Construir el mejor sistema Es posible construir este operativo en cuento a objetivo y cumplirlo seguridad de ingreso. aunque con mucho esfuerzo, pero se corren muchos riesgos al plantear este objetivo y la razón es que la seguridad es un tema bastante espinoso que hasta el momento ninguna casa de software puede decir que no ha tenido problemas de seguridad, y si hasta el momento todos los fabricantes de software han tenido problemas con seguridad no es recomendable ser tan osado y atreverse a realizar afirmaciones como esta. Construir un sistema bonito No existen métricas para medir lo bonito de un sistema. UNA FORMA ALTERNATIVA DE COLOCAR EL OBJETIVO Construir un sistema operativo que respecto a los actuales este entre los 10 sistemas operativos mas pequeños del mundo. Construir un sistema que permita la autenticación basado en el estándar X para encriptación de datos y usando el algoritmo Y como algoritmo de encriptación de datos al momento de enviar datos hacia el servidor. Construir un procesador de textos con una apariencia similar a la del procesador de textos Start Office. <<Este un objetivo mejorado, pero le falta Construir un sistema No existen métricas de agradable agradabilidad. Construir un sistema ágil. Lo ágil no solamente depende del programador o desarrollador del sistema, sino de la congestión de la red entre otros factores, razón por la cual no es bueno colocar este objetivo que no solamente depende de los desarrolladores del sistema. El objetivo propuesto faltaría todavía depurarlo, pero tan solo se coloca para dar una idea de cómo enfocar el objetivo Desarrollar un sistema de Es posible que el sistema registro de notas que permita agilizar los permita agilizar los procesos de preinscripción procesos de preinscripción de notas, pero de ser esto lo automática de notas. que se quiere se debe tener en cuenta que el proceso como tal depende de otros factores y no del software en su totalidad. Desarrollar un sistema de Esta bien, pero le falta mas consulta bibliotecaria cosas como en donde y que tipo de sistema va a ser. Software educativo que permita mejorar el nivel de aprendizaje en java de los estudiantes y les permita aprobar los parciales propuestos por los profesores de sistematización de datos. El software educativo es tan solo una herramienta que si es usada bien ayuda a mejorar los procesos de aprendizaje, pero en ningún caso reemplaza al docente. mejorar mas>> Seria bueno suprimir este objetivo Construir un sistema que en condiciones normales de red permita realizar consultas a datos en menos de un minuto si la base de datos no ha alcanzado los 20000000 registros y la red tiene una velocidad promedio de 200 kb por segundo y no se presentan sistemas que interfieran con los puertos y servicios que usa el sistema en cada una de las maquinas. Colocar en alguna parte del documento algo que aclare que en condiciones normales de uso se cumpliría, pero que el proceso se puede agilizar si existe la disposición y las condiciones para que esto se de. Sistema intranet de consulta bibliotecaria en la Facultad Tecnológica de la Universidad Distrital Desarrollar un material educativo computarizado que sirva de apoyo al proceso de enseñanza de los principios de programación orientada a objetos con Java. 2.7. OTRAS COSAS SOBRE LOS OBJETIVOS ESPECIFICOS No debería haber menos de 3 objetivos específicos. Recuerde que en la mayoría de las instituciones si usted cambia un objetivo específico podría estar alterando el proyecto como tal y le tocaría formular otro proyecto. Una forma de bosquejar los objetivos específicos es que vislumbre los menus principales del sistema y cuales serian las opciones principales del menú principal y justamente estos corresponderán con algunos de los objetivos específicos del proyecto de desarrollo de software. POR EJEMPLO SI EL PROYECTO ES Desarrollar un editor de textos. ALGUNOS OBJETIVOS ESPECIFICOS SERAN Realizar un subsistema que permita la importación y exportación de documentos con el S.O. (Archivo) Desarrollar un subsistema que permita la manipulación de texto al interior del documento presentando formas de tipo de letras y de fuentes diversas. = (Edición) Desarrollar un subsistema que permita la visualización del documento en varias vistas incluyendo presentaciones personales y de impresión. RAZON DE LOS OBJETIVOS ESPECIFICOS Si usted observa las opciones principales que aparecen en la mayoría de los editores de texto encuentra estas opciones. Osea que una forma de vislumbrar el asunto es observando aplicaciones que hagan cosas que usted esta haciendo en su proyecto de desarrollo de software, aunque no sean completamente iguales le darán una noción de las opciones principales de menú y de algunos de los objetivos del proyecto. Recuerde que hay algo de relación con los subsistemas del proyecto, las opciones principales del menú principal y los objetivos específicos, no se esta diciendo que las tres sean iguales, simplemente que hay algo de relación. EJEMPLOS DE OBJETIVOS MAL REDACTADOS Disenar y desarrollar una base de datos. RAZON POR LA QUE ESTA MAL Las bases de datos son difíciles de desarrollar porque ya están desarrolladas a menos que uno la vaya a mejorar. CORRECTO. Disenar e implementar. EJEMPLOS DE OBJETIVOS MAL REDACTADOS Entender las necesidades de la organizacion RAZON POR LA QUE ESTA MAL Las necesidades son muy grandes y todas no se pueden abarcar. CORRECTO. Concretarlo mas. 2.8. ALGUNOS EJEMPLOS DE OBJETIVOS Y SUS CORRECCIONES UN OBJETIVO BUENO, PERO MAL Desarrollar módulo básico de registro, este REDACTADO módulo permite el ingreso de los datos de los estudiantes, y maestros de la institución RAZONES POR LAS QUE ESTA MAL La forma como esta escrito el objetivo da REDACTADO la impresión de indicar el objetivo, después se esta colocando una coma y a continuación la explicación del modulo, con lo cual el objetivo queda mal redactado al parecer explicación de algo. De otra parte la palabra “de los” es redundante UNA CORRECCION SUGERIDA AL ANTERIOR OBJETIVO Desarrollar un modulo de registro que permita el ingreso de los datos referentes a los estudiantes y maestros de la institución. ANALISIS DEL SIGUIENTE OBJETIVO Implementar un módulo de seguimiento para maestros y estudiantes que permitan el cumplimiento de los procesos definidos por la institución EL ANTERIOR OBJETIVO TIENE LAS Tenga en cuenta que el objetivo anterior SIGUIENTES REPERCUSIONES. involucra que todos los procesos definidos por la institución serán sistematizados en un modulo, cosa que es bastante complicada en un software. SE RECOMIENDA DELIMITAR LOS Implementar un módulo de seguimiento PROCESOS QUE SERAN para maestros y estudiantes que permitan SISTEMATIZADOS el cumplimiento de los procesos académicos definidos por la institución ANALISIS DEL SIGUIENTE OBJETIVO Desarrollar una herramienta de fácil manejo que permita la interacción de las personas que participan en los procesos. EL ANTERIOR OBJETIVO TIENE LAS Se esta comprometiendo a que la SIGUIENTES REPERCUSIONES. herramienta será de fácil manejo sin importar el usuario que la use. Garantizar SE RECOMIENDA CUALIDADES QUITAR la facilidad para cualquier usuario es bastante complicado por cuanto es muy posible que las cosas fáciles para unos, sean complicadas para otros. Es de notar que este tipo de cosas se presentan por colocar cualidades en los objetivos y cualidades que no tienen métricas asociadas. LAS Desarrollar una herramienta que permita la interacción de las personas que participan en los procesos. ANALISIS DEL SIGUIENTE OBJETIVO Desarrollar un sistema de fácil acceso ya sea en un área local o remota, para la comodidad de los usuarios del sistema. EL ANTERIOR OBJETIVO TIENE LAS A parte de tener la palabra fácil, tiene otra SIGUIENTES REPERCUSIONES. palabra que es comodidad y esto son objetivos bien complicados de implementar en el desarrollo de aplicaciones tipo software SE RECOMIENDA REPLANTEAR EL Desarrollar un sistema que pueda ser OBJETIVO QUITANDOLE TODAS LAS accedido desde redes locales o remotas. CUALIDADES 2.9. CUIDADOS AL PLANTEAR EL ALCANCE DEL PROYECTO AL momento de plantear el alcance de su proyecto tenga en cuenta algunos de los errores mas comunes que se presentan en proyectos de grado, como los siguientes: ALCANCE QUE NO RAZON POR LA QUE EL ALCANCE MEJORADO ESTA BIEN ALCANCE NO ESTA QUE POSIBLEMENTE REDACTADO BIEN REDACTADO. FALTE DEPURARLO El sistema alcanzara a ser Es bastante osado este Sistema que valide la el sistema mas seguro en objetivo y esta entrada de los usuarios Colombia. subvalorando la capacidad basado en el mecanismo de de otros desarrolladores, clave y nombre de usuario. cosa que nunca se puede El sistema usara cookies o hacer. sesiones para restringir el acceso a ciertos módulos web. Se sugiere que en los formatos de anteproyectos de grado no se quite esta parte de las limitaciones y alcance, por cuanto estos son importantes en la definición del anteproyecto de grado. 2.10. COSAS HA TENER EN CUENTA EN EL PLANTEAMIENTO DEL PROBLEMA No siempre lo que se ve como problema es un problema. Por ejemplo decir que: “El problema es que mi papá lleva su contabilidad en un cuaderno”, parece ser un problema, pero si vemos que los ingresos de mi padre no son muchos y como si fuera poco nadie le exige contabilidad y sus gastos ya no son artos por cuanto esta pensionado y sus hijos ya son independientes y como si fuera poco no tiene negocios, ni quiere tenerlos, diríamos que lo que parecería ser un problema ya no lo es. Hay veces que los problemas no se dicen completos y esto hace que el problema no quede bien especificado. Por ejemplo el siguiente problema: “El problema es que yo amo a Natalia Paris”, puede ser entendido por algunos, pero otros no lo podrán comprender, pero si coloco el objetivo completo: “El problema es que yo amo a Natalia Paris y ella no me ama”, entonces vemos que el problema es bien claro. Y finalmente podemos decir que en el planteamiento del problema tenemos que las personas tienden a ver las soluciones a estos problemas de acuerdo a su área de estudio y sus conocimientos y para comprender esto veamos la siguiente tabla: PROBLEMA SOLUCION El señor Mario Silva Colocarle no ve bien por un gafas. ojo. PROFESION DEL QUE DIO LA SOLUCION. unas Oftalmólogo Mi Padre tiene Desarrollar un Ingeniero problemas con su sistema contable Sistemas contabilidad. para las necesidades de mi Padre. LA SOLUCION NO SIEMPRE ES LA MEJOR Es posible que al colocarle gafas vea, pero la solución óptima podría ser operarlo de la miopía, pero esta solución no fue vista por cuanto el área de conocimiento del que dio la solución era un oftalmólogo que no sabia hacer operaciones de ojos. de A mi Padre no le gusta estar pegado a un computador y a duras penas usa Word cuando le toca y como si fuera poco sus contabilidades son pequeñas y pueden caber perfectamente en una hoja de cuaderno. Y la razón del problema contable de mi Padre es que se le perdían las facturas, con lo cual la mejor solución no era construir un sistema contable sino darle algunas nociones de archivística y comprarle el legajador para que guarde sus facturas de las mesadas de su pensión. Es mas, usar el computador para sumar uno mas uno es mucha tecnología, es como usar una escopeta para matar a una mosca. Según lo mostrado en el cuadro anterior queda el interrogante siguiente: ¿Cómo hago para saber si algo es un problema que se puede solucionar con software?. Una de las formas para saber esto es haciendo uso de las cualidades de la información entre las que podemos encontrar: Veracidad Identidad Integridad Capacidad Seguridad Fiabilidad Confidencialidad Autenticación No denegación No repudiación Accesibilidad Si estas se llegan a ver afectadas muy seguramente es porque hay un problema de información y si el problema es de información muy posiblemente se puede atacar con la creación de un sistema informático. Si ninguna de estas características se ven afectadas es porque no es un problema que pueda ser solucionado por profesionales de la información, sino por otro tipo de profesionales, puede ser por médicos, veamos un ejemplo de esto. PROBLEMA MAL SOLUCION PLANTEADO CUALIDAD AFECTADA El problema es que Desarrollar un uso Excel para sistema informático almacenar la en Access. información de 65536888888 clientes. El problema no debe ser planteado como que se usa Excel, sino que en Excel la información para esta cantidad de registros no se guarda en forma segura, es mas ni siquiera se guarda. PLANTEAMIENTO MEJORADO PERO EN PROCESO El problema es que el sistema actual no permite almacenar en forma SEGURA la información de 65536888888 clientes. También hay que tener en cuenta hasta que punto el problema que al parecer es informático no lo es, debido a factores no informatizables que afectan el problema. Por ejemplo. EJEMPLO DE PROBLEMA MAL PLANTEADO PLANTEMIENTO DEL PROBLEMA El problema es que la información se almacena no es veraz e integra. RAZON POR LA QUE EL PROBLEMA ESTA MAL PLANTEADO La razón es que la persona que lo almacena tiene problemas de digitación por cuanto sus ojos y sus dedos presentan problemas. Vemos que el problema que parecería ser solucionable por medios informáticos no puede ser solucionado debido a que las causales no son por mal funcionamiento del sistema en este aspecto. UN PLANTEAMIENTO NUEVO DEL PROBLEMA No es un problema para solucionar un profesional de la informática. OTRO EJEMPLO DE PROBLEMA MAL PLANTEADO PLANTEMIENTO DEL PROBLEMA El problema es que la empresa no cuenta con un sistema de enseñanza de las tablas de multiplicar. RAZON POR LA QUE EL PROBLEMA ESTA MAL PLANTEADO El planteamiento del problema debe dejar entrever que existen varias soluciones, y si según el problema planteado la única solución es construir un sistema de enseñanza de las tablas de multiplicar. Recordemos que en los problemas se tienen alternativas de solución y la forma como se definió el problema no da para construir alternativas de solución. UN PLANTEAMIENTO NUEVO DEL PROBLEMA Los estudiantes solo tienen acceso a libros que muestran las tablas de multiplicar, pero por sus bajos recursos no cuentan con otros modelos pedagógicos que le permitan apropiarse del conocimiento de las tablas de multiplicar teniendo en cuenta que el modelo de libros solo es acorde con estudiantes que tienen psíquicamente asociado un modelo repetitivo de aprendizaje, dejando por fuera a los que por su naturaleza tengan asociados otros modelos pedagógicos como el constructivista, el jerárquico, en didáctico y el metódico. OTRO EJEMPLO DE PROBLEMA MAL PLANTEADO PLANTEMIENTO DEL PROBLEMA El problema es que la empresa usa Word para almacenar los datos RAZON POR LA QUE EL PROBLEMA ESTA MAL PLANTEADO Si el anterior problema es un problema también lo será el siguiente: El problema es que la empresa usa Satara suit 4.5 para almacenar los datos. Pero, con seguridad este nuevo problema no es comprendido debido a que la herramienta Word es mas conocida por una mayoría, mientras que Satara suit 4.5 no, con lo cual se tiene que si alguien desconoce Word no comprenderá el problema. Bueno, esto es una exageración, pero muestra que el problema debe incluir la cantidad menor de tecnicismos posibles, obviamente hay momentos en los que es imposible quitarlos. UN PLANTEAMIENTO NUEVO DEL PROBLEMA El problema es que la empresa usa un procesador de textos que no tiene la capacidad para soportar el volumen de datos exigidos por la empresa. NOTA Se recomienda que en ningún formato de anteproyecto de grado se quite el planteamiento del problema. Se recomienda que en ningún formato de anteproyecto de grado se quiten las alternativas de solución a los problemas. 2.11. EJEMPLO DESGLOSADO DE DESCRIPCION DEL PROBLEMA Si el titulo del sistema es: Sistema multinivel para el registro único nacional de talento humano en salud en el área de recursos humanos del ministerio de la protección social. Comenzamos identificando componentes y elementos del dominio del problema. Componente1 = DERECHO LABORAL Componente12= ETICA FRASE QUE ENGLOBA EL KERNEL DEL PROBLEMA. Formulacion se puede hacer mediante una pregunta, lo dicen muchos textos de metodología de la investigación. ¿Como hacer para que los que ejerzan las profesiones en las aéreas de salud tengan la formación para hacerlo? Según el formato de la Universidad. ¿Por que debería resolverse? Porque si personas no calificadas ejercen cargos en áreas de la salud, se pueden presentar altos riesgos para la atención a los usuarios del sector de la salud. -Que soluciones existen actualmente y por qué debería buscarse nuevas soluciones. Una solución es una ley que salió para controlar y vigilar el ejercicio ilegal de las profesiones y ocupaciones en el área de la salud.. La situación actual Actualmente el manejo de la información para la expedición de la tarjeta, consiste en diligenciar los documentos necesarios de una manera personalizada, generando retardos en la verificación de los documentos ya que solo se realizara la comprobación de los mismos cuando la entidad considere que hay suficientes solicitudes para empezar. Las raíces del problema Muchas personas no se capacitan para ejercer puestos en el área de la salud y sin embargo ejercen usando títulos falsos Situación deseada Solamente los profesionales que tengan los requisitos establecidos por la ley pueden ejercer ocupaciones en el aérea de la salud. Comparación entre lo actual y lo deseado. Se conocen resultados de aplicación de estas soluciones en otras partes. En el mundo existen aplicaciones basadas en XML para intercambiar información entre sectores de la salud. Un estándar a nivel mundial para la realización de sistemas en el area de la salud es el HL7, el cual se encuentra en www.hl7.org. Por que profundizar en el tema Porque el desarrollo de sistemas de este permitirían contar con mejores beneficios en la formación y atención dentro de la disponibilidad dentro de la disponibilidad del sistema educativo y de servicios, con los menores riesgos para los usuarios de los servicios de salud. 2.12. COSAS SOBRE LAS DELIMITACIONES Recuerde que en las delimitaciones se colocan las cosas que no me comprometo a hacer. SI EL PROYECTO ES Desarrollar un sistema para la enseñanza de las tablas de multiplicar en grados tercero y cuarto de primaria de la Escuela la Alquería. UNA DELIMITACION SERIA Esta es una herramienta de apoyo al aprendizaje de las tablas de multiplicar en ningún momento podrá ser usada para evaluar la capacidad de los niños en el tema de las tablas de multiplicar. 2.13. SOBRE EL ALCANCE Y LAS DELIMITACIONES En la media de lo posible para proyectos de software es bueno bosquejar alcances y delimitaciones de acuerdo a la siguiente tabla: ALCANCE Y SUBDIVISION EXPLICACION EJEMPLOS DELIMITACION TECNICA PLATAFORMA LENGUAJE HARDWARE MODELADO INFRAESTRUCTA DE RED OPERATIVA FORMACION EXPERIENCIA ACADEMICA ESPACIO DISPOSICION FUNCIONAL NAVEGACIONAL ACTORES INTERNOS ESCENARIOS GEOGRAFICA TEMPORAL 2.14. COSAS SOBRE EL RIESGO Recuerde que a todo proyecto hay que verle los riesgos no para no sufrir, sino para evitar que el impacto sobre el desarrollo del proyecto sea negativo frente a eventualidades y percances que se presenten en el entorno del proyecto. SI EL PROYECTO ES Desarrollar un sistema para la enseñanza de las tablas de multiplicar en grados tercero y cuarto de primaria de la Escuela la Alquería. UN RIESGO SERIA Cambien los equipos de la sala de sistemas y como REDP dona computadores y la Escuela no tiene suficientes recursos para adquirir licencias, adquieran equipos con S.O. Linux. Y Frente a este riesgo hay que establecer por lo menos dos planes: PLAN A Desarrollar un sistema que también se pueda ejecutar en Linux. PLAN B Desarrollar el software web en un servidor externo para que pueda ser accedido usando el navegador de internet de Linux. 2.15. SOBRE EL MARCO TEORICO. Es bueno involucrar marco teórico sobre la plataforma utilizada. Marco teórico sobre la metodología usada Marco teórico sobre el lenguaje de modelamiento usado Marco teórico sobre la base de datos usada y/o los sistemas de persistencia utilizados. Marco teórico sobre la lógica del negocio Es bueno colocar en el marco teórico el estado del arte, que en pocas palabras hace referencia a los actuales desarrollos tecnológicos a nivel mundial y nacional sobre lo que se esta intentando realizar. 2.16. COSAS HA TENER EN CUENTA SOBRE EL MARCO HISTORICO Para mostrar por medio de un ejemplo como hacer un marco histórico, digamos que mi sistema es construir un sistema educativo para la enseñanza de las tablas de multiplicar, con lo cual el marco histórico seria el siguiente: Como han evolucionado los sistemas educativos que ensenan las tablas de multiplicar. En un principio las tablas se aprendían a juete, después se repetía como lora mojada, después se inventaron las tablas giratorias, reglas aritméticas, memofichas la clave de sus estudios, las tablas cantadas, software de repetición de tablas, software de combate que ensenan las tablas de multiplicar, sistemas expertos. 2.17. COSAS SOBRE EL MARCO CONCEPTUAL En el marco conceptual se colocan diccionario de términos raros y técnicos. 2.18. COSAS SOBRE EL MARCO REFERENCIAL En el marco referencial se colocan que otras empresas han hecho lo que el proyecto indica que se va a realizar. En caso que 2.19. COSAS SOBRE LOS COSTOS DEL PROYECTO Recuerde que el software libre no es gratis. Recuerde que hay costos fijos y variables que deben ser tenidos en cuenta en sus proyectos. 2.20. COSAS SOBRE LA FACTIBILIDAD OPERATIVA DEL PROYECTO Es necesario observar si los usuarios del sistema tienen las habilidades necesarias para manipular el sistema. 2.21. COSAS SOBRE LA METODOLOGIA Sin importar la metodología que escoja es importante tener en cuenta que no puede olvidar las cuatro p de la ingeniería de software que son: Producto Proceso Proyecto Personal También es importante tener en cuenta que el presente documento esta pensado en proyectos de software que usen la metodología RUP, junto con el lenguaje UML, como lenguaje de modelado. Si se piensa realizar un proyecto de software con otra metodología es posible que este material no aporte lo que usted espera. 2.22. COSAS HA TENER EN CUENTA EN EL MODELAMIENTO Es bueno tener en cuenta que en UML se pueden modelar clases y también se pueden modelar objetos. Por lo que los objetos del modelo de objeto de Documento DOM que usan los navegadores en sus JavaScript son plenamente modelables con UML. Recordemos que la especificación UML 2.0 ha dicho que se pueden modelar paginas html cosa que no se podía hacer con las versiones anteriores de UML. Si un estudiante hace proyectos con lenguajes como PHP que no son del todo orientados a objetos, pueden perfectamente modelar todo lo que hagan si es que lo hacen sin usar la funcionalidad de objetos que provee la herramienta, otra cosa es que no usen la funcionalidad de objetos que permite el lenguaje como en el caso de PHP 5.0, que entre otras tiene muchos enemigos cuando de usar todas las características de objetos se trata debido a que muchos puritanos del modelamiento dicen que si se hace un sistema orientado a objetos que se haga en su totalidad orientado a objetos, pero no unas cosas con objetos y otras cosas estructuradas como pasaría con PHP 5.0. Recordemos también que PHP es de orientación a objetos y no orientado a objetos. 2.23. TALLER PROPUESTO PARA MEJORAR LA FASE DE PLANEACION DEL PROYECTO PROFESOR: LUIS FELIPE WANUMEN SILVA Según los proyectos que han establecido en el ultimo taller en donde establecida el titulo del trabajo, el objetivo general, el objetivo especifico, los recursos usados, la factibilidad, técnica operativa, factibilidad económica, requerimientos funcionales, requerimientos legales, requerimientos legales y de instalación responda las siguientes preguntas: Establezca los sustantivos del titulo del proyecto que usted va a realizar para clase. Establezca los sustantivos de los objetivos generales del proyecto que usted va a realizar. Llene la siguiente tabla: Sustantivos que no Sustantivos que aparecen en aparecen en el titulo objetivo alguno, pero que usted cree que hacen parte del sistema. Sustantivos que aparecen en el objetivo general Llene la siguiente tabla: Acciones que debe Lista de verbos que desempeñar el sistema, pero aparecen en el titulo del que no están en el titulo, ni proyecto en el objetivo general, ni especifico. Sustantivos que aparecen en los objetivos específicos Empresa, sustantivo, persona, cargo, departamento o similar con el que se encuentra asociada la acción de la anterior columna. Llene la siguiente tabla: Acciones que debe Lista de verbos que desempeñar el sistema, pero aparecen en el titulo del que no están en el titulo, ni proyecto en el objetivo general, ni especifico. Llene la siguiente tabla: Acciones que debe desempeñar el sistema, y que se encuentran en el objetivo general del proyecto. Llene la siguiente tabla: Lista de acciones que son desempeñadas por personas de carne y hueso, y que también debe desempeñar el sistema. Llene la siguiente tabla: Lista de actores del sistema Empresa, sustantivo, persona, cargo, departamento o similar con el que se encuentra asociada la acción de la anterior columna. Acciones que debe desempeñar el sistema, y que se encuentran en los objetivos específicos del proyecto. Lista de acciones que son desempeñadas por personas de carne y hueso pero que no son desempeñadas por el sistema o software que usted a va realizar. Lista de acciones que son desempeñadas por el sistema, pero que no son desempeñadas por el sistema. Lista de acciones Espero que esta vez, si entreguen el trabajo, no como la vez pasada que no lo entregaron, sino tan solo unos pocos, porque de no entregarlo, la nota de talleres le queda en CERO. 2.24. TALLER PROPUESTO PARA PENSAR EN OBJETOS 1. Construir la clase denominada Circulo que permita a. Definir el centro y el radio b. Calcular su area c. Calcular la longitud de la circunferencia d. Un metodo que muestre todos los atributos del objeto Esta clase debe heredar de la clase punto para definir su centro 2. Construir la clase Cilindo que herede de la clase Circulo que permita: a. Calcular su volumen b. Un metodo que muestre todos los atributos del objeto 3. Construir la clase Cono que herede de la clase Circulo que permita a. Calcular su volumen V = 1/3(Area*h) b. Calcular su area total At = Pi*r(g+r) c. Un metodo que muestre todos los atributos del objeto El area debe ser un atributo heredado y g es la hipotenusa que forma h y r del cono 4. Estas clases deben ser construidas en lenguaje JAVA y los datos de los objetos deben ser ingresados por el usuario. Mentalidad para solucionar y pensar en orientación a objetos. Se debe usar la herencia y aplicar conceptos de programación orientada a objetos. Para las dos horas de Clase: 1. Hacer los diagramas de casos de uso 2. Construir el diagrama de secuencia 3. Construir los diagramas de Actividad Individual. Hora de Entrega 4:00 PM Día de entrega: 01 de Abril de 2008 Para la próxima Clase 4. Construir el programa, pensando mentalmente que quede con un correcto diagrama de secuencia (en Java Obviamente se realiza el programa) (El complique es que el programa debe ser un autónomo.) 2.25. ALGUNAS COSAS DE COMO PLANTEAR EL TITULO DE UN PROYECTO RELACIONADO CON SOFTWARE Con las siguientes tablas, se pueden comenzar a ensamblar títulos de tesis tentativos. Obviamente no todas cuadran con todas, pero si con muchas de las de la siguiente tabla. También sería tedioso hacer un título usando todas las tablas, pero se puede pensar en un título que contenga dos o tres tablas más algo específico que el desarrollador quiera mostrar. Sin embargo estas tablas son supervaliosas para mejorar la redacción del título del proyecto. PARTE A 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 Administración de Análisis de Analizar el impacto de Analizar la evolución de Analizar y rediseñar Aplicación de Aprendizaje Automatización de Búsqueda de Caracterizar Comparar Composición de Conexión de Control de Desarrollo de Desarrollo de un Desarrollo de un modelo de Detección de Diseñar un sistema Especificación de Estudiar la Evaluar las distintas alternativas Exportación Extensión del estándar Extracción de Generación de Gestión de 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 Identificación de Identificar y establecer prioridades acerca de Implementación de Importación Indexación Integración de Interconexión de Manipulación de Modelado Monitoreo Optimización de Orquestación Personalización de Predicción de Procesamiento de Recolección de Reconocimiento de Reconstrucción Recuperación de Selección de Sincronización de Tipificación de Utilización de Verificación de PARTE “B” Ambiente virtual de aprendizaje Objeto Virtual de aprendizaje Red Neuronal Sistema experto Sistema de información geográfico Sistema de información gerencial MEC Material Educativo computarizado Solución BPM Business Process Management Solución BI Business Intelligent PESI Planeación estratética de sistemas de información HelpDesk CRM Custom Relation Management CMS Content Management System ERP Enterprise Relation Planimetric gestión de Recursos Humanos (HRM) AVA OVA RN SE SIG sistema para la administración de la relación con los clientes (CRM) Videojuego Micromundo Tutorial Entrenador virtual Recorrido virtual Sistema de alertas Sistema de detección Sistema de difusión Organizacional Conocimiento Sistema clasificador Sistema multinivel Sistema de procesamiento de transacciones (TPS). Sistemas de información gerencial (MIS) Sistemas de soporte a decisiones (DSS) Sistemas de información ejecutiva (EIS) Sistemas de automatización de oficinas (OAS) Sistema Planificación de Recursos (ERP) Sistema experto (SE). Sistema de Administración de Cursos (LMS) Sistema web Entorno Virtual análisis de la canasta de compra (MBA) (CRM) Datos Comportamientos Juego didáctico Base de datos Bodega de datos Simulador Comunidad de práctica Plataformas Estrategia de Esquemas de Interfaces Parámetros de Infraestructura Descripciones Tendencias Mejoras tecnológicas Vulnerabilidades Requerimientos Información los procesos de las tecnologías las aplicaciones situación actual los principios Fraudes Intrusos Una metodología Método de Patrón de análisis Patrón de diseño Patrón de implementación Middleware Técnicas Ambiente Mecanismos de valoración Hábitos de Teoría de Métricas Fallos Framework marco DE PARTE “C” Clasificación Selección Ponderación Normalización Agentes Patrones Segmentación Difusión Pruebas Almacenamiento Replicación Administración Manipulación Sincronización Orquestación Integración Creación Recopilación PARA PARTE “D” Aseguramiento de entornos informáticos Modelado de Visualización de La verificabilidad de Aplicaciones Enterprise Modelado de grafos Detección de patrones Desarrollo de software Proveer servicios Soportar servicios Intercambio de información Intercambio de procesos Dispositivos Ambientes de aprendizaje Apoyo de Administración de Almacenamiento de BASADO EN PARTE “E” tecnología J2EE SAP Realidad aumentada Gramáticas 3D 2D Posición Especificación de requisitos según el estándar IEEE 830 Procesos de gestión Norma ISO 12207 Proceso de ciclo de vida del software ISO/IEC 14764 Conceptos y definiciones de testing ISO/IEC/IEEE 29119-1:2013 Proceso de testeo ISO/IEC/IEEE 29119-2:2013 Documentación de pruebas IEEE. ISO/IEC/IEEE 29119-3:2013 Técnicas de testeo ISO/IEC/IEEE DIS 29119-4.2 Testeo dirigido por palabras clave ISO/IEC/IEEE CD 29119-5. Keyword-Driven Testing estándar IEEE 828 Planes de gestión de configuración de software estándar IEEE 830 Prácticas recomendadas para la creación de especificaciones de requisitos de software o SRS IEEE 1233 Guía para el desarrollo de especificaciones de requisitos de software Norma IEEE 1028 Revisión de software antes del lanzamiento formal IEEE 1042 Guía para la gestión de configuración de software con los detalles de cómo llevar a cabo el plan de gestión de la configuración. IEEE Std. 610.12-1990. IEEE Standard Glossary of Software Engineering Terminology IEEE Std. 1016-1998. IEEE Recommended Practice for Software Design Descriptions IEEE Std. 1471-2000. IEEE Recommended Practice for Architectural Description of Software Systems IEEE Std. 1012-1998. IEEE Standard for Software Verification and Validation IEEE Std. 1008-2002. IEEE Standard for Software Unit Testing IEEE Std. 1058-1998. IEEE Standard for Software Project Management Plans IEEE Std. 730-1998. IEEE Standard for Software Quality Assurance Plans IEEE Std. 830-1998. IEEE Recommended Practice for Software Requirements Specifications Norma SPICE. Proceso de ingeniería, Gestión, relación cliente-proveedor, de la organización y el soporte. Estándar COBIT. Mejores prácticas para la gestión de los sistemas de información de las organizaciones Norma ISO/IEC 2000. Estándar en gestión de servicios de tecnologías de información. IEEE-std-830-1998. Práctica Recomendada para la Especificación de Requerimientos de Software. Android Códigos QR Web Inteligencia empresarial Business intelligent Minería de datos espacial Minería de datos de texto Minería de datos de video Modelo de capacidad de madurez test driven development MDA Workflows Reconocimiento de voz Lenguaje natural Planeación estratégica Sistema de control y seguimiento Aplicación de la metodología X Plan de comercialización Métricas de software Algoritmo aplicado a Generación automática de Plataforma Sistemas orientados a servicios Arquitecturas P2P Red Neuronal Algoritmo genético Data Mining Técnicas de aprendizaje Técnicas de optimización Sistemas inteligentes autónomos Algoritmos evolutivos Arquitecturas de software CORBA Programación dinámica Programación genética Programación orientada a objetos Programación orientada a aspectos Programación orientada a eventos Programación estructurada Programación procedimental Programación orientada a atributos Programación basada en etiquetas Programación orientada a servicios Esquemas multihilo simultáneo Sistemas distribuidos Sistemas multiagente BPM Hardware gráfico programable Plataformas de desarrollo de aplicaciones Reglas de asociación Redes Decisiones de diseño Decisiones de arquitectura Sistemas de tiempo real Protocolos de Mecanismos Razonador Ontologías Tarjetas de video programables GPU Sistemas de administración UML Árboles de decisión Firmas digitales Drones Repositorio Intefaces Canales Servicios Mensajes Lenguaje descriptivo ASN.1 Lenguaje descriptivo EBML Lenguaje descriptivo YAML Lenguaje de presentación Rich Text Format Lenguaje de presentación S1000D Lenguaje de presentación TeX Lenguaje de presentación troff Lenguaje de presentación HTML Lenguaje ligero BBCode Lenguaje ligero Markdown Lenguaje ligero ReStructuredText Lenguaje ligero setext Lenguaje ligero Textile Lenguaje ligero Wikitexto Lenguaje para manuales DocBook Lenguaje para manuales HelpML Lenguaje para manuales LinuxDoc Lenguaje para manuales POD Lenguaje para manuales Microsoft Assistance ML Lenguaje para interfaz de usuario GladeXML Lenguaje para interfaz de usuario MXML (Macromedia) Lenguaje para interfaz de usuario User Interface ML Lenguaje para interfaz de usuario XAML and MyXaml Lenguaje para interfaz de usuario XForms Lenguaje para interfaz de usuario XUL / XBL Lenguaje de sindicación Atom Lenguaje de sindicación RSS Lenguaje de sindicación ICE Lenguaje de sindicación OPML y OML Lenguaje de sindicación SyncML Lenguaje para servicios web WSDL Lenguaje para servicios web XINS Lenguaje para servicios web WSCL Lenguaje para servicios web WSFL Lenguaje para servicios web XML-RPC Lenguaje para servicios web Webml Lenguaje para Gráficos 2D: SVG Lenguaje para Gráficos 2D: CGM Lenguaje para Gráficos 2D: VML Lenguaje para Gráficos 2D: InkML Lenguaje para Gráficos 3D: VRML/X3D Lenguaje para Gráficos 3D: STEP Lenguaje para Matemática: MathML Lenguaje para Matemática: OpenMath Lenguaje para Música: LilyPond Lenguaje para Música: MusicXML Lenguaje para Taxonomía: DITA Lenguaje para Finanzas: eXtensible Bussiness Reporting Language Lenguaje para Finanzas: Financial products ML Lenguaje para Geomática: Geography ML Lenguaje para Aeronáutica: Spacecraft ML Lenguaje para Multimedia: Synchronized Multimedia Integration Language Lenguaje para Voz: VoiceXML Lenguaje para Voz: CCXML Lenguaje para Voz: CallXML Lenguaje para Voz: SALT Lenguaje para Mensajería instantánea: XMPP Lenguaje para Videojuegos: BulletML Lenguaje para Videojuegos: COLLADA Lenguaje para definición de vocabularios RDFS o RDF Schema Lenguaje para definición de vocabularios DAML Lenguaje para definición de vocabularios DAML+OIL Lenguaje para definición de vocabularios OWL o DAML-S Lenguaje para descripción de servicios WSDL Lenguajes para la descripción semántica de los servicios Web OWL-S Lenguajes para la descripción semántica de los servicios Web WSMF (Web Service Modeling Framework) Lenguajes para la descripción semántica de los servicios Web WSMO (Web Service Modeling Ontology) Lenguajes para la descripción semántica de los servicios Web WSML (Web Service Modeling Language) Lenguajes para la descripción semántica de los servicios Web WSDL-S Lenguajes para la descripción semántica de los servicios Web SAWSDL Lenguajes para la especificación de la composición de los servicios Web BPEL4WS Lenguajes para la especificación de la composición de los servicios Web WSFL ((Web Services Flow Language)) Lenguajes para la especificación de la composición de los servicios Web WSCL (Web Services Conversation Language) Lenguajes para la especificación de la composición de los servicios Web BPML Bases de datos jerárquicas Base de datos de red Bases de datos transaccionales Bases de datos relacionales Bases de datos multidimensionales Bases de datos orientadas a objetos Bases de datos documentales Bases de datos deductivas Sistemas Operativos paralelos Sistemas Operativos de red Sistemas Operativos distribuidos Sistemas Operativos de tiempo compartido. Sistemas Operativos de tiempo real Sistemas Operativos por lotes Sistema Operativo Multiusuario Sistema Operativo Monousuario Sistema Operativo Monotareas ORIENTADAS A PARTE “F” Componentes reutilizables componentes ADJETIVOS PARTE “G” Estratégica Espacio temporales Complejas Independiente de Convencional Adaptativo Tridimensionales Analógicos Pasivos Semánticos Seguras Móviles Accesibles Proactivos Dinámica Inalámbricas Online Activo visual Concurrente Arquitectónico Artificial Evolutivo Automatizados Heterogéneas Administrable Textuales Sintáctico Digital Electrónico Muldidimensional Variante Competitivos invariante Sensorial Distribuido Administrativo Geográfica Automática Comerciales No comerciales Virtuales De bajo nivel De alto nivel Interactivo Genérico Remoto Cooperativa Colaborativo Integral Táctil Espacial Multimedia Clásica No clásiva Convencional No convencional Industrial Múltiples Binario COMO PARTE “H” Servicio COSAS QUE NO DEBEN IR Análisis de fondo 2.26. LISTA DE ALGUNOS ARTEFACTOS DE ENTREGA EN PROYECTOS DE TECNOLOGÍAS DE LA INFORMACIÓN Acróni Definición mos con SOFT WARE ASDP Accelerated Software Development Proc ess Idio ma Categoría Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ASAM C Advanced Software AcquisitionManagement Cours e Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ASPG Advanced Software Products Group Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ASTA Advanced Software Technology and Agorithms Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ATASP I Advanced Technology Attachment Soft wareProgramming Interface Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ATSCDASE Advanced Television Systems Committee DTV Application Software Environment Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ASIP AFGWC Software Improvement Program Acró nimo en Tecnología de la Información, Ingeniería, Acrónimo Inglés ABSE Agent Based Software Engineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés AOSE Agent Oriented Software Engineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés AGSSS Airborne Graphics Software Support System Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ASB Airborne Software Bulletin Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés AGESA AMD Generic Encapsulated SoftwareArchitect ure Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ASUG American Software Users Group Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ASZP And Software Product Lines Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ASSD Andreas Stolz Software Development Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ASF Apache Software Foundation Acró nimo Tecnología de la Información, Ingeniería, en Acrónimo Inglés ASL Apache Software License Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ASIS Application Software Installation Server Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ATSE Application Timesharing SoftwareEngin eering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ASSET Asset Source for Software EngineeringTechnology Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ASTE Association for Software Testing andEvaluation Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés AISC Association of Independent Software Companies Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ADASS Astronomical Data Analysis Software and Systems Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés AJSS Atlanta Java Software Symposium Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ASDU Aurora Software Development Unit Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ACCES S Automated Catalog of Computer Equipment and Software System Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ASES Automated Software Evaluation System Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ASQ Automated Software Quality Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés AUSMS Automated Unbundled SoftwareManagement System Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés BSAM C Basic Software Acquisition ManagementCours e Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés BOSS Batch Operating Software System Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés BESD Becta Educational Software Database Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés BSD Berkeley Software Design Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés BSD Berkeley Software Distribution Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés BSDK BioLink Software Development Kit Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés BESQ Blekinge Engineering Software Qualities Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés BSWS Boeing Software Standard Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés BSDG Boise Software Developers Group Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés BBBO Bonn Archaeological Software Package Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés BASDA British Accounting Software Developers Association Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés BSQA Bulgarian Software Quality Association Acró nimo en Inglés BEST Business Equipment Software Technique Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés Organizaciones, Asociaci ones, Sociedad, Comunidad, Acrónimo BEST Business Equipment Software Techniques Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés BOS5 Business Operating Software /5 Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés BSA Business Software Alliance Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés BSA Business Software Association Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés BSLE Business Software License Exchange Acró Negocio, nimo Finanzas, Contabilidad, S en eguros, Acrónimo Inglés CSRB Campuswide Software License Grant Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CAAST Canadian Alliance Against Software Theft Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés CSARCSCI Canadian Synthetic Aperture RadarComputer Software Configuration Item Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés CSSE CDOS Software Support Environment Acró nimo en General, Abreviatura Co mún, Acrónimo Inglés CSE Center for Software Engineering Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés CQSA Certified Quality Software Analyst Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés CQSE Certified Quality Software Engineer Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSDP Certified Software Development Professional Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés CSPM Certified Software Project Manager Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés CSQA Certified Software Quality Analyst Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSQE Certified Software Quality Engineer Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSQP Certified Software Quality Professional Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés CSTE Certified Software Test Engineer Acró nimo Tecnología de la Información, Ingeniería, en Acrónimo Inglés CPSS Chemist's Personal Software Series Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés CSIR Chemistry Software and InformationResources Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés CSSL Clarke Software Solutions, Limited Acró Negocio, nimo Finanzas, Contabilidad, S en eguros, Acrónimo Inglés CSDK Client Software Development Kit Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés CHEST Combined Higher Education Software Team Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CASLA N Command Automated Software Local Area Network Acró Militar, Acrónimo nimo en Inglés CCSIL Command Control Software Interface Language Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés COSIE Commission on Software Issues in the Eighties Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés COSE Common Open Software Environment Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSH Complementary Software House Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CBSD Component-Based Software Development Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés COCAS A Comprehensive Clinic Assessment Soft wareApplication Acró Medicina, Acrónimo nimo en Inglés CASE Computer Aided Software Engineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CASRE Computer Aided Software ReliabilityEstimation Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CAST Computer Aided Software Testing Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CAST Computer Aided Software Translator Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CASDE Computer Assisted Software DevelopmentEnvironment Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CASE Computer Assisted Software Engineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSSA Computer Services & Software Association Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés COMPS Computer Software AC and ApplicationsConference Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés COMPS Computer Software O and Peripherals Show Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés CSC Computer Software Component Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSCI Computer Software Configuration Item Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSCM Computer Software ConfigurationManagement Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSDT COMPuter Software Data Tapes Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSDD Computer Software Design Description Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSDI Computer Software Distribution Item Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSWD Computer Software Documentation Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSWL Computer Software Listing Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSMN Computer Acró Tecnología de la SOFTWARE MAINTENANCENetwork nimo Información, Ingeniería, en Acrónimo Inglés COSMI C Computer Acró Tecnología de la Software Management andInformation C nimo Información, Ingeniería, enter en Acrónimo Inglés CSNL Computer Software Nottingham Limited Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSOM Computer Software Operator's Manual Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSPEI Computer Software Product End Item Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSRS Computer Software RequirementsSpecification Acró nimo en Tecnología de la Información, Ingeniería, Acrónimo Inglés CSS Computer Software Specialist Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés CSSA Computer Software Support Agency Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSU Computer Software Unit Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSUD Computer Software User Documentation Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CADSI Computer-Aided Design and SoftwareIncorporated Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés CASP Computerized Administrative Software Program Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSRP Computers and Software Review Panel Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CHEST Computers in Higher Education Software Team Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CDS Computing, Data and Software Services Acró nimo General, Abreviatura Co mún, Acrónimo en Inglés CMSSL Connection Machine Scientific Software Library Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés CSER Consortium for Software Engineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSQC Continuous Software Quality Control Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés CSS Conversational Software System Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés CSP Cooperative Software Partners Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés CSP Cooperative Software Program Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés COSQ Cost Of Software Quality Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés COSTA DE Cost Optimization Software for Transport Aircraft Design Evaluation Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés CSI Crew Software Interface Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés CSTA Crew Software Training Aid Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés CCHSS A Cyprus Computer Hardware and Software Suppliers Association Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DNBE Data Miner Software Kit Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DP&SS Data Processing and Software Subsystem Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés DPSS Data Processing Software System Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés DB2SD K DataBase 2 Software Development Toolkit Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DFSG Debian Free Software Guidelines Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DSTS Decision Software Trading System Acró Negocio, nimo Finanzas, Contabilidad, S en eguros, Acrónimo Inglés DSRS Defense Software Repository System Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DSL Definitive Software Library Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DLDX Der Kleine Software Laden Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DSUI Desktop Software User Interface Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DSA Destination Software Address Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DSSEP Developmental Software SupportEnvironment Plan Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DSDP Device Software Development Platform Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés DASDF DF-224 Analysis and SoftwareDevelopment Facility Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés DCSE Diba Consulting Software Engineers Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DCASS Digital Cartographic Software System Acró Geografía, Geología, nimo Acrónimo en Inglés DMSD K Digital Media Software Development Kit Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DSIN Digital Software INformation Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DSIS Digital Software Integration Station Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés DSLA Digital Software Licensing Architecture Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DISSPL A Display Integrated Software System and Plotting Language Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DTBB Distribute Software Updates Wizard Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DSEE Distributed Software EngineeringEnviro nment Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DSL Distributed Software Libraries Acró nimo en General, Abreviatura Co mún, Acrónimo Inglés DMAU SE DMA Utility Software Environment Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DSEE DOMAIN Software EngineeringEnvironment Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DSSA Domain Specific Software Architecture Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DFSL Driving Force Software Limited Acró Negocio, nimo Finanzas, Contabilidad, S en eguros, Acrónimo Inglés DSPSE DSP Software Engineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DASE DTV Application Software Environment Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés DYSIS Dynamic Software and Integrated Solutions,Incorporated Acró Negocio, nimo Finanzas, Contabilidad, S en eguros, Acrónimo Inglés ESGI Eagle Software Group, Incorporated Acró Negocio, nimo Finanzas, Contabilidad, S en eguros, Acrónimo Inglés ELSA Econometrics Laboratory Software Archive Acró nimo General, Abreviatura Co mún, Acrónimo en Inglés ESAP Educational Software Acquisition Progra Acró Educación, Escuela, Cole ms nimo gio, Universidad, en Acrónimo Inglés ESA Electronic Software Acquisition Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ESDS Electronic Software Deployment Service s Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ESD Electronic Software Distribution Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ESL Electronic Software Licensing Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ESD Electronics and Software engineeringDepartment Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés ESOFT A Embedded Software Association Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ESEL Empirical Software Engineering Laboratory Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ESTSC Energy Science Acró Tecnología de la and Technology Software Center nimo Información, Ingeniería, en Acrónimo Inglés ESRB Entertaining Software Rating Board Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ESYP Entertainment Software Rating Board Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés EASIE Environment for Application SoftwareIn tegration and Execution Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés EAST European Advanced Software Technology Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ESSI European Software and Systems Initiative Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ESEC European Software Engineering Conference Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ESSI European System and Software Initiative Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ESP Evaluation Software Program Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ECHAS L Every Computer Has A Software Lapse Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés EBSE Evidence Based Software Engineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ESG Exchange Software Generator Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ESEG Experimental Software Engineering Gro up Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés FASP Facility for Automated Software Production Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés FESDK Far East Software Development Kit Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés FDSD Feature Driven Software Development Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés FSEC Federal Software Exchange Center Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés FSEP Federal Software Exchange Program Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés FSMSC Federal Software Management Support Center Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés FAST Federation Against Software Theft Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés FEMAP Finite-Element Mold-Filling Analysis (Computer Software Program) Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés FSDD Flight Software Design Document Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés FSMF Flight Software Maintenance Facility Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés FSMP Flight Software Management Plan Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés FSRR Flight Software Readiness Review Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés FSSS Flight Software Support System Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés FSSR Flight Systems Software Requirements Acró nimo en General, Abreviatura Co mún, Acrónimo Inglés FSLM Fluent Software License Manager Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés FASE For Advancing Software Engineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés FSAG Free Software Association of Germany Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés FSEO Free Software Engineering Organization Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés FSFW Free Software For Windows Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés FSF Free Software Foundation Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés FSFE Free Software Foundation Europe Acró nimo en Inglés FSFI Free Software Funding Initiative Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés FSU Free Software Union Acró nimo Organizaciones, Asociaci ones, Sociedad, Comunidad, Acrónimo Tecnología de la Información, Ingeniería, en Acrónimo Inglés FSA Functional Software Architecture Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés FSSR Functional Subsystem SoftwareRequirements Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés GSDK Game Software Development Kit Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés GSDS Genealogy Software Distribution Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés GSDS Genealogy Software Distribution System Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés GAST Generic Automated Software Testsystem Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés GSI Generic Software Interface Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés GIUSA Government Industry University Softwar Acró Educación, Escuela, Cole e Alliance nimo gio, Universidad, en Acrónimo Inglés GSS Graphic Software System Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés GPSI Graphics Processor Software Interface Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés GSL Graphics Software Laboratories Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés GSDL Ground Software Development Laboratory Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés GUISE Group for Unidata Interface SoftwareExploration Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés HRSPI N Hampton Roads Software ProcessImprovement Network Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés HSTP Hardware and Software Turnover Plan Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés HSTSP Hardware and Software Turnover Support Plan Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés HOSED Hardware Or Software Error Detected Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés HSIF Hardware Software Integration Facility Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés HASQ Hardware-Assisted Software Queue Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés HSMU Harrier Software Maintenance Unit Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés HSDI Herrin Software Development, Incorporated Acró Negocio, nimo Finanzas, Contabilidad, S en eguros, Acrónimo Inglés HQSO High Quality Software Outsourcing Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés HSGT Hitachi Software Global Technology Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés HOSC Holland Open Software Conference Acró nimo en Inglés HRSS Host Resident Software System Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés HCSE Human Centered Software Engineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés Organizaciones, Asociaci ones, Sociedad, Comunidad, Acrónimo IP-SEN IEE Proceedings, Software Engineering Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés IMEX Image Format Conversion Software System Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ISET Independent Software Evaluation Test Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ISNSA Independent Software Nuclear Safety Analysis Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ISV Independent Software Vendor Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ISA Industrial Software Architecture Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ISDD Informatics Software Download Database Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés I&SI Information and Software Integration Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ISIC Information and Software IntegrationContractor Acró nimo en Tecnología de la Información, Ingeniería, Acrónimo Inglés ISSUE Information System Software UpdateEnvironment Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ISC Initial Software Configuration Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ISE Institute for Software Engineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés IFSQ Institute For Software Quality Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ISYN Instrumental Software Technologies,Inc orporated Acró Negocio, nimo Finanzas, Contabilidad, S en eguros, Acrónimo Inglés ICASE Integrated Computer Aided SoftwareEnvironment Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés I-CASE Integrated Computer-aided SoftwareEngineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ISDV Integrated Software Development andVe rification Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ISDS Integrated Software Development Syste m Acró nimo General, Abreviatura Co mún, Acrónimo en Inglés ISE Integrated Software Engineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ISEE Integrated Software Engineering Environ Acró Tecnología de la ment nimo Información, Ingeniería, en Acrónimo Inglés ISFUG Integrated Software Federal User Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ISFUG Integrated Software Federal User Group Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ISFD Integrated Software Functional Design Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ISPW Integrated Software Processing Workfra me Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ISSCO Integrated Software Systems Corporation Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés IWSSF Integrated Weapon System Software Facility Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés IH/SR Integration Hardware and Software Acró General, Abreviatura Co Review nimo mún, Acrónimo en Inglés IDSA Interactive Digital Software Association Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés IRSSP Interactive Remote Sensing Software Package Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ISDA Interactive Software Developers Associa tion Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ICSC Interconnect Software Consortium Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ISP Interferometer Software Package Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ISPE Interim Software Progress Emulation Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ISAMC Intermediate Software AcquisitionMana gement Course Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ICSE International Conference on SoftwareEngineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés IMSEX PO International Manufacturing SoftwareEx position and Conference Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés ISAGU G International Software AG Users Group Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ISCN International Software Consulting Netwo Acró Tecnología de la rk nimo Información, Ingeniería, en Acrónimo Inglés ISM International Software Marketing Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ISPW International Software Process Working Group Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ISQI International Software Quality Institute Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ISSI International Software Systems Incorporated Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ISSRE International Symposium on SoftwareReliability Engineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés IBSE Internet Based Software Enterprise Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés ISC Internet Software Consortium Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ISVL Internet Software Visualization Laboratory Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés JSIA Japan Software Industry Association Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés JSCP Java Software CoProcessor Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés JMSW Joint Mission Software Subsystem Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés JSSEE Joint Service Software EngineeringEnvironment Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés JSRB Joint Software Review Board Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés JTOSS Joint Task-Organized Software Subsystem Acró Militar, Acrónimo nimo en Inglés JFSF Jordan Free Software Frontier Acró nimo en General, Abreviatura Co mún, Acrónimo Inglés JESQ Just Enough Software Quality Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés KSCW Kempe Software Capital Enterprises Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés KIT Kernel Software for Intelligent Terminals Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés KMSE Kings Mountain Software Engineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés KBSA Knowledge Based Software Assistant Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés LSEC Land Software Engineering Centre Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés LSAP Laserfiche Software Assurance Plan Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés LSQE Lead Software Quality Engineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés LSSL Legal Software Solutions Limited Acró nimo General, Abreviatura Co mún, Acrónimo en Inglés LSP Library Software Package Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés LCSE Life Cycle Software Engineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés LCSS Life Cycle Software Support Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés LCSSE Life Cycle Software Support Environment Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés LISSA Life Insurance Software Systems of America Acró Negocio, nimo Finanzas, Contabilidad, S en eguros, Acrónimo Inglés LCSEC Life-cycle Software Engineering Center Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés LSEK Linux Software Evaluation Kit Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés LSM Linux Software Map Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés LSMY Livermore Acró Tecnología de la Software LaboratoriesInternational nimo Información, Ingeniería, en Acrónimo Inglés LSTC Livermore Software Technology Corp Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés LOHSS Local Hardware and Software Systems Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés LISA Locally Integrated Software Architecture Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés LLCSC Lower-level Computer Software Component Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés LFSF Lueck Free Software Foundation Acró nimo en Inglés MBSC M B SOFTWARE CORP Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés MSPI M&T Software Partner International Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés MRJSD K Macintosh Runtime for Java Software Developer Kit Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés Organizaciones, Asociaci ones, Sociedad, Comunidad, Acrónimo MINST REL Management Information Software Tool - Research in Libraries Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés MSAC Management of Software Acquisition Course Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés MUSS Manchester University Software System Acró Educación, Escuela, Cole nimo gio, Universidad, en Acrónimo Inglés MSAI Martin Software Associates, Incorporated Acró Negocio, nimo Finanzas, Contabilidad, S en eguros, Acrónimo Inglés MSE Master of Software Engineering Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés MUSE MC&G Utility Software Environment Acró Militar, Acrónimo nimo en Inglés MUSA C Measurement Uncertainty Software inAnalytical Chemistry Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés MSR Medical Software Reviews Acró Medicina, Acrónimo nimo en Inglés MCSE Microsoft Certified Software Engineer Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés MSL Microsoft Software Library Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés MILSTD2167A Military Standard: Defense System SoftwareDevelopment Acró Militar, Acrónimo nimo en Inglés MSS MIMOLA Software System Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés MBSE Model Based Software Engineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés MASC OT Modular Approach to SoftwareConstruction, Operation and Test Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés MICRO SOFT Most Idiots Can't Realize: Obsolete Software Organization Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés MSSG MPEG Software Simulation Group Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés MBSD Multi Business Software Design Acró Negocio, nimo Finanzas, Contabilidad, S en eguros, Acrónimo Inglés NASF National Applied Software EngineeringCenter Acró nimo en General, Abreviatura Co mún, Acrónimo Inglés NCSA National Construction Software Associat ion Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés NESC National Energy Software Center Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés NESC National Energy Software Corporation Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés NFSP National Federation of Software Pirates Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés NHSE National Hpcc Software Exchange Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés NISS National Information on Software and Services Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés NSDIR National Software Data and InformationRepository Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés NSQE National Software Quality Experiment Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés NSRL National Software Reference Library Acró nimo General, Abreviatura Co mún, Acrónimo en Inglés NSRD National Software Reuse Directory Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés NSTL National Software Testing Lab Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés NSTL National Software Testing Laboratories Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés NSW National Software Works Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés NTSL National Testing Software Laboratories Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés NWSS Navy WWMCCS® SoftwareStandardization Acró Militar, Acrónimo nimo en Inglés NSE Network Software Environment Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés NSL Network Software Laboratory Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés NESSI Networked European Software and Acró Ciencia, Unidad de ServicesInitiative nimo Medida, Química, Biolog en ía, Acrónimo Inglés NZSA New Zealand Software Association Acró nimo en Inglés NSPP Nihon Software Outsourcing Vision Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés NASD NMCS Applications Software Descriptio Acró Tecnología de la n nimo Información, Ingeniería, en Acrónimo Inglés NLSA Northern Lights Software Associates Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés OOSD OBJECT ORIENTED SOFTWAREDEVELOPMENT Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés OOSE Object Oriented Software Engineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés OOST Object Oriented Software Technology Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés OOSM Of Object-Oriented Software Measures Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés Organizaciones, Asociaci ones, Sociedad, Comunidad, Acrónimo OSDIT Office of Software Development andInformation Technology Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés OIT Office Software Development andInformation Technology Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés OLSS On-line Software System Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés OESS Ontario Educational Software Service Acró Educación, Escuela, Cole nimo gio, Universidad, en Acrónimo Inglés OTLI Open Pedigree Software Group Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés OSD Open Software Description Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés OSD Open Software Distribution Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés OSE Open Software Environment Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés OSF Open Software Foundation Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés OSF1 Open Software Foundation /1 Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés OSF/D CE Open Software Foundation/Distributed Computing Environment Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés OSSIM Open Source Software Image Map Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés OASCB Orbiter Avionics Software Control Board Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés OSSP Organization's Standard Software Process Acró nimo en Inglés OGSE Orion Group Software Engineers Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés OSQA Ottawa Software Quality Association Acró nimo en Inglés PNSQ Pacific Northwest Software Quality Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés PTSP Paper Tape Software Package Acró nimo en Organizaciones, Asociaci ones, Sociedad, Comunidad, Acrónimo Organizaciones, Asociaci ones, Sociedad, Comunidad, Acrónimo General, Abreviatura Co mún, Acrónimo Inglés PISE Pasteur Institute Software Environment!! Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés PENSD K Pen Computing Software Development Kit Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés PASS Performance Analysis Software System Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés PCSIG Personal Computer Software Interest Group Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés PSM Personal Software Marketing Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés PSP Personal Software Product Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés POSC Petroleum Open Software Corporation Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés POSC Petrotechnical Open Software Corporation Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés POSE Picture-Oriented Software Engineering Acró nimo Tecnología de la Información, Ingeniería, en Acrónimo Inglés POSSE E Plant Organizational Software System for Emissions From Equipment Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés PSDK Platform Software Development Kit Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés PASS POCC Applications Software Support Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés PASSO PS POCC Applications Software SupportOperations Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés PRISM Portable Reuseable Integrated Software Nodules Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés PDSS Post Deployment Software Support Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés PDSSC Post Deployment Software Support Center Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés PDSS Post Development and Software Support Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés PPSS Post Production Software Support Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés PSQT Practical Software Quality Techniques Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés PDSS Predeployment Software Support Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés PGSD Pretty Good Software Design Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés PASS Primary Avionics Software System Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés PRIME NET Prime Network Software Package Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés PNC PRIMENET (Prime Network Software Package) Node Controller Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés PSS Professional Software Services Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés PSSL Professional Software Solutions Limited Acró Negocio, nimo Finanzas, Contabilidad, S en eguros, Acrónimo Inglés PASS Program Aid Software System Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés PASS Program Aid Software Systems Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés PSESW G Programming Support Environment Soft ware Working Group Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés PSDN Progress Software Developers Network Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés PSCI Progressive Software Computing,Incorp orated Acró Negocio, nimo Finanzas, Contabilidad, S en eguros, Acrónimo Inglés PSDI Project Software Development,Incorporated Acró Negocio, nimo Finanzas, Contabilidad, S en eguros, Acrónimo Inglés PSS Proprietary Software System Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés PDSL Public Domain Software Library Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés PSL Public Software Library Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés PSA Python Software Activity Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés QSSL QNX Software Systems, Limited Acró Negocio, nimo Finanzas, Contabilidad, S en eguros, Acrónimo Inglés QASS Quality Assurance Software Systems Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés QMSW Quality Mission Software Workshops Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés QOSA Quality Of Software Architectures Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés QSSI Quality Software Systems, Incorporated Acró Negocio, nimo Finanzas, Contabilidad, S en eguros, Acrónimo Inglés QTSC Quang Trung Software City Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés QSPM Quantitative Software Process Management Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés QMVL Quintessential Mailing SoftwareIncorporated Acró nimo en Tecnología de la Información, Ingeniería, Acrónimo Inglés RSAC Recreational Software Advisory Council Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés RSACI Recreational Software Advisory Council on Internet Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés RITSEC Regional Information Technology and Software Engineering Center Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés RSU Remote Software Update Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés ROSQ Return On Software Quality Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés RAASP Reusable Ada Avionics Software Package Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés RSA Reusable Software Assets Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés RSRG Reusable Software Research Group Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés RETSA M Review, Editing and Tagging Software for Automated Mapping Acró nimo Tecnología de la Información, Ingeniería, en Acrónimo Inglés RGSS Robert Gannon Software Services Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés RSI Rockwell Software Incorporated Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés SBST Santa Barbara Software Products Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés SESA Scientific/Engineering Software Applications Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés SSCD SDV Software Concept Document Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés SOSE Service Oriented Software Engineering Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés SSFF Showcase Software Factory of the Future Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés SSDM Sibilo Software Development Model Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés SITEST Siemens ISDN Protocol Software Test Acró Tecnología de la Tools SIPO6022 nimo Información, Ingeniería, en Acrónimo Inglés SIDES Siemens ISDN Software Development andEvaluation S ystem Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés SSD Spacecraft Software Division Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés SIGSOF Special Interest Group on T SoftwareEngineering Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés SSIG Statistical Software Interest Group Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés SUNSI TE Sun Software Information & TechnologyExc hange Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés SSB Support Software Bulletin Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés SSC Support Software Change Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés SSA System Software Associates Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés SSL System Software Loader Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés SSRN System Software Reference Number Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés SSIP Systems Software Interface Processing Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés SSSA Systems Software Support Activity Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés TCSS Technical Control Software Support Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés TSR Technical Software Review Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés TSPA Technology and Software Publicly Available Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés TSP Test Software Program Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés TISSS Tester Independent Software Support System Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés TOSC The Other Software Company Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés TPSG The Profits Software Group Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés TSFI The Software Force, Incorporated Acró Negocio, nimo Finanzas, Contabilidad, S en eguros, Acrónimo Inglés TSWN The Software Without Name Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés TLCSC Top-level Computer Software Component Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés TSDK TORNADO Software Development Kit Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés TJSD Trainee Java Software Developers Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés TTSA Trainer Tactical Software Activity Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés TISS Travel Information Software Systems Acró nimo en Tecnología de la Información, Ingeniería, Acrónimo Inglés TPSW Triangle Powers SoftWare Welcome Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés TSS2 TurboSurvey Software 2 Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés TOSD Twin Oaks Software Development Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés USA United Software Association Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés USAISS United States SC Army Information Systems Software Support Command Acró Militar, Acrónimo nimo en Inglés USCSS University of Southern California Software Systems Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés USO Unix Software Operation Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés USI Update Software Identity Acró General, Abreviatura Co nimo mún, Acrónimo en Inglés UIST User Interface Software and Technology Acró nimo Ciencia, Unidad de Medida, Química, Biolog en ía, Acrónimo Inglés USSA User Supported Software Association Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés UGST User's Group on Software Tools Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés VISTA Validation Intelligent Software for ThermalApplications Acró Ciencia, Unidad de nimo Medida, Química, Biolog en ía, Acrónimo Inglés VEST VAX Environment Software Translator Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés VISA Virtual Instruments Software Architectur Acró Tecnología de la e nimo Información, Ingeniería, en Acrónimo Inglés VSP Virtual Software Processor Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés VSC VocalTec Software Compression Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés WCMS Web Content Management Software / System Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés WISE Web Integrated Software Metrics Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés WSDK Websphere Software Development Kit Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés WSLSC Worldwide Software Lifecycle Support Contract Acró Tecnología de la nimo Información, Ingeniería, en Acrónimo Inglés Estudio de antecedentes Análisis comparativo Análisis crítico Conclusiones 2.27. COSAS SOBRE COMO COMENZAR CON LOS REQUERIMIENTOS SOBRE EL DISEÑO DE REQUERIMIENTOS Se debe especificar Qué funciones serán realizadas Con qué datos Para producir qué resultados En qué situación Para quien No debe especificar Módulos en que divide el software Funciones a los módulos Flujo de información entre módulos Controles entre módulos Estructuras de datos Necesidad de especificar condiciones de diseño en la ERS para casos especiales, con el fin de imponer restricciones de diseño por Seguridad Confiabilidad Necesidad de funciones en módulos separados Restricciones de comunicaciones entre áreas del programa Garantía de integridad en variables críticas Disponibilidad física Disponibilidad de programas/aplicativos/utilitarios Cumplimiento de estándares La ERS debe estar dirigida al producto del software, no al proceso de producir el software Algunos requisitos del proyecto, acordados entre el cliente y el proveedor, se incluyen en la ERS Costos Tiempos de entrega Procedimientos para reportes Métodos para el desarrollo de Software Aseguramiento de Calidad Criterios para validación y verificación Procedimientos para aceptación PARTES DE UNA ESPECIFICACIÓN DE REQUERIMIENTOS Tabla de Contenido 1. Introducción 1.1 Propósito 1.2 Alcance 1.3 Definiciones, siglas, y abreviaciones 1.4 Referencias 1.5 Descripción global de la ERS 2. Descripción global del producto 2.1 Perspectiva del producto 2.2 Funciones del producto 2.3 Características de usuario 2.4 Restricciones 2.5 Condiciones y dependencias 2.6. Repartir proporcionalmente los requisitos 3. Requisitos específicos Apéndices Índice 1.1. Propósito 1.1.1. Delinear el propósito de la ERS 1.1.2. Especificar a qué público va dirigida la ERS 1.2. Alcance 1.1.1. Identificar el(los) producto(s) de software a construir 1.1.2. Explicar qué hace y qué no hace el(los) producto(s) de software 1.1.3. Describir el software especificando beneficios, objetivos y metas 1.1.4. Ser consistente con otras especificaciones de niveles superiores 1.3. REFERENCIAS 1.1.1. Proporcionar lista completa de todas las referencias de los documentos de la ERS 1.1.2. Identificar cada documento por el título, número de reporte, fecha y publicación de la organización 1.1.3. Especificar la fuente de las referencias DESCRIPCION GLOBAL DE LA ERS Describir el contenido de la ERS Explicar la organización de la ERS PERSPECTIVAS DEL PRODUCTO Interfaces del sistema Interfaces del usuario Interfaces con el hardware Interfaces con el software Interfaces de comunicaciones Restricciones de memoria Funcionamiento del sistema (normal y especial) Requisitos del Sitio RESTRICCIONES Políticas reguladoras Limitaciones del Hardware Interfaces con otras aplicaciones Operaciones en paralelo Funciones de Auditoría Funciones de Control Requerimientos de lenguaje(s) de alto nivel Protocolos Requerimientos de fiabilidad Criticidad de la aplicación Consideraciones de seguridad y confiabilidad REQUISITOS ESPECÍFICOS Deben declararse los requisitos específicos de conformidad con todas las características descritas en la sección de “características del usuario” Los requisitos específicos deben tener referencias cruzadas a los documentos más actuales que los relacionen Todos los requisitos deben ser singularmente identificables Debe prestarse atención para organizar los requisitos de manera que se aumente al máximo la legibilidad 2.28. ALGUNOS EJEMPLOS DE REQUERIMIENTOS REQUERIMIENTOS DE FUNCIONALIDAD El sistema debe calcular el máximo común divisor. El sistema debe registrar la información personal de los usuarios. El sistema debe permitir que los usuarios registrados hagan sus pagos El sistema debe almacenar información sobre libros que son más solicitados por los usuarios y su precio en pesos. El sistema debe permitir a los administradores buscar y consultar la información de los deudores de la biblioteca REQUERIMIENTOS DE PLATAFORMA El sistema debe funcionar en ANDROID 4.3. El sistema se debe visualizar desde los navegadores: Internet Explorer, Firebird, Mozilla y Nautilus REQUERIMIENTOS PERFORMANCE La velocidad con la que se ejecutan las operaciones de multiplicación y división depende de la RAM del dispositivo móvil REQUERIMIENTOS DE ESCALABILIDAD El sistema estará diseñado para calcular hasta cinco numeros distintos REQUERIMIENTOS DE DISTRIBUCIÓN E INSTALACIÓN El sistema no estará público en PlayStore, para que cualquiera lo pueda descargar a instalar, sino que debe ser solicitado a su autor para posterior envío por correo electrónico. Sin embargo cualquier usuario con la aplicación podría redistribuirla. El sistema debe ser instalable enviando un archivo .apk al correo eletrónico. REQUERIMIENTOS DE ALMACENAMIENTO El sistema en sus versiones iniciales no contempla el almacenamiento de datos calculados, ni de información de los usuarios Requerimientos del Producto Ejemplo La interfaz debe ser implementada en HTML puro (Sin applets, Javascript, o frames). Requerimientos que especifican que el producto deba comportarse de una determinada manera. Requerimientos de eficiencia Requerimientos de fiabilidad Requerimientos de portabilidad Requerimientos de usabilidad Requerimientos de espacio Requerimientos de mantenibilidad Requerimientos de flexibilidad Requerimientos de reusabilidad Requerimientos de compatibilidad Requerimientos de integración Requerimientos Organizacionales Ejemplo El proceso de desarrollo debe estar conforme con el SGC de la corporación. Requerimientos que surgen de políticas y procedimientos de la organización (Creadora o Usuaria). Requerimientos de entrega Requerimientos de implementación Requerimientos de estándares Requerimientos Externos Ejemplo La información médica de un paciente, no debe estar al alcance del público general. Requerimientos surgidos por factores externos al proyecto de desarrollo como tal. Requerimientos de interoperabilidad Requerimientos éticos Requerimientos legislativos Requerimientos de privacidad Requerimientos de seguridad Requerimientos de proceso Requerimientos de tiempo de desarrollo Requerimientos de disponibilidad de recursos Requerimientos de estándares de desarrollo Requerimientos de rendimiento del sistema: Fiabilidad, tiempo de respuesta, disponibilidad… Requerimientos de interfaces: Dispositivos de E/S, usabilidad, interoperabilidad… Requerimientos de proceso de desarrollo: Estándares, herramientas, plazo de entrega Requerimientos de interoperabilidad Se requiere que el sistema académico SIUL interactúe con el sistema de pagos para permitir al estudiante el pago de la matrícula siempre y cuando éste halla inscrito asignaturas en el mismo. Requerimientos de seguridad El sistema no debe permitir el ingreso a estudiantes que no tengan correo institucional. El sistema no debe permitir al estudiante modificar las notas. Requerimientos de maturability (madurez) Se requiere que el sistema tenga una disponibilidad web de 670 horas mensuales (2 Horas que se permite que falle) Requerimientos de recoverability (Capacidad de recuperación) Capacidad de un sistema para restablecer su normal funcionamiento El sistema debe permitir reinstalar los datos a partir de una memoria USB y por cada 100 MB debe permitir su restauración en un tiempo menor a una hora. El sistema debe permitir la creación de puntos de restauración. El sistema debe permitir crear backups temporalizados. En segundo plano. Requerimientos de Fault Tolerance (Tolerancia a fallas) Le coloco situaciones difíciles y las supera. El sistema debe notificar a los estudiantes sus notas, aún cuando el operador de SMS esté fuera de línea. Requerimientos de learnability (Capacidad de auto explorar y comprender el funcionamiento del sistema) En forma individual lo comprende y lo puede estudiar 2.29. ALGUNAS ACTIVIDADES QUE PUEDEN SER NECESARIAS PARA LA REALIZACIÓN DE UN PROYECTO PLANIFICACIÓN DE UN PROYECTO Planificar la gestión del alcance Recopilar los requisitos Definir el alcance Crear EDT (WBS) Planificar para gestionar el cronograma Definir y secuenciar las actividades Estimar los recursos y la duración de las actividades Desarrollar el cronograma Planificar la gestión de costos Estimar los costos Determinar el presupuesto Planificar para gestionar la calidad Desarrollar el plan de recursos humanos Planificar las comunicaciones Planificar la gestión del riesgo Identificar riesgos Realizar análisis cualitativo y cuantitativo de riesgos Planificar la respuesta a los riesgos Planificar las adquisiciones Planificar la gestión de los interesados Definir y establecer estándares a seguir por el grupo. Definir una estructura organizacional y hacer un diagrama organizacional. Capacitar al grupo en las metodologías y estándares a utilizar. Crear un modelo de ciclo de vida para el proyecto. Definir un plan y protocolo para desarrollo de reuniones. Definir una agenda de reuniones con cada rol. Construir un plan de trabajo específico que contenga diagramas Gantt y de flujo de actividades. Definir protocolos para asignar y evaluar actividades. Nótese que durante el proyecto, será necesario redefinir tareas, y con ello, miembros del equipo deberán alterar su carga de trabajo para realizarlas. PROCESOS PARA PONERNOS DE ACUERDO CON LAS PARTES INTERESADAS Identificar y priorizar los intereses de las partes interesadas. Analizar sus intereses y necesidades. Comunicar a las partes interesadas cuáles de sus requerimientos se cumplen o no en el proyecto. Desarrollar una estrategia para hacer frente a la gestión de las partes interesadas. Incluir los intereses y las expectativas de las partes interesadas en cuanto a los requisitos, objetivos, ámbito de aplicación, los resultados, calendario y costes de planificación del proyecto. Ordenar, en función del riesgo, las amenazas y oportunidades que las distintas partes interesadas representan para el proyecto. Identificar el proceso de decisión a seguir entre el equipo de proyecto y las partes interesadas. Asegurar la satisfacción de las partes interesadas en cada fase del proyecto. Llevar a cabo el plan de gestión de las partes interesadas. Ejecutar, comunicar y gestionar los cambios relacionados con la planificación de las partes interesadas. Documentar la experiencia adquirida para su aplicación a futuros proyectos. GESTION DE LA INTEGRACIÓN Desarrollo del plan del proyecto Ejecución del plan del proyecto Control de cambios integrado GESTION DEL ALCANCE Iniciación Planificación del alcance Definición del alcance Verificación del alcance Control de cambios del alcance GESTIÓN DEL TIEMPO Definición de actividades Secuenciación de actividades Estimación de la duración Desarrollo de la programación Control de la programación GESTIÓN DEL COSTE Planificación de recursos Estimación del coste Presupuestación del coste Control del coste GESTIÓN DE LA CALIDAD Planificación de la calidad Aseguramiento de la calidad Control de la calidad GESTION DE RECURSOS HUMANOS Planificación organizativa Adquisición de personal Desarrollo del equipo GESTIÓN DE COMUNICACIONES Planificación de comunicaciones Distribución de la información Informe de la ejecución Cierre administrativo GESTIÓN DE RIESGO Planificación de la gest. riesgo Identificación del riesgo Análisis cualitativo del riesgo Análisis cuantitativo del riesgo Planificación respuesta al riesgo Control y monitoriz. del riesgo GESTIÓN DE LAS ADQUISICIONES Planificación de la adquisición Planificación de la solicitud Solicitud Selección de fuentes Administración del contrato Cierre del contrato PROCESO DE ORGANIZACIÓN Identificar y agrupar las funciones, actividades y tareas del proyecto. Seleccionar estructuras organizacionales Crear posiciones organizacionales Definir responsabilidades y autoridades Establecer el perfil de cada puesto Documentar las decisiones organizacionales PROCESO DE ADQUISICIÓN DE PERSONAL Llenar los puestos de la organización. Asimilar al personal recientemente asignado Educar o entrenar al personal Proveer de desarrollo general Evaluar y valorar al personal Compensar PROCESO DE ELEBORACIÓN DE DOCUMENTOS Fijar los objetivos y metas Desarrollar estrategias Desarrollar políticas Anticipar futuras situaciones Conducir un establecimiento de riesgos Determinar posibles cursos de acción Tomar decisiones de planificación Fijar procedimientos y reglas Desarrollar los planes del proyecto Preparar presupuestos Documentar los planes del proyecto. PROCESO DE LIDERAZGO proveer liderazgo supervisar personal delegar autoridad motivar personal construir equipos coordinar actividades facilitar comunicaciones resolver conflictos manejar cambios documentar las decisiones de dirección. PROCESO DE DESARROLLO DE SOFTWARE O DE TENOLÓGIAS FASE DE NEGOCIOS Y MODELAMIENTO Modelo de Dominio Establecimiento de viabilidad del sistema Establecimiento de factibilidad Técnica del sistema Establecimiento de factibilidad Operativa del Sistema Establecimiento de factibilidad Legal del Sistema Modelo de procesos Depuración del Modelo De Dominio Depuración del modelo de procesos Diagnóstico de viabilidad del sistema PROCESO DE DESARROLLO DE SOFTWARE O DE TENOLÓGIAS FASE DE REQUERIMIENTOS Definición de actores Lista preliminar de casos de uso Documentación de las excepciones de los casos de uso Documentación de descripción de casos de uso Depuración de los casos de uso Modelo de casos de Uso Depuración de actividades de los actores Depuración de requerimientos funcionales Depuración de requerimientos no funcionales Documentación de casos de uso Depuración de la lista de casos de uso Depuración del diagrama final de casos de uso Depuración de casos de uso extendido PROCESO DE DESARROLLO DE SOFTWARE O DE TENOLÓGIAS FASE DE ANALISIS Y DISEÑO Lista preliminar de clases Elaboración del Diagrama de secuencia Elaboración del Diagrama de colaboración. Elaboración del diagrama de estados. Elaboración de diagrama de actividad. Diagrama de actividades Elaboración de diagramas de clase final Elaboración de diagramas de actividad finales Elaboración de diagramas de secuencia finales. Elaboración de diagramas de colaboración finales Elaboración de diagramas de estado finales Depuración del modelo de análisis y colocación de etiquetas OCL PROCESO DE DESARROLLO DE SOFTWARE O DE TENOLÓGIAS FASE DE IMPLEMENTACION Definición de las características de la herramienta Elaboración del diagrama de componentes inicial. Creación de clases de prueba Pruebas basadas en objetos. Elaboración de diagrama de componentes final Creación de módulos de interfaz de usuario. Creación de módulos de lógica del negocio. Creación de módulos de acceso a datos PROCESO DE DESARROLLO DE SOFTWARE O DE TENOLÓGIAS FASE DE TEST PRUEBAS Pruebas basadas en escenarios Pruebas basadas en escenarios Pruebas unitarias de clase Pruebas de acoplamiento Pruebas de cohesión Pruebas de concurrencia PROCESO DE DESARROLLO DE SOFTWARE O DE TENOLÓGIAS FASE DE DESPLIEGUE Elaboración del diagrama de despliegue inicial Elaboración de diagrama de despliegue final Empaquetamiento de componentes de lógica de aplicación Empaquetamiento de componentes de acceso a datos Empaquetamiento de componentes de interfaz grafica Distribución de paquetes en los distintos nodos PROCESO DE DESARROLLO DE SOFTWARE O DE TENOLÓGIAS FASE DE CONFIGURACION Y MANTENIMIENTO Creación de casos de uso de prueba Establecimiento de un modelo de pruebas Montaje de un servidor de pruebas Montaje de un servidor de control de escenarios Montaje de un servidor de control de versiones de software Pruebas del servidor CVS Montaje de un servidor de subversiones Montaje de un servidor de pruebas PROCESOS DE EJECUCIÓN Ejecución del plan del proyecto Aseguramiento de la calidad Desarrollo del equipo Distribución de la información Solicitud Selección de fuentes Administración del contrato PROCESOS DE MERCADEO Fijación de precios Explotación de las listas de email Uso de los canales sociales, Factbook & Twister. Anuncios de Display o Rich Media contratados en medios Online, como DiarioLibre.com, ListinDiario Online, Cnn, etc. Promociones y ofertas por mensajería móvil. PROCESOS DE CONTROL Control de cambios integrado Verificación del alcance Control de cambios del alcance Control de la programación Control del coste Control de la calidad Informe de la ejecución Control y monitorización de riesgos Desarrollar estándares de desempeño Establecer sistemas de monitoreo y reportes Medir y analizar resultados Iniciar acciones correctivas Recompensar y disciplinar Documentar los métodos de control. PROCESOS DE CIERRE Cierre del contrato Cierre administrativo 2.30. ALGUNAS PERSONAS QUE PUEDES NECESITAR PARA TU PROYECTO DE SOFTWARE Es bueno que bosqueje en forma general el personal que se requiere para estos procesos, por ejemplo a continuación se menciona una potencial lista que le sería de gran utilidad. El administrador de proyecto • Analistas: Trabajar con los analistas para estudiar las necesidades de los clientes y los requisitos del sistema. • Diseñadores: Trabajar con ellos para diseñar la arquitectura del sistema de acuerdo con los recursos asignados al proyecto. El administrador de proyecto requiere la arquitectura del sistema para determinar el plan de trabajo de los demás roles. Es el responsable de las actividades referentes al diseño gráfico de la aplicación, guardando los lineamientos institucionales que tenga lugar dentro del proyecto y aplicando sus conocimientos en concordancia con las especificaciones del cliente. • Tésters: Trabajar con ellos para determinar que tipo de testeo deberá utilizarse, y con que profundidad, de acuerdo con los requisitos de seguridad en el diseño del sistema y de los recursos disponibles. Los resultados de los tests ayudan a determinar el éxito del proyecto, preocupación principal de la administración de proyecto. • Aseguradores de calidad: La información provista por este rol ayuda a conocer el avance del proyecto. Este rol observa si cada una de las actividades se realiza de acuerdo a las especificaciones planificadas. • Ingenieros de manutención: Generalmente la manutención utiliza una cantidad muy importante de recursos del proyecto. Por ello, el administrador debe conocer los planes de manutención, y de ser necesario, ajustarlos a los recursos disponibles. • Documentadores: El administrador de proyecto tomará como referencia los documentos controlados por los documentadores para elaborar planes y la evaluación del proyecto. • Clientes: El administrador de proyecto deberá administrar la relación con los clientes, desarrollando una comunicación fluida con éstos, y siendo la cara visible del proyecto. • Asistente Personal es alguien que asiste en la realización de las tareas diarias personales o dentro de una organización • Director Comercial es el máximo responsable del departamento comercial. En dependencia directa del Director General de la compañía el Director Comercial es responsable del cumplimiento de los objetivos de ventas de la misma • El director financiero o CFO (del inglés chief financial officer) de una compañía es el ejecutivo a cargo del gestión financiera de la organización. Es responsable de la planificación, ejecución e información financieras. Generalmente reporta directamente al director ejecutivo de la empresa. • Chief risk officer (CRO), Chief risk management officer (CRMO) o Director de riesgos (en su acepción al español) es un cargo de reciente data destinado a aquel ejecutivo responsable de gestionar la eficiencia y efectividad de los riesgos significativos de una corporación, así como también las oportunidades que entrega el mercado tanto para la organización en general, como para uno o varios segmentos específicos que se están atacando; si bien es cierto es un puesto que aún no es predominante al interior de las organizaciones, cada vez se va haciendo más común su presencia, en especial, para el caso de empresas de gran envergadura. Los riesgos a los que se alude son comúnmente categorizados como estratégicos, operativos, financieros o relacionados al cumplimiento de las metas propuestas. • El Director de Seguridad es la figura del máximo responsable de la seguridad de una Empresa u Organismo, tanto público como privado, en la que esté constituido un Departamento de Seguridad. • El director de tecnología (del inglés chief technical officer o chief technology officer, abreviado como CTO) es una posición ejecutiva dentro de una organización en el que la persona que ostenta el título se concentra en asuntos tecnológicos y científicos. A menudo, el CTO es líder de un grupo técnico en una compañía, particularmente construyendo productos o creando servicios que dan cuerpo a tecnologías específicas de la industria. En algunos casos el CTO además maneja el trabajo de investigación y desarrollo en las organizaciones • Los términos director ejecutivo, director gerente, ejecutivo delegado, jefe ejecutivo, presidente ejecutivo, principal oficial ejecutivo, consejero delegado y primer ejecutivo suelen usarse indistintamente para hacer referencia a la persona encargada de máxima autoridad de la llamada gestión y dirección administrativa en una organización o institución • Director general persona investida de máxima autoridad en la gestión y dirección administrativa en una empresa, organización o institución • Administrador de bases de datos - debes manejar Oracle, Sybase o SQL Server. • Ingeniero Desarrollador - debes conocer Java/J2EE, Visual Basic/.NET o algún lenguaje como C++ o COBOL. • Ingeniero Webmaster - debes conocer paquetería como Dreamweaver, HTML, CSS, Javascript y nociones de diseño gráfico. Conforme adquieres experiencia puedes optar por cualquiera de los "nichos" que se dan con regularidad en esta industria: • Desarrollo/Consultoría - sobre todo aplicados en el sector privado y aunque puede ser muy demandante (jornadas de 10-12 horas) en general los puestos son mejor pagados. Este rol es responsable de desarrollar las funcionalidades del sistema, incluyendo su diseño para ajustarlo en la arquitectura, implementando, probando, integrando y documento componentes que hagan parte de la solución. • Ingeniero de Operaciones/Soporte - se dan especialmente en empresas grandes o en gobierno, implican "horario fijo" y tiempos relajados la mayor parte del tiempo pero es muy fácil estancarse en este tipo de puestos y en caso de "bomberazos" la presión puede volverse insoportable. • Líder de Proyecto es el responsable por garantizar el éxito del proyecto. Otros títulos usados son los de Coordinador o Gerente de Proyecto, o Líder de Equipo, pero si su empresa lo ha nombrado Líder del proyecto, lo más probable es que espera de usted que lleve a feliz término el proyecto asignado. • Administrador de bases de datos (DBA) es el profesional de tecnologías de la información y la comunicación, responsable de los aspectos técnicos, tecnológicos, científicos, inteligencia de negocios y legales de bases de datos. • Los analistas y especialistas en redes se concentran en el diseño y seguridad de la misma, particularmente en la resolución de problemas relacionados con proporcionar servicios de soporte, asegurarse de que la red se utiliza eficientemente y que los objetivos de calidad de servicio se alcancen • Diseñador gráfico es el profesional cuya actividad es la acción de concebir, programar, proyectar y realizar comunicaciones visuales, producidas en general por medios industriales y destinadas a transmitir mensajes específicos a grupos sociales determinados, con un propósito claro y específico. • El Broker de Negocios actúa como intermediario entre Compradores y Vendedores de negocios. Es responsable de conjuntar a dichas partes y su objetivo es vender negocios. La mejor manera de ubicar la función de un Broker de Negocios es compararlo a su pariente más cercano… el Corredor de Bienes Raíces. El trabajo de un Corredor de Bienes Raíces es el ubicar Vendedores de casas y cazarlos con Compradores potenciales. En el evento de que se logre la venta se ganan una comisión • Analista funcional Este rol lidera toda la parte de análisis de requerimientos capturados por el cliente. Convierte la informalidad de las necesidades del cliente a especificaciones y requerimientos formales desde el punto de vista de ingeniería de software. El Analista Funcional es el vínculo de unión entre el usuario y el área informática de la entidad. Su misión consiste en elaborar el análisis de las funcionalidades para el proyecto, así como actualizar y mejorar las conceptualizaciones; es decir, debe trabajar de manera conjunta con el desarrollo funcional de las aplicaciones informáticas, asegurando su correcta explotación y su óptimo rendimiento. • El Coordinador de Proyecto aplica conocimientos en administración de proyectos, habilidades, herramientas y técnicas a un amplio rango de actividades, con el fin de encontrar requerimientos y entregar un resultado final para un proyecto en particular. • Arquitecto de software. Este rol es responsable de definir la arquitectura de software, que incluye tomar las decisiones técnicas claves que restringen el diseño general y la implementación del proyecto. Coordinará el grupo de desarrolladores. • Profesional temático. Este rol es el encargado de apoyar, en el área de su especialidad, el desarrollo del sistema en aquellas actividades en donde el ciclo de vida y las características del proyecto lo requieran • Analista de aseguramiento de calidad. Es el responsable de las actividades principales para el desarrollo de pruebas a la aplicación. Incluye la identificación, definición e implementación de las pruebas funcionales y no funcionales necesarias, así como el registro de los resultados y el análisis de los mismos. • Interesados. Este rol representa los grupos o las personas cuyas necesidades deben ser satisfechas por el proyecto. Pueden ser: clientes, usuarios, patrocinadores, grupo de trabajo. • Ingeniero control de producción. Vigilar que los procesos productivos se hagan cumpliento las normas de seguridad industrial y velar para que cualquier anomalía en la definición de los mismos sea corregida a tiempo. • Existen otros roles en la parte industrial como o Supervisor de entrenamiento o Planeador de producción o Ingeniero de manufactura o Ingeniero de mantenimiento • Existen otros roles en la parte de analista como o Analista de procesos de negocio. o Diseñador del negocio. o o Analista de sistema. Especificador de requisitos. • Existen otros roles en la parte de desarrolladores como: o o o o o o o Arquitecto de software. Diseñador Diseñador de interfaz de usuario Diseñador de cápsulas. Diseñador de base de datos. Implementador. Integrador. • Existen otros roles en la parte de Gestores como: o o o o o o o o Jefe de proyecto Jefe de control de cambios. Jefe de configuración. Jefe de pruebas Jefe de despliegue Ingeniero de procesos Revisor de gestión del proyecto Gestor de pruebas. • Existen otros roles en la parte de Apoyo como: o o o o o Documentador técnico Administrador de sistema Especialista en herramientas Desarrollador de cursos Artista gráfico • Existen otros roles en la parte de Especialista en pruebas como: o o o o o o o o o Especialista en Pruebas (tester) Analista de pruebas Diseñador de pruebas Otros roles: Stakeholders. Revisor Coordinación de revisiones Revisor técnico Cualquier rol 2.31. ALGUNOS MOTORES PARA TU PROYECTO DE SOFTWARE MOTORES DE BASES DE DATOS OPEN SOURCE CSQL Derby Java DB Firebird Gladius DB H2 HSQLDB Ingres LucidDB Mckoi SQL Database MonetDB MySQL Ocelot SQL OpenLink Virtuoso (Open Source Edition) PostgreSQL Quadcap QED Rebol sql-protocol SmallSQL SAPDB SQLite txtSQL MOTORES DE BASES DE DATOS PROPIETARIOS Adabas D Advantage Local Server IBM DB2 Express-C FrontBase MaxDB Microsoft SQL Server Express Oracle Database 10g Express Edition Sav Zigzag ScimoreDB Sybase ASE Express Edition Tdbengine 2.32. ALGUNOS SOFTWARE QUE TE AYUDAN A REALIZAR LAS PRUEBAS DE TU SOFTWARE HERRAMIENTAS DE GESTIÓN DE PRUEBAS OPEN SOURCE Bugzilla Testopia (http://www.mozilla.org/projects/testopia/) FitNesse (http://fitnesse.org/) qaManager (http://sourceforge.net/projects/qamanager) qaBook (http://www.qabook.com/) RTH (open source) (https://sourceforge.net/projects/rth/) Salome-tmf (https://wiki.objectweb.org/salome-tmf/) Squash TM (http://www.squashtest.org/index.php?option=com_content&view=article&id=111&Ite mid=175&lang=en) Test Environment Toolkit (http://tetworks.opengroup.org/Products/tet.htm) TestLink (http://www.teamst.org/) Testitool (http://majordojo.com/testitool/) XQual Studio (http://www.xqual.com/) Radi-testdir (http://sourceforge.net/projects/radi-testdir/) Data Generator (http://www.generatedata.com/) HERRAMIENTAS PARA PRUEBAS FUNCIONALES OPEN SOURCE Selenium (http://docs.seleniumhq.org/download/) Soapui (http://www.soapui.org/) Watir (Pruebas de aplicaciones web en Ruby) (http://wtr.rubyforge.org/) WatiN (Pruebas de aplicaciones web en .Net) (http://watin.sourceforge.net/) Capedit (http://www.packetsquare.com/) Canoo WebTest (http://webtest.canoo.com/webtest/) Solex (http://solex.sourceforge.net/) Imprimatur (http://imprimatur.wikispaces.com/) SAMIE (http://samie.sourceforge.net/) ITP (http://www.incanica.com/itp.html) WET (http://wet.qantom.org/) WebInject (http://www.webinject.org/) HERRAMIENTAS PARA PRUEBAS DE CARGA Y RENDIMIENTO OPEN SOURCE FunkLoad (http://funkload.nuxeo.org/) FWPTT load testing (http://fwptt.sourceforge.net/) loadUI (http://www.loadui.org/) jmeter (http://jmeter.apache.org/) HERRAMIENTAS DE GESTIÓN DE PRUEBAS COMERCIALES HP Quality Center/ALM (http://www8.hp.com/us/en/software/enterprise-software.html) QA Complete (http://www.testmanagement.com/qacomplete.html) qaBook (http://www.qabook.com/) T-Plan Professional (http://www.t-plan.com/product_trials.html) SMARTS (http://www.testworks.com/) QAS.Test Case Studio (http://www.objentis.com/index.php?id=productsmain&L=2) PractiTest (http://www.practitest.com/product/) SpiraTest (http://www.inflectra.com/SpiraTest/Default.aspx) TestLog (http://www.testlog.com/download.htm) ApTest Manager (http://www.aptest.com/tools.html) Zephyr (http://www.getzephyr.com/) HERRAMIENTAS PARA PRUEBAS FUNCIONALES COMERCIALES QuickTest Pro (http://www8.hp.com/us/en/software/enterprise-software.html) Rational Robot (http://www-01.ibm.com/software/rational/) Sahi (http://sahi.co.in/sahi-pro/) SoapTest (http://www.parasoft.com/jsp/products.jsp?itemId=13) Test Complete (http://smartbear.com/products/qa-tools/automated-testing-tools) QA Wizard (http://www.seapine.com/qawizard.html) Squish (http://www.froglogic.com/) vTest (http://www.verisium.com/products/vTest/index.html) Internet Macros (http://www.iopus.com/imacros/) HERRAMIENTAS PARA PRUEBAS DE CARGA Y RENDIMIENTO HP LoadRunner (http://www8.hp.com/us/en/softwaresolutions/software.html?compURI=1175451#.UXI1xKLTx2c) LoadStorm (http://loadstorm.com/) NeoLoad (http://www.neotys.com/) WebLOAD Professional (http://www.radview.com/product/product.aspx) Forecast (http://www.facilita.co.uk/products/) ANTS – Advanced .NET Testing System (http://www.red-gate.com/products/dotnetdevelopment/) Webserver Stress Tool (http://www.paessler.com/webstress) Load Impact (http://loadimpact.com/) HERRAMIENTAS TODO EN UNO Test Studio – Una herramienta para pruebas de rendimiento, carga, pruebas automáticas, gestión de pruebas y test exploratorio (http://www.telerik.com/automated-testing-tools) HERRAMIENTAS PARA PRUEBAS SOBRE TELÉFONOS MÓVILES Testdroid-Herramienta para pruebas automatizadas para Android. (http://testdroid.com/) HERRAMIENTAS PARA PRUEBAS DE SEGURIDAD Wireshark (http://www.wireshark.org/) Kali Linux (http://www.kali.org/) Nmap (http://nmap.org/) 2.33. ALGUNOS FRAMEWORKS PARA EL DESARROLLO DE TU PROYECTO DE SOFTWARE Web Application Frameworks Ruby on Rails Framework MVC basado en Ruby, orientado al desarrollo de aplicaciones web (http://www.linuxlinks.com/article/20120525000539219/RubyonRails.html ) CodeIgnite r Poderoso framework PHP liviano y rápido (http://www.linuxlinks.com/article/20120525000531497/CodeIgniter.html) Kohana Un fork de CodeIgniter, Gracias a Samuel por mencionarlo en los comentarios. (http://kohanaframework.org/) Django Framework Python que promueve el desarrollo rápido y el diseño limpio (http://www.linuxlinks.com/article/20120525000545879/Django.html) CakePHP Framework MVC para PHP de desarrollo rápido (http://www.linuxlinks.com/article/20120525000252509/CakePHP.html) Zend Framewor k Framework para PHP 5, simple, claro y open-source (http://www.linuxlinks.com/article/20120525000536311/ZendFramework. html) Yii Framework PHP de alto rendimiento basado en components (http://www.linuxlinks.com/article/2012052500054269/Yii.html) Pylons Framework web para Python que enfatiza la flexibilidad y el desarrollo rápido (http://www.linuxlinks.com/article/2012052500055227/Pylons.html) Catalyst Framework para aplicaciones web MVC elegante (http://www.linuxlinks.com/article/20120525000602635/Catalyst.html) Symfony Framework full-stack (http://www.linuxlinks.com/article/20120525000534344/Symfony.html) TurboGear s Próxima generación construido sobre Pylons (http://www.linuxlinks.com/article/20120525000548217/TurboGears.html) 2.34. ALGUNAS METODOLOGÍAS DE DESARROLLO DE SOFTWARE 1970 Programación estructurada sol desde 1969 Programación estructurada Jackson desde 1975 1980 Structured Systems Analysis and Design Methodology (SSADM) desde 1980 Structured Analysis and Design Technique (SADT) desde 1980 Ingeniería de la información (IE/IEM) desde 1981 1990 Rapid application development (RAD) desde 1991. Programación orientada a objetos (OOP) a lo largo de la década de los 90's Virtual finite state machine (VFSM) desde 1990s Dynamic Systems Development Method desarrollado en UK desde 1995. Scrum (desarrollo), en la última parte de los 90's Rational Unified Process (RUP) desde 1999. Extreme Programming(XP) desde 1999 Nuevo milenio Enterprise Unified Process (EUP) extensiones RUP desde 2002 Constructionist design methodology (CDM) desde 2004 por Kristinn R. Thórisson Agile Unified Process (AUP) desde 2005 por Scott Ambler Desarrollo manejado por rasgos FDD Microsoft Solution Framework MSF 2.35. ALGUNAS DEFINICIONES ÚTILES PARA TU GLOSARIOS DE TÉRMINOS Término Aceptación Acceptance Acreditado Accredited Definición Acuerdo formal de que un Servicio de TI, un Proceso, un Plan, o cualquier otro Servicio prestado está completo, es preciso, Confiable y que cumple con los Requisitos specificados. La Aceptación suele verse precedida por una Evaluación o Prueba y a menudo es necesaria antes de pasar a la siguiente etapa de un Proyecto o de un Proceso. Autorizado oficialmente a asumir determinado Rol. Por ejemplo, un cuerpo acreditado puede estar autorizado a proveer cursos de capacitación o a realizar Auditorías. Actividad Activity Un conjunto de acciones concebidas para alcanzar un resultado particular. Las actividades se definen normalmente como parte de un Proceso o de Planes, y se documentan en los Procedimientos. Activo Asset (Estrategia del Servicios) Cualquier Recurso o Capacidad. Los activos de un Proveedor de Servicios incluyen cualquier cosa que pueda contribuir con la prestación de un Servicio. Los activos pueden ser de los siguientes tipos: Gestión, Organización, Proceso, Conocimiento, Personal, Información, Aplicaciones, Infraestructura y Capital financiero. Activo de Servicio Service Asset Cualquier Capacidad o Recurso de un Proveedor de servicio. Consulte Activo. Activos de Servicio y Gestión de la Configuración (SACM) Service Asset and Configuration Management (SACM) (Transición del Servicio) El Proceso responsable por la Gestión de la Configuración y la Gestión de Activos. Acuerdo Agreement Un Documento que describe un pacto formal entre dos o más partes. El acuerdo no vincula desde el punto de vista legal, a menos que forme parte de un Contrato. Consulte Acuerdo de Nivel de Servicio, Acuerdo de Nivel Operacional. 3. LA COHESIÓN Y EL ACOPLAMIENTO CLASES Y OBJETOS ENTRE La cohesión y el acoplamiento son dos cosas importantes cuando se habla de orientación a objetos y se debe tener cuidado en no confundir estos términos. El doctor Jim Keogh en su libro J2EE Manual de Referencia (Pag 66) habla como la cohesión y el acoplamiento son dos factores que determinan si las clases son mantenibles. Es bueno tener en cuenta que el concepto de cohesión y acoplamiento no nace de la orientación a objetos, sino que son conceptos que existieron en la programación funcional que son válidos y aplicables a la programación orientada a objetos, razón por la cual es muy probable que se muestren definiciones y conceptos que involucren la programación funcional, pero se vera en el presente texto con una orientación a objetos estos términos. Uno de los principios que usa el buen diseño de sistemas orientados a objetos es “bajo acoplamiento y alta cohesión” Para comprender al anterior principio se hace necesario que se comprendan estos dos términos cosa que nos proponemos en esta sección. 3.1. GENERALIDADES SOBRE LA COHESIÓN El doctor Roger S. Presssman en su libro “Ingeniería del Software un enfoque práctico. Sexta Edición” (en la pagina 260) habla de lo que significa alta cohesión, y para ellos dice que se presenta alta cohesión cuando “una clase de diseño cohesiva tiene un conjunto de responsabilidades pequeño y enfocado y aplica atributos y métodos de manera sencilla para implementar dichas responsabilidades”. Esto quiere decir en pocas palabras “una clase no debe abarcar muchas cosas porque el que mucho abarca poco aprieta”, y aunque suena feo la aplicación y utilización de dichos populares en el caso de la cohesión el anterior refrán popular encaja bien en la definición de lo que es cohesión. Analizando detenidamente la anterior definición vemos que si una clase abarca muchas cosas en su quehacer, es porque de una manera u otra invoca muchas responsabilidades de otras clases. En pocas palabras si un docente se enfoca en dictar una sola asignatura, teóricamente debería hacerlo mejor que un docente que dicta simultáneamente siete asignaturas que no tienen casi relación entre sí. A nivel de orientación a objetos una clase que haga muchas cosas tiene que valerse muy posiblemente de otras clases para ejecutar sus responsabilidades. Por ejemplo una clase que calcula los totales de ventas, posiblemente interactúe con las clases ventas, que le arrojaran o devolverán el valor de cada una de las ventas en forma detallada, pero una clase que a parte de calcular los saldos de las ventas, también calcule los valores del inventario actual, tiene que interactuar además con otras clases de inventario para que estas le devuelvan el valor unitario de cada inventario para que ésta con estos valores totalice. En el ejemplo anterior se vio que una clase que tenga bastantes responsabilidades tiende a tener muchas relaciones con otras clases. De otra parte si se incrementa la funcionalidad de una clase sin ampliar el número de clases con el que se relacione, es posible que las relaciones existentes con las clases actuales tengan que estrecharse y establecerse mayor comunicación entre las clases. Por ejemplo si una clase antes solo calculaba los valores totales de los inventarios tenía que solicitar a cada objeto de inventario que le devolviera su valor unitario para después ella totalizarlo, en cambio si ahora a parte de esta responsabilidad se le delega la responsabilidad de calcular los totales de los inventarios por tipo de inventario, tiene que solicitar a cada uno de los objetos inventariados no solamente su valor, sino también su tipo para poder hacer el cálculo de inventario total y por tipo. Esto un últimas palabras está mostrando que existen dos tendencias en las clases a las que se les aumentan sus responsabilidades, por un lado tienden a interactuar con mas clases y por otro lado tienden a tener mayores relaciones con las clases con las que ya interactuaba. Obviamente también se pueden presentar ambas tendencias en una clase, puesto que una tendencia no excluye a la otra. Veamos ahora los efectos que tendría cada una de estas tendencias. Examináramos en primera medida la tendencia que tendría el hecho de tener relación con mayor número de clases y para esto supondremos el siguiente caso: Sea X una clase que tiene relación con objetos de tipo clase A, B, y C. Si incrementamos la funcionalidad de la clase X de tal manera que ahora tenga relaciones con objetos de las clases A, B, C, D, E y F, tendremos que la clase X con su funcionalidad no ampliada no tendría problemas de ejecución cuando los objetos de tipo D, E y F tengan problemas en la implantación de sus funcionalidades, pero si la clase X tiene funcionalidad ampliada de tal manera que le obliga esta funcionalidad a tener relaciones con las clases A, B, C, D, E y F, se presentarían problemas en la ejecución de algunas funcionalidades de X cuando se invoquen las funcionalidades de las clases D, E y F que presentan problemas. En otras palabras estamos diciendo que a mayor número de relaciones con otros objetos de otras clases mayor probabilidad de error de ejecución cuando alguna de las clases con las que se relaciona tenga funcionalidades con errores que sean invocadas por la clase inicial. Algunos autores definen la cohesión como una relación funcional intramodular, es decir definen la cohesión como la forma en que se agrupan unidades de software en una mayor unidad. A primera medida esta definición parece no ser igual a la definición dada inicialmente en la que se decía “una clase de diseño cohesiva tiene un conjunto de responsabilidades pequeño y enfocado y aplica atributos y métodos de manera sencilla para implementar dichas responsabilidades”, pero examinando con detenimiento vemos que las relaciones funcionales intramodulares indican que tantas responsabilidades tiene un objeto de una clase y el establecimiento de estas responsabilidades sirve para analizar el enfoque funcional que tienen los métodos de una clase en cuanto a su naturaleza. Es bueno ahora decir que entre mas funcionalidades dispersas tenga una clase es porque la clase no tiene coherencia con su objetivo general de dicha clase y a este grado de coherencia se le denomina cohesión. A mayor coherencia mayor cohesión, es decir entre más se enfoque una clase en unas cosas puntuales que le den una funcionalidad específica y concreta a la clase mayor cohesión y entre más dispersas estén sus funcionalidades respecto a la naturaleza de dicha clase menos cohesionada está la clase. Podemos entonces inferir que a mayor número de responsabilidades y funcionalidades de una clase menor cohesión y a menor número de responsabilidades mayor cohesión. Según el docente Luis Felipe Wanumen “La cohesión es el grado en el que las pequeñas responsabilidades tienen relación unas con otras relaciones coherentes”, y según esto se puede aplicar el concepto de cohesión a una clase en donde las pequeñas responsabilidades son cada uno de los métodos y se puede ver la cohesión a nivel de clase como el grado en que los métodos de una clase están relacionados entre sí. También se puede ver la cohesión a nivel de componente en el que cada uno de las clases tiene una responsabilidad que tiene coherencia con la responsabilidad del componente y si existe una clase que tiene asignadas responsabiliades poco relacionadas con las responsabilidades de otra clase, muy posiblemente esta clase debe estar en otro componente. Con todo lo dicho hasta el momento vemos que se busca la mayor cohesión en el desarrollo de aplicaciones software. En sitios de Internet como http://phedetech.wordpress.com/2006/04/24/cohesion-yacoplamiento/ se habla de siete tipos de cohesión 1. Cohesión Casual (la peor) 2. Cohesión Lógica (sigue a la peor) 3. Cohesión Temporal (de moderada a pobre) 4. Cohesión de Procedimiento (moderada) 5. Cohesión de Comunicación (moderada a buena) 6. Cohesión Secuencial 7. Cohesión Funcional (la mejor) 3.2. COHESIÓN CASUAL La cohesión casual se presenta cuando existe poca o nula relación entre los elementos de un módulo, obviamente a nivel de orientación a objetos la cohesión casual se presenta cuando existe poca o nula relación entre los métodos de una clase. ¿Qué significa poseer una relación nula?. Significa que un método de una clase no tiene relación con otro método de la misma clase y si no tienen relación alguna es porque muy posiblemente son dos métodos que deberían pertenecer a distinta clase. Como conclusión este tipo de cohesión es lo peor, porque hacen que se pierda la naturaleza de una clase. Una clase hace lo que hacen sus métodos y si sus métodos son inconexos, la naturaleza de la clase es ambigua porque su responsabilidad no ha se ha sabido asignar. Se podría pensar que si la cohesión es casual es porque el valor para la métrica de cohesión es baja y está muy cerca del 0%, también podemos decir que si la cohesión no es nada casual la métrica de cohesión es alta y está lejos del 0%. También podemos analizar la cohesión en un componente examinando la funcionalidad de cada uno de los elementos de dicho componente. Si existiera un elemento “i” de dicho componente que tuviera funcionalidad nada relacionada con la funcionalidad de los otros elementos, podríamos pensar que se tendrían cohesiones casuales entre el elemento “i” y el resto de elementos. 3.3. COHESIÓN LÓGICA Para explicar la cohesión lógica imaginémonos una clase que tiene los siguientes métodos: PROFESOR:Luis String nombre; void dictarAjedrez() void dictarMatematicas() void dictarMusica() void dictarInformatica() void dictarMantenimientoCarros() void dictarOrigamia() void dictarPsicologia() Podríamos pensar que los métodos están bien agrupados en forma lógica, debido a que todos son métodos de dictar algo, lo que sucede es que las cosas que se dictan en algunos casos no tienen relación unas con otras, por ejemplo dictar mantenimiento de carros no tiene nada que ver con dictar origamia, con lo cual podríamos pensar que las relaciones entre los métodos son nulas y por tanto tan solo tendríamos una simple cohesión pero a nivel lógico. 3.4. COHESIÓN TEMPORAL Para explicar la cohesión temporal imaginémonos las siguientes clases: INICIO CIERRE cargarControladores() cargarDrivers() cargarVentanas() cargarFuentes() bajarControladores() bajarDrivers() bajarVentanas() bajarFuentes() Estas dos clases hacen cosas que solamente estan relacionadas con el tiempo en el que se ejecutan los métodos. Por ejemplo los controladores se cargan al igual que los drivers, las ventanas y las fuentes cuando comienza la aplicación, pero esto no quiere decir que estén relacionados entre sí. Es más, estaría diciendo que en la ejecución del sistema cuando se arranca el sistema se pone en acción a la clase “INICIO”, con lo cual al momento del arranque del sistema se tendría en tiempo de ejecución una sola clase activa, es decir en ejecución, cosa que no debería pasar con un buen diseño de una aplicación. De otra parte es importante notar que la clase “CIERRE” realiza acciones que se ejecutan cuando se cierra el sistema, pero esto no quiere decir que estén relacionadas entre si. Para complementar la idea expuesta podríamos decir que algo lógico seria crear una clave ventana que gestione los eventos de la ventana sin importar el tiempo en el que se ejecute, tal como lo muestra la siguiente figura: VENTANA cargarVentana() maximizarVentana() cerrarVentana() minimizarVentana() opacarVentana() desactivarVentana() La anterior clase si tiene relacionados sus métodos no de acuerdo al tiempo de ejecución de los mismos sino de acuerdo a la funcionalidad propia de la clase “VENTANA” que es como se debería hacer. Cuando se organizan las funcionalidades de los métodos de las clases de acuerdo con el tiempo en el que ocurren se está haciendo una agrupación pobre de dichos métodos, pero por tener en común el tiempo de ejecución se dice que se dichos métodos tienen una cohesión temporal. 3.5. COHESIÓN DE PROCEDIMIENTO La cohesión de procedimiento se parece a la cohesión temporal, excepto que en la cohesión procedimental se tiene una secuencia de ejecución de los pasos. Recordemos que en la cohesión temporal se ejecutan los métodos de la clase medianamente en el mismo instante, pero no se sabe en que secuencia, es decir, siguiendo el ejercicio de la sección anterior, no se sabe si primero se cargan los drivers o primero se carga la ventana, pero lo único cierto es que estas acciones se ejecutan al momento de iniciar el sistema. La ejecución de métodos con cohesión de procedimiento quiere decir que la funcionalidad de estos métodos se ha establecido sobre la base de sus relaciones algorítmicas o procedimentales. Para explicar la cohesión de procedimiento supongamos la siguiente clase: UNIVERSIDAD ingresoEstudiante() matricularEstudiante() inscribirMateriasEstudiante() dictarClaseEstudiante() evaluarEstudiante() graduarEstudiante() En donde se ve que la clase “UNIVERSIDAD” permite el ingreso de estudiantes, la matricula de los mismos, la inscripción de materias y otra serie de procesos sobre un estudiante. Si se hace un examen de dichos métodos se puede verificar que el orden en el que aparecen es el orden procedimental en el que se realizan en la práctica dichos procesos en la “UNIVERSIDAD”. Establecer esta secuencialidad es bueno, pero si por establecer esta secuencialidad no se establece una verdadera asignación de responsabilidades a las clases de tal forma que las clases hagan cosas puntuales o tengan funcionalidades puntuales, estamos implementando un sistema con cohesión procedimental que muy posiblemente hace que algunas clases tengan más funcionalidad de la que deben tener. En nuestro ejercicio podemos pensar que las funcionalidades de dictar clase y de evaluar al estudiante son funcionalidades que deben ser delegadas a otra clase como por ejemplo la clase “PROFESOR”. Generalmente las cohesiones de procedimiento son el fruto de hacer análisis pensando en diagramas de flujo y para probar esto, a continuación mostramos el diagrama de flujo de los procesos de la “UNIVERSIDAD” con respecto a la atención a sus estudiantes. INICIO ingresoEstudiante() NO ¿ingresó? SI matricularEstudiante() NO ¿matriculado? SI inscribirMateriasEstudiante() NO ¿inscribió materias? SI dictarClaseEstudiante() NO ¿se dicto clase? SI evaluarEstudiante() NO ¿evaluación satisfactoria? SI graduarEstudiante() FIN 3.6. COHESIÓN DE COMUNICACIÓN Los métodos que tienen cohesión de comunicación operan sobre el mismo conjunto de datos de entrada o de salida. TABLA ESTUDIANTE Cod Nombre Apellido 1 Hugo Silva 2 Paco Silva 3 Luis Silva 3 Sofia Vergara 4 Natalia Paris CLASE ESTUDIANTE mostrarNombre(int cod) mostrarApellido(int cod) mostrarDatosCompletos(int cod) imprimirDatos(int cod) En el anterior gráfico estamos mostrando en la parte izquierda los datos de una tabla “ESTUDIANTE” de una base de datos. Al lado derecho se tiene una clase llamada “ESTUDIANTE” que tiene los métodos para mostrar el nombre, el apellido y los nombres completos de un estudiante, así como para imprimir todos los datos. Podemos ver en este caso que los métodos actúan sobre la misma tabla, o sea que comparten el mismo conjunto de datos de entrada. Se podría pensar que los métodos “mostrarNombre(int cod)”, “mostrarApellido(int cod)”, “mostrarDatosCompletos(int cod)” e “imprimirDatos(int cod)” dado que tienen en común el mismo conjunto de datos de entrada deberían hacer parte de la misma clase. Aplicar el anterior raciocinio logra en la mayoría de los casos que los métodos de la clase tengan un grado aceptable de cohesión. También es importante que la cohesión del ejemplo que estamos mostrando en realidad es cohesión de comunicación por datos de entrada. En forma similar a la mostrada en este ejercicio podemos tener métodos con cohesión de comunicación por parte de los datos de salida que procesan. 3.7. COHESIÓN SECUENCIAL Dos métodos “A” y “B” tienen cohesión secuencial cuando los datos de salida del método “A” sirven como datos de entrada del método “B” o viceversa cuando los datos de salida del método “B” sirven como datos de entrada del método “A”. Obviamente no es posible tener cohesión de comunicación entre métodos en ambos sentidos, es decir que los datos de salida del método “A” sirvan como datos de entrada del método “B” y que al mismo tiempo los datos de salida del método “B” sirvan como datos de entrada del método “A”, puesto que ello llevaría a redundancias cíclicas. 3.8. COHESIÓN FUNCIONAL En una clase los métodos tienen cohesión funcional cuando cada una de ellas es parte integral para la realización de las funcionalidades asociadas a una clase. También se puede dar cohesión funcional a nivel de componentes y en este sentido se puede decir que el componentes tiene cohesión funcional cuando cada uno de sus elementos constitutivos tienen una funcionalidad que es parte integral de la funcionalidad del mencionado componente. 3.9. ACOPLAMIENTO El acoplamiento clásicamente se definía como la interdependencia entre módulos. Pero este concepto al igual que el concepto de cohesión es absolutamente aplicable a la orientación a objetos, obviamente haciéndole algunos ajustes, pero en esencia se sigue aplicando. A nivel de orientación a objetos el acoplamiento mide el grado de dependencia entre dos clases. Según Jim Keogh en su libro de J2EE Manual de Referencia a nivel de orientación a objetos existen dos formas en las que se puede presentar el acoplamiento, es decir dos formas en las que se puede afirmar que una clase “A” depende de otra “B”. La primera forma es cuando se usa herencia. Supongamos una clase “A”, sirve como clase base para una clase “B”, con lo cual la clase heredada “B” depende de la existencia de la clase “A” La segunda forma es cuando una clase “A” delega responsabilidades a otra clase “B”. En este caso la clase delegada “B” depende de la clase que le delegó la responsabilidad, es decir de la clase “A” en nuestro ejemplo. 3.10. TALLER PROPUESTO Busque en bibliografía reconocida definiciones de cohesión y acoplamiento. Busque artículos reconocidos sobre cohesión y acoplamiento. Haga un ejercicio a nivel de diagrama de clases y con su correspondiente codificación en lenguaje Java en el que implemente cohesión casual. Para el ejercicio elaborado sobre cohesión casual elabore el ejercicio que solucione la falta de cohesión y para ello explique el diagrama de clases de la solución óptima, explique en una hoja porque es solución óptima e implemente la respectiva solución en lenguaje Java. Haga un ejercicio a nivel de diagrama de clases y con su correspondiente codificación en lenguaje Java en el que implemente cohesión lógica. Para el ejercicio elaborado sobre cohesión lógica elabore el ejercicio que solucione la falta de cohesión y para ello explique el diagrama de clases de la solución óptima, explique en una hoja porque es solución óptima e implemente la respectiva solución en lenguaje Java. Haga un ejercicio a nivel de diagrama de clases y con su correspondiente codificación en lenguaje Java en el que implemente cohesión temporal. Para el ejercicio elaborado sobre cohesión temporal elabore el ejercicio que solucione la falta de cohesión y para ello explique el diagrama de clases de la solución óptima, explique en una hoja porque es solución óptima e implemente la respectiva solución en lenguaje Java. Haga un ejercicio a nivel de diagrama de clases y con su correspondiente codificación en lenguaje Java en el que implemente cohesión de procedimiento. Para el ejercicio elaborado sobre cohesión de procedimiento elabore el ejercicio que solucione la falta de cohesión y para ello explique el diagrama de clases de la solución óptima, explique en una hoja porque es solución óptima e implemente la respectiva solución en lenguaje Java. Investigar patrones de software que hagan uso del concepto de cohesión. Investigar patrones de software que hagan uso del concepto de acoplamiento. Investigar otros tipos de cohesión que no hallan sido establecidos en el documento. Investigar tipos de acoplamiento. 4. GENERALIDADES DE UML UML es un lenguaje que tiene elementos, relaciones y diagramas, tal como se especifica en la siguiente tabla Elementos VISION GENERAL DE UML Elementos estructurales Elementos de comportamiento Elementos de agrupación Elementos de anotación Relaciones Diagramas Diagrama de casos de uso Diagrama de clases Diagrama de objetos Diagrama de secuencia Diagrama de colaboración Diagrama de estado Diagrama de actividad Diagrama de componentes Diagrama de despliegue 4.1. DIAGRAMAS DE CASOS DE USO Son los encargados de documentar los requisitos de sistema a nivel general. En un diagrama de casos de uso solamente pueden aparecer los elementos mostrados en la siguiente tabla: ELEMENTO Actor NOTACION UML DEL ELEMENTO Actor Caso de Uso Caso de Uso Relaciones de generalización y especificación Caso de Uso NewUseCase Asociaciones unidireccionales Caso de Uso Actor Notas Los actores por lo general son seres autonomos que interactuan con el sistema y tienen estrecha relacion con los usuarios finales del mismo. Los casos de uso son las acciones que va a realizar un actor por medio del sistema. Las relaciones de generalización se presenten unicamente entre casos de uso. Las asociaciones unidireccionales se presentan entre los actores y los casos de uso. Las notas son elementos UML para colocar las aclaraciones a cosas que no se comprendan en el diagrama. 4.2. DIAGRAMAS DE ACTIVIDADES Son equivalentes a los diagramas de flujo de las metodologías estructuradas y se usan para analizar procesos. 4.3. DIAGRAMAS DE CLASES Muestran la vista estática del sistema, con sus clases y las relaciones entre las mismas. En un diagrama de clases solamente pueden aparecer los elementos mostrados en la siguiente tabla: ELEMENTO Clase con solo nombre NOTACION UML DEL ELEMENTO Clase Clase con definición completa Relaciones de realizacion Relaciones de generalización Relaciones de dependencia o instanciacion Relaciones de asociación Relaciones de asociacion Clases tipo interfaz <<Interface>> Clase 4.4. DIAGRAMAS DE INTERACCION En UML existen dos tipos de diagramas de interacción que son: Diagramas de secuencia y Diagramas de colaboración. También se denominan diagramas isomorfos debido a que a partir de un diagrama se puede obtener el otro, es decir que a partir del diagrama de secuencia se puede obtener el diagrama de colaboración y viceversa, a partir del diagrama de colaboración se puede obtener el diagrama de secuencia. 4.5. DIAGRAMAS DE ESTADO Muestra el estado cambiante de un solo objeto 4.6. DIAGRAMAS DE COMPONENTES Muestra una vista estática de los componentes que están implementados en el sistema y sus relaciones, las cuales son las mismas que las existentes en los diagramas de clases, y esto, debido a que se presume que al interior de cada componente van una o varias clases y por tanto las relaciones entre estas clases son las que marcan la pauta de las relaciones que deben llevar estos componentes. 4.7. DIAGRAMAS DE DESPLIEGUE Muestra una visión general que incluye los nodos que son los elementos que contienen los componentes del sistema. 5. MODELANDO CON UML El problema del modelado se puede enfocar desde tres puntos de vista: Modelar el Dominio del problema Modelar la solución del problema Modelar la codificación del problema Y cada modelamiento debe verse desde varios puntos de vista. A continuación veremos que algunos de estos modelamientos son mas cercanos a la codificación y otros son menos cercanos a la codificación (“Cuando se habla de codificación, se hace referencia en este material a código fuente”). Podemos decir que se después de modelar el dominio del problema, se esta en disposición de modelar la solución del problema y transitivamente después de modelar la solución del problema se esta en disposición de modelar la codificación del problema. 5.1. MODELAMIENTO DEL DOMINIO DEL PROBLEMA El dominio del problema es todo el conocimiento expresado en diagramas que asegure que el tema que se va a implementar se conoce, en pocas palabras que la lógica de negocio se conoce, que se tienen definidos los requerimientos del sistema y que se tienen identificadas las funcionalidades que debe desempeñar el sistema. En el modelamiento del negocio se debe modelar su parte dinámica como su parte estática. Por lo general se acostumbra a modelar la parte dinámica del negocio por medio de un modelo de procesos y la parte estática del negocio por medio de un modelo de dominio. Tenemos pues la siguiente tabla: MODELAMIENTO DEL NEGOCIO MODELAMIENTO PARTE ESTATICA MODELAMIENTO PARTE DINAMICA FORMA DE MODELARLO Modelo de Dominio Modelo de procesos 5.2. MODELAMIENTO DE LA SOLUCION DEL PROBLEMA MODELAMIENTO DE SOLUCION MODELAMIENTO PARTE ESTATICA MODELAMIENTO PARTE DINAMICA FORMA DE MODELARLO Diagrama de clases Diagrama de estado Diagrama de casos de uso Diagrama de secuencia Diagrama de colaboración Diagrama de Actividad 5.3. MODELAMIENTO DE LA CODIFICACION DEL PROBLEMA MODELAMIENTO DE LA FORMA DE MODELARLO CODIFICACION DEL PROBLEMA MODELAMIENTO PARTE ESTATICA Diagrama de Clases Diagrama de componentes Diagrama de despliegue MODELAMIENTO PARTE DINAMICA Diagrama de objetos Diagrama de secuencia Diagrama de colaboración Diagrama de actividad 6. MODELOS UML EN LOS FLUJOS DE TRABAJO RUP Teniendo en cuenta que para modelar con UML disponemos de los siguientes diagramas Diagrama de casos de uso Diagrama de clases Diagrama de objetos Diagrama de secuencia Diagrama de colaboración Diagrama de estado Diagrama de actividad Diagrama de componentes Diagrama de despliegue Y que los flujos de trabajo de RUP son: FLUJOS DE PROCESO Modelado del negocio Requisitos Análisis y Diseño Implementación Pruebas Despliegue FLUJOS DE SOPORTE Gestión del cambio y configuraciones Gestión del proyecto Entorno A continuación vamos a bosquejar los diagramas que se pueden asociar con cada uno de dichos flujos de RUP. 6.1. DIAGRAMAS USADOS EN EL FLUJO DE MODELADO DEL NEGOCIO Teniendo en cuenta Modelado del negocio Diagrama de casos de uso En bajo porcentaje Diagrama de clases En alto porcentaje , pero diagramas de clases globales Diagrama de objetos Diagrama de secuencia Diagrama de colaboració n Diagrama de estado Diagrama de actividad Diagrama de componente s Diagrama de En alto porcentaje Requisito s Análisi sy Diseño Implementació n Despliegu e Prueba s despliegue 6.2. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO REQUERIMIENTOS Modelado del negocio Requisito s Diagrama de casos de uso En bajo porcentaje En alto porcentaj e Diagrama de clases En alto porcentaje , pero diagramas de clases globales Diagrama de objetos Diagrama de secuencia En bajo porcentaj e Diagrama de colaboració n Diagrama de estado Diagrama de actividad Diagrama de componente En alto porcentaje En un bajo porcentaj e En un bajo porcentaj e Análisi sy Diseño Implementació n Despliegu e Prueba s s Diagrama de despliegue 6.3. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO ANALISIS Y DISENO Diagrama de casos de uso Diagrama de clases Modelad o del negocio En bajo porcentaj e Requisito s En alto porcentaj ee incluyend o casos de uso extendido s En alto porcentaj e, pero diagrama s de clases generales Diagrama de objetos Diagrama de secuencia Análisis y Diseño En bajo porcentaj e En alto porcentaje, incluyendo funcionalidad es que no estaban en la fase de modelado del negocio. En alto porcentaje, sobre todo en el flujo de diseño, mas que en el de análisis. En alto porcentaje Implementa ción Despliegu e Pruebas Diagrama de colaboració n En alto porcentaje Diagrama de estado Diagrama de actividad En alto porcentaj e En un bajo porcentaj e En un bajo porcentaj e En alto porcentaje En alto porcentaje Diagrama de component es Diagrama de despliegue 6.4. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO IMPLEMENTACION Modelad o del negocio Diagrama En bajo de casos de porcentaj uso e Diagrama de clases En alto porcentaj e, pero diagrama Requisito Análisis y s Diseño En alto porcentaj ee incluyen do casos de uso extendid os En alto porcentaje, incluyendo funcionalidad Implementaci ón Desplieg ue Prueb as s de clases generales Diagrama de objetos Diagrama de secuencia En bajo porcentaj e Diagrama de colaboraci ón Diagrama de estado Diagrama de actividad En alto porcentaj e En un bajo porcentaj e En un bajo porcentaj e es que no estaban en la fase de modelado del negocio. En alto porcentaje, sobre todo en el flujo de diseño, mas que en el de análisis. En alto porcentaje En alto porcentaje En alto porcentaje En bajo porcentaje En alto porcentaje En alto porcentaje Diagrama de component es Diagrama de despliegue En alto porcentaje 6.5. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO DESPLIEGUE Modelad Requisito Análisis y Implementaci Desplieg Prueb o del negocio Diagrama En bajo de casos de porcentaj uso e Diagrama de clases s Diagrama de objetos En bajo porcentaj e Diagrama de colaboraci ón Diagrama de actividad Diagrama En alto porcentaje, incluyendo funcionalidad es que no estaban en la fase de modelado del negocio. En alto porcentaje, sobre todo en el flujo de diseño, mas que en el de análisis. En alto En alto porcentaje porcentaje En alto porcentaje Diagrama de estado En alto porcentaj e ón ue En alto porcentaj ee incluyen do casos de uso extendid os En alto porcentaj e, pero diagrama s de clases generales Diagrama de secuencia Diseño En un bajo porcentaj e En un bajo porcentaj e En bajo porcentaje En alto porcentaje En alto porcentaje En alto En alto porcentaj e En bajo porcentaj e as de component es Diagrama de despliegue porcentaje En alto porcentaj e 6.6. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO PRUEBAS Diagrama de casos de uso Diagrama de clases Diagrama de objetos Diagrama de secuencia Modelad o del negocio En bajo porcentaj e Requisit os Análisis y Diseño Implementaci Desplieg ón ue Pruebas En alto porcentaj ee incluyen do casos de uso extendid os En alto porcenta je En alto porcentaj e, pero diagrama s de clases generale s En alto porcentaje, incluyendo funcionalida des que no estaban en la fase de modelado del negocio. En alto porcentaje, sobre todo en el flujo de diseño, mas que en el de análisis. En bajo En alto porcentaj porcentaje e En alto porcenta je En alto porcenta je En alto porcentaje En alto porcentaj e En alto porcenta je Diagrama de colaboraci ón Diagrama de estado Diagrama de actividad Diagrama de component es Diagrama de despliegue En alto porcentaje En un bajo porcentaj e En alto En un porcentaj bajo e porcentaj e En bajo porcentaje En bajo porcentaj e En alto porcenta je En alto porcentaje En alto porcenta je En alto porcentaje En alto porcenta je En alto porcentaje En alto porcenta je En alto porcentaj e En alto porcenta je 7. EL LENGUAJE OCL La presente sección pretende mostrar una breve introducción a lo que es lenguaje OCL pero desde el enfoque de compararlo con otras cuestiones de UML. Comienza el trabajo explicando la diferencia entre OCL y MOF, después entre OCL y UML. Más adelante se escriben las cosas más importantes de la evolución de OCL y de las cosas que se pueden hacer con OCL. Continuando se muestra la simbiosis existente entre OCL y los requisitos. Al finalizar se muestran en forma de conclusiones ventajas y desventajas de UML. El lenguaje OCL ha sido desarrollado a la par que el lenguaje de modelado UML, y por ello, podemos decir que es difícil que hablemos de OCL sin hablar de UML. [1] 7.1. OCL Y MOF El lenguaje de modelado UML es tan completo que incluso permite definirse así mismo, claro que dentro de unos parámetros como para no perderse la esencia inicial de UML. De otra parte es importante tener en cuenta que MOF es un lenguaje para definir lenguajes de modelado y obviamente desde este punto de vista debería estar bien acorde con UML, pero la verdad es que cuando se habla de UML 1.0 existen algunas diferencias entre éste y UML y por lo tanto algunas diferencias entre el OCL que se tenia en la versión OCL 1.0 y el OCL por ejemplo de la versión que acompaña a UML 1.5. [3] Todo lo anterior nos da a entender que el lenguaje de restricción de objetos está íntimamente relacionado con el lenguaje UML y a su vez UML está relacionado en forma estrecha con MOF, de lo cual se desprende que indirectamente podríamos pensar que cualquier versión de OCL no compagina muy bien con cualquier versión de MOF. [1] 7.2. UML Y OCL La idea general no es que UML dependa de OCL, sino que OCL se construye cuando se ven ciertas deficiencias en alguna especificación UML y se saca otra versión UML mejorada. [3] Otro aspecto que es necesario comprender es el aspecto de la independencia que debe existir entre OCL y UML para unas cosas y la dependencia para otras cosas. Por ejemplo, si no existiera UML no habría razón alguna para hablar de OCL, pero si no existiera OCL se podría pensar en UML como un lenguaje en el cual se dejaría al libre albedrío de los diseñadores la especificación de condiciones invariantes que deben cumplirse. [1] [3] Es importante notar que UML usa OCL, pero UML en ningún momento depende de OCL. Sin embargo los cambios y las mejoras hechas a OCL no tienen porque cambiar la estructura de UML y en forma recíproca los cambios hechos a UML en ningún momento tienen porque afectar al lenguaje OCL y es ésta situación la que habla de la independencia entre UML y OCL. [3] Algunos autores hablan de lo anteriormente mencionado diciendo que la especificación OCL no puede alterar la especificación del modelo gráfico[1] [3] Lo que hace UML, no lo hace OCL y lo que no hace OCL no lo puede hacer UML, lo que muestra una relación de complementariedad entre OCL y UML. 7.3. EVOLUCION DE OCL OCL en su primera versión lo que hacía y aún lo sigue haciendo es brindando la sintáxis necesaria para colocar especificaciones a un modelo UML, lo que sucede es que dichas especificaciones no siempre le dan precisión y consistencia, debido a que las herramientas no siempre usan dichas especificaciones de la misma manera. [4] Por todo esto, se puede decir que no solamente es necesario revaluar algunos aspectos de UML, sino de su lenguaje OCL. Como ejemplo claro de dicha revaluación se trabaja pues la versión UML 2.0 en la cual se desean corregir algunos de estos problemas[1]. De todas formas algo que si es natural es que todavía se tengan que reevaluar algunos aspectos tanto de UM como de OCL, debido a que es muy corto el tiempo que lleve éste lenguaje y son demasiadas las situaciones venideras que todavía no se tienen en cuenta. [4] La versión de OCL RFP más conocida es la versión OCL 2.0 que en verdad fue denominada UML 2.0 OCL RFC adoptado en agosto de 2003 y ofrece todos los elementos necesarios para ser integrada a UML 2.0 ofreciendo un lenguaje que permita especificar restricciones de objetos acordes al metamodelo de UML. 7.4. COSAS QUE SE PUEDEN HACER CON OCL [1] Describir guardas en los diagramas de estados. Navegar a través de los modelos gráficos. Especificar restricciones en las operaciones [4] 7.5. OCL Y LOS REQUISITOS Es interesante notar que un diagrama UML y concretamente un diagrama de Casos de Uso que no tenga especificados sus elementos OCL completamente , todavía no es un diagrama que capture los requisitos, pues las cuestiones puntuales de los requisitos por lo general se especifican con OCL. No olvidar que de todas formas OCL puede estar presente en casi cualquier diagrama de UML, con lo cual se puede decir que ayuda a ir enriqueciendo la semántica y el significado de cada uno de los mismos. 7.6. CONCLUSIONES SOBRE OCL 1. OCL tiene la ventaja de ser un lenguaje más fácil que cualquier otro lenguaje de programación y ello facilitaría su uso [1] 2. Tiene la ventaja de poderse utilizar para especificar invariantes en las clases, tipos y estereotipos. 3. Otra ventaja es que con el uso de OCL en modelos UML y dado que OCL sirve para describir las operaciones en base a pre y post condiciones los modelos que se construyan en UML y que estén correctamente especificados con OCL adquieren una mayor claridad para el usuario de dicho modelo. 4. Anteriormente se mencionaba que con OCL se podían especificar restricciones en las operaciones y esto trae grandes beneficios a los desarrolladores bien juiciosos pues les dejaría una buena documentación sobre la implementación de muchos métodos. 5. Por ser un lenguaje parecido al lenguaje de programación puede en algunas ocasiones a llegar a ser inentendible para algunos diseñadores que no programen mucho. 6. Al ser demasiado extenso se hace bastante largo el estudio de OCL 7. OCL ayuda a que los modelos UML tengan coherencia. 7.7. BIBLIOGRAFIA SOBRE OCL [1] http://www.afm.sbu.ac.uk/logic/ [2] Depetris, S. Aguería y H. Leone. "Introducción a la Programación Orientada a Objetos. Apuntes del curso". (1995). [3] http://www.vico.org [4] OMG Unified modeling language specification. Version 1.3. Cap. 7 : OCL. Publicat per l’Object Management Group http://www.omg.org/ . The Object constraint language : precise modeling with UML. Jos B. Warmer, Anneke G. Kleppe. Addison-Wesley, 1998 . 8. SOBRE LOS CASOS DE USO EN UML 2.0 Los casos de uso son una de las formas mas conocidas para capturar requerimientos. Esto no quiere decir que sean la única forma para capturar requerimientos. 8.1. IDENTIFICAR ACTORES Y CASOS DE USO Es importante notar que los actores son entidades autónomas desde la perspectiva del sistema que se esta desarrollando. Por ejemplo una aplicación de gestión de ventas que requiera información del sistema de nomina, no vera al sistema nomina como una persona de carne y hueso, pero si la vera como un ente autónomo que solicita información en un determinado momento. Esto es importante que se tenga en cuenta, si el ente autónomo solicita información al sistema es prudente colocar a este ente como un actor. Algunas cosas que nos ayudan a identificar actores es pensar en funcionalidades que debe prestar el sistema en relación con los clientes que requieren esta funcionalidad. Y en este punto la mayoría de las veces se puede ver que estas funcionalidades están especificadas en el manual de funciones de algún funcionario, pero esto no siempre sucede, caso en el cual hay que tener un poco de astucia y sentido común para capturar estas funcionalidades. Tal vez esta puede ser la razón por la cual se acostumbra a relacionar siempre actores con cargos y funciones, pero en algunos casos esto no siempre funciona según lo explicado anteriormente. Suponga que estamos desarrollando un sistema de información sobre quejas y reclamos a clientes. Algunas de las funcionalidades de un sistema como este serian: Envio de quejas a la empresa Captura de quejas del cliente Solicitud de envio de queja a Empresa Almacenamiento de quejas de clientes Seguimiento de queja expuesta por el Cliente Evaluacion de quejas no atendidas Evaluacion de quejas atendidas Es importante notar que estas funcionalidades a veces ocurren con una secuencialidad, razón por la cual es necesario conocer previamente a esta fase los procesos de la organización para poder establecer esta secuencialidad y conocer el dominio de aplicación del sistema con respecto a la empresa en la que va a funcionar el mismo. En otras palabras podríamos decir que estas funcionalidades tienen mas o menos las siguientes relaciones en un flujo de procesos de la empresa: Solicitud de envio de queja a Empresa Captura de quejas del cliente Almacenamiento de quejas de clientes Envio de quejas a la empresa Evaluacion de quejas atendidas Seguimiento de queja expuesta por el Cliente Evaluacion de quejas no atendidas Es importante notar que el anterior diagrama nunca se coloca en UML, pero si se observa desde el punto de vista de procesos de la empresa, se tiene un diagrama de procesos de la empresa. Bueno, continuando con nuestro proceso de establecer actores en este punto es importante notar que lo mas importante en el diagrama de casos de uso inicialmente es establecer bien las funcionalidades del sistema que posteriormente se convertirán en los casos de uso del sistema, y posterior a ello se observan entes autónomos que realicen dichas funcionalidades y estos serán candidatos a ser actores. En pocas palabras estamos diciendo que se comienza con las funcionalidades. De todas formas, hay ocasiones en las que como no es tan fácil identificar las funcionalidades del sistema se establece una serie de personas y entes autónomos que están directamente relacionados con el sistema y se observan las funcionalidades que realizan estos entes con el animo de establecer los casos de uso que faltan. Suponiendo que los casos de uso expuestos en el anterior diagrama ya están completos procedemos a separarlos y a ha colocar con la figura de un ser humano el ente que posiblemente ejerce dicha funcionalidad en el sistema que estamos desarrollando. Veamos: funcionario Solicitud de envio de queja a Empresa Cliente Envio de quejas a la empresa Captura de quejas del cliente Almacenamiento de quejas de clientes sistema Seguimiento de queja expuesta por el Cliente Evaluacion de quejas no atendidas auditorInterno Evaluacion de quejas atendidas 8.2. TIPOS DE RELACIONES ENTRE LOS CASOS DE USO Cuando dos casos de uso están relacionados es porque tienen algo en común. Si tienen algo en común pueden existir tres tipos de relaciones: Relaciones Extends Relaciones Include y Relaciones de generalización. En las siguientes secciones se explicaran cada una de estas tres. 8.3. IDENTIFICAR RELACIONES TIPO <<EXTENDS>> Según Martin Fowler es importante que se use la relación de <<extends>> cuando se tenga un caso de uso que es similar a otro, pero que hace mucho más. No se debe confundir esto con que un caso de uso “A” implica que se deba hacer algo que hace otro caso de uso “B” a parte que hace otras cosas. Lo anterior suena bastante confuso, pero es importante que se comprenda, porque si no seria causa de un mal modelamiento. Supongamos los siguientes casos de uso: Solicitud de envio de queja a Empresa Cliente Envio de quejas a la empresa Y supongamos que al analizar el caso de uso “envió de quejas a la empresa”, vemos que hay dos tipos de quejas que el cliente puede enviar a la empresa que son: Quejas sobre maltrato físico Quejas sobre maltrato psicológico. Y también digamos que después de analizar la situación, vemos que es necesario hacer la anterior división, debido a que los maltratos físicos son atendidos finalmente por un medico, en tanto que los maltratos psicológicos son atendidos por un psiquiatra. De otra forma, vemos que tanto los maltratos físicos como los maltratos psicológicos tienen unas mismas características, pero que hacen estas que su atención sea distinta la una de la otra, pero lo único cierto es que ambas son “quejas de maltrato” Con todo lo dicho hasta el momento tenemos pues el siguiente diagrama de casos de uso: Solicitud de envio de queja Enviar quejas de maltrato fisico <<<<extends>>>> Cliente Envio de quejas <<<<extends>>>> Envia quejas de maltrato psicologico Observe amigo lector / estudiante que el caso de uso “envio de quejas a la empresa” no esta directamente relacionado con el actor “Cliente”. Tambien observe que en términos lógicos una queja de maltrato físico es un tipo de queja sobre maltrato y para que esto quede bien claro en el diagrama es necesario colocar la palabra “maltrato” como se muestra en el siguiente diagrama: Solicitud de envio de queja Enviar quejas de maltrato fisico <<<<extends>>>> Cliente Envio de quejas de maltrato <<<<extends>>>> Envia quejas de maltrato psicologico Con el anterior diagrama es bueno observar dos cosas: Los casos de uso que extienden del caso de uso base no se colocan directamente relacionados con el actor del sistema. Cuando se dice que un cliente envía quejas de maltrato, se esta diciendo que eventualmente el puede o esta en capacidad de enviar quejas sobre maltrato físico y de enviar quejas sobre maltrato psicológico, en pocas palabras se dice que si un actor de hace cargo del caso de uso base, también se debe hacer cargo de todas sus extensiones. Una conclusión de las dos anteriores es que si un actor se hace cargo de un caso de uso base, tan solo el se hará cargo de todas sus casos de uso que son extensiones del mismo. Según algunos autores es bueno colocar los verbos de los casos de uso en algún formato, por ejemplo el más acogido es colocarlos en términos de verbos en infinitivo, con lo cual nuestro diagrama de casos de uso mejorado seria: solicitar envio de queja enviar quejas de maltrato fisico <<<<extends>>>> Cliente enviar quejas de maltrato <<<<extends>>>> enviar quejas de maltrato psicologico 8.4. ERRORES COMUNES CON RELACIONES TIPO <<EXTENDS>> Según lo mencionado en la sección anterior podemos decir que el siguiente diagrama de casos de uso esta mal elaborado. Solicitud de envio de queja Enviar quejas de maltrato fisico <<<<extends>>>> <<<<extends>>>> Envio de quejas de maltrato Cliente Envia quejas de maltrato psicologico La razón por la cual esta mal elaborado el anterior diagrama de casos de uso es porque no podemos relacionar los casos de uso que extienden de otro caso de uso directamente con el actor. Veamos ahora el error existente en el siguiente diagrama de casos de uso: Funcionario Solicitud de envio de queja <<<<extends>>>> Enviar quejas de maltrato fisico <<<<extends>>>> Envio de quejas de maltrato Cliente Envia quejas de maltrato psicologico El error es que si un actor se hace cargo de un caso de uso base, también el se hace cargo de todas las extensiones de dicho caso de uso. En el caso concreto del anterior diagrama vemos que el actor “Funcionario” se hace cargo de un caso de uso extendido de uno base que esta a cargo del actor “Cliente”. Es posible que el diagramador quiera hacer el anterior diagrama de casos de uso y se encontrara con que no es posible llevar este diagrama de casos de uso a código. Una opción para solucionar este problema es crear un caso de uso separado para las quejas de maltrato físico de los funcionarios. Una posible solución al anterior problema es la siguiente: Solicitud de envio de queja a Empresa Enviar quejas de maltrato fisico a clientes <<<<extends>>>> <<<<extends>>>> Envio de quejas de maltrato a clientes Cliente Envia quejas de maltrato psicologico a clientes <<<<extends>>>> Funcionario Enviar quejas de maltrato fisico a funcionarios Envio de quejas de maltrato a funcionarios En donde queda claro que se han discriminado los maltratos a funcionarios y los maltratos a clientes. La pregunta que surge entonces es: ¿Cómo optimizar este modelamiento cuando la misma acción sea realizada por varios actores?. Obviamente el modelamiento anterior es bueno cuando no se tengan muchos actores relacionados con “envió de quejas sobre maltratos”. En términos de código fuente estaríamos diciendo que estaríamos escribiendo y duplicando tanto código que el modelamiento no tendría razón de ser si este tipo de situaciones a nivel de implementación se presentan. Una respuesta posible a la anterior pregunta es que de pronto estemos modelando a un nivel de detalle tan grande que posiblemente ya lo que se este modelando no sean actores y casos de uso, sino métodos de una clase. 8.5. RELACIONES DE GENERALIZACION SIN ESTEREOTIPO Hasta el momento las relaciones vistas son relaciones de generalización con estereotipo, es decir relaciones de extensión muy controladas con la palabra <<extends>>, pero a veces es importante hacer relaciones de generalización menos controladas, por ejemplo en el caso que no se requiera que un actor se haga cargo de todas las extensiones de un caso de uso determinado. Este problema lo vemos en el siguiente caso de uso: solicitar envio de queja <<<<extends>>>> enviar quejas de maltrato fisico a clientes Cliente enviar quejas de maltrato a <<<<extends>>>> clientes enviar quejas de maltrato psicologico a clientes <<<<extends>>>> enviar quejas de maltrato fisico a funcionarios enviar quejas de maltrato a funcionarios <<<<extends>>>> Funcionario enviar quejas de maltrato psicologico a funcionarios <<<<extends>>>> enviar quejas de maltrato fisico a auditores <<<<extends>>>> enviar quejas de maltrato psicologico a auditores enviar quejas de maltrato a auditores Auditor En donde no es posible agrupar las quejas de maltrato psicológico y las quejas de maltrato físico si se sigue usando la palabra <<extends>>. Una solución es hace relaciones de extensión poco controladas. A fin de comprender como se podría solucionar el agrupamiento en el anterior diagrama de casos de uso, mostramos a continuación una posible solución: enviar quejas de maltrato enviar quejas de maltrato fisico enviar quejas de maltrato fisico a clientes enviar quejas de maltrato psicologico Cliente enviar quejas de maltrato psicologico a clientes enviar quejas de maltrato psicologico a funcionarios enviar quejas de maltrato fisico a funcionarios enviar quejas de maltrato psicologico a auditores enviar quejas de maltrato fisico a auditores Funcionario Auditor Observe amigo lector / estudiante que ahora si es posible que casos de uso extendido estén directamente asociados con distintos actores y todo debido a que son relaciones de generalización sin estereotipo. Antes de concluir con la explicación sobre relaciones de generalización sin estereotipo decimos algunas afirmaciones sobre este tipo de relaciones: 1. En una relación de generalización sin estereotipo puede anadir o no acciones con respecto al caso de uso base. 2. Un caso de uso extendido por medio de una relación de generalización sin estereotipo es una variante del caso de uso base. 3. En las relaciones de generalización sin estereotipo el caso de uso que extiende puede incluir parte o la totalidad del comportamiento del caso de uso base. 8.6. IDENTIFICAR RELACIONES TIPO <<USES>> O <<INCLUDE>> La razón por la cual la relación <<uses>> es la misma que la relación <<include>> es que antiguamente antes de la versión 1.3 de UML se usaba la palabra <<uses>>, pero ahora se usa la palabra <<include>>. A diferencia de las relaciones de generaliacion tanto con estereotipo como con estereotipo <<extends>>, decimos que si un caso de uso “A”, incluye el comportamiento del caso de uso “B”, entonces el caso de uso “A”, esta obligado a incluir todo el comportamiento del caso de uso “B”. En pocas palabras estamos diciendo que para los casos de uso que tengan una relación <<include>> como la siguiente: <<<<include>>>> Caso de USO A Diagrama NO VALIDO <<<<include>>>> ACTOR Caso de USO X Caso de USO B No son validos, al igual que tampoco son validos diagramas como el siguiente: Caso de USO A <<<<include>>>> Diagrama NO VALIDO validar usuario ACTOR <<<<include>>>> Caso de USO B En tanto que diagramas como los siguientes si son validos: <<<<include>>>> Caso de USO A <<<<include>>>> validar usuario ACTOR Diagrama VALIDO Caso de USO B Y no esta demás recordar que diagramas de casos de uso como los siguientes: <<<<extends>>>> Diagrama NO VALIDO Caso de USO A Caso de USO X ACTOR <<<<extends>>>> Caso de USO B No son validos, en tanto que diagramas como los siguientes: <<<<extends>>>> Caso de USO A Diagrama VALIDO ACTOR Caso de USO X <<<<extends>>>> Caso de USO B Son validos. Para resumir estamos diciendo que relaciones entre casos de uso tipo <<include>> son relaciones de dependencia y por tanto la flecha de generalización no aplica cuando se encuentre presente este termino en el diagrama de casos de uso. 8.7. EJEMPLO DE RELACION TIPO <<USES>> O <<INCLUDE>> El siguiente es un ejemplo de un diagrama de casos de uso que usa la relación tipo <<include>>: <<<<include>>>> Consultar Cliente <<<<include>>>> validar usuario funcionario Diagrama VALIDO Matricular Cliente En el que se esta diciendo que para que se pueda consultar un cliente se debe validar el usuario, y también se esta diciendo que para matricular un cliente se debe validar el usuario. Recordemos pues que el siguiente diagrama de casos de uso no es valido: <<<<include>>>> Consultar Cliente <<<<include>>>> funcionario validar usuario Diagrama NO VALIDO Matricular Cliente 8.8. CASO ESPECIAL DE RELACION TIPO <<USES>> O <<INCLUDE>> Cuando un caso de uso “A” dependa de otro caso de uso “B”, es porque muy probablemente el caso de uso “A” es usado por un actor, pero esto no quiere decir que el caso de uso “B”, no sea usado directamente por el mismo u otro actor. Veamos el siguiente diagrama de casos de uso para comprender el concepto: <<<<include>>>> CASO DE USO ABSTRACTO A B ACTOR En el anterior diagrama estamos diciendo que el caso de uso “B” es un caso de uso abstracto porque no es invocado directamente por un actor. En el siguiente diagrama de casos de uso: A ACTOR A <<<<include>>>> CASO DE USO CONCRETO B ACTOR B Tenemos que el caso uso “B”, es un caso de uso no abstracto o mejor dicho lo que algunos autores llaman caso de uso “concreto”. 8.9. DOCUMENTACION DE CASOS DE USO Es importante documentar los casos de uso y para esto es necesario tener en cuenta que un caso de uso no debe ser una actividad atómica que realiza el sistema, sino que debe ser una funcionalidad que el sistema presta y que puede ser iniciada por unos actores. Dicho esto, es claro que un caso de uso por ser una funcionalidad no tan simple tiene posibilidades que no funciones y esto debe ser de alguna manera documentado, también es importante notar que para realizar un caso de uso se deben realizar una serie de acciones con una secuencia que deben estar también documentadas debidamente con el fin que el flujo de trabajo de análisis sea lo mas claro posible. A continuación se muestra una plantilla sugerida para documentar casos de uso Numero del caso de uso <<Numero >> Cabecera del caso de uso <<Nombre del Caso de Uso.>> Ejemplo: Ingresar estudiante <<Id del <<Nombre del requisito funcional>> requisito funcional>> Ejemplo: <<Versión>> Requisito numero 44 del documento de requisitos funcionales establecidos en la entrevista 2 hecha al asistente de decanatura de la Facultad Tecnológica de la Universidad Distrital <<Numero de versión y fecha>> <<Autores>> Ejemplo: Version 1.3 del 14 de abril de 2008 <<Autor>> Ejemplo: Luis Felipe Wanumen Silva y Juan Carlos Guevara Bolaños Tipo de Caso Abstracto No Abstracto X de USO Fuentes <<Fuente de la versión actual>> Ejemplo: Estado documento Documento almacenado en http://www.udistrital.edu.co/facultados.tecnologica/docu mento1.doc del DEFINITIVO Evento de <<Nombre del evento de activación>> Activación Ejemplo: Cuando un estudiante hace su petición de ingreso y se comunica con un usuario que esta activo en el sistema y que tiene las facultades para hacer su ingreso, obviamente con la autorización de la Decanatura y de la Universidad para realizar el proceso de matricula para dicho estudiante. <<Objetivo <<Nombre del objetivo general>> general del caso de uso>> Ejemplo: <<Objetivos específicos>> Registrar un estudiante mediante el proceso de matricula para que sea parte activa del sistema y pueda gozar de todos los privilegios académicos con que cuenta un estudiante de la Universidad Distrital. <<Nombre del objetivo especifico>> Ejemplo: Matricular a un estudiante a la Universidad Distrital y concretamente a la Facultad Tecnológica en el proyecto Curricular de Sistematización de Datos. Modalidad del <<Numero modal en el que los actores o entidades son caso de Uso afectadas>> Ejemplo: Descripción: El caso de uso no afecta sino únicamente a un estudiante y para ver afectados a varios estudiantes recién matriculados es necesario realizar el proceso n veces, donde n es el numero de estudiantes a los que se les va a realizar el proceso de matricula. El sistema permite a <<lista de actores>> en <<instante en el que se puede realizar el caso de uso>> <<funcionalidad del caso de uso>>. Ejemplo: El sistema permite a los administradores, profesores y estudiantes con permisos de decanatura, hacer la Actores matricula de estudiantes ingresando los datos personales, económicos, sociales y académicos de los nuevos y futuros estudiantes de la Universidad. <<Listado de actores>> Ejemplo: Administrador, profesor, estudiante Objetivo Precondici ones Pos condicione s Flujo de Eventos o secuencia Normal de acciones. <<Objetivo en infinitivo>><<elementos que se ven afectados por el verbo incluyendo actores o estados del sistema>> Ejemplo: Registrar en la base de datos un estudiante <<Estado(s) de actores y/o entidades preliminares para que se pueda ejecutar el caso de uso en cuestión>> Ejemplo: El estudiante no debe estar registrado. <<Estado posterior en el que debe estar un actor o una entidad, después de ejecutado el caso de uso>> Ejemplo: Conocer todos los datos del estudiante <<Recuerde que el flujo de eventos debe tener coherencia con el futuro diagrama de secuencia y diagrama de colaboración y que no debe incluir casos no perfectos o excepcionales>> Paso Acción Responsabl e <<Identifica <<acción a realizar o situación que produce <<Actor>> ción del una alternativa, mostrando las alternativas . paso>> para este ultimo caso>> Especifica ndo si es una acción o una respuesta de algún agente del sistema. Ejemplo: Ejemplo: Ejemplo: Si << situación que produce una alternativa>>, el sistema deberá <<acción a realizar>> 1 Digitar todos los datos del estudiante Actividade s del Actor Ejemplo: Ejemplo: Ejemplo: 2 Validar formulario 2a. Si se valido correctamente el formulario, el sistema debe mostrar un mensaje de satisfacción al cliente. 2a. Si se valido correctamente el formulario, el sistema debe enviar los datos al servidor usando el método de autenticación POST. -------- Invocada por el actor e implement ada por el sistema Ejemplo: Ejemplo: Ejemplo: 2 Almacenar los datos en la base de datos - Respuesta del Sistema ---------------------------------------------------------------------------------N --------------------------------------Flujos 1 --------------------------alternos 2 ----------------------------------------------------------N --------------------------Situaciones <<Recuerde que en esta parte de la documentación se pretende modelar el Anormales caso de uso y sus situaciones excepcionales que deben estar completamente acordes con los diagramas de flujo futuros con los que se relaciona este caso de uso y que serán elaborados en el flujo de análisis y diseño. También es bueno recordar que un caso de uso como mínimo debe tener una situación excepcional, porque si no tiene casos excepcionales, quiere decir que es demasiado atómico o que le falta modelamiento>>. Tambien recuerde que en muchos lenguajes de programación las excepciones se codifican con bloques try-catch-finally, es decir que no solamente es necesario colocar la excepción y el manejo que se le va a dar, sino que en muchos casos es necesario colocar acciones que en forma indiferente de la presentación de la excepción siempre se van a efectuar, este es el caso de las instrucciones que van en los bloques “finally”. Tambmién es bueno tener en cuenta que las excepciones son lanzadas y capturadas por otros actores, entidades o sistemas con el animo de lograr un tratamiento adecuado de las excepciones <<en el caso en el que>><<actor o entidad involucrada>><<estado del actor o entidad>><<predicado acorde con la frase>>, el sistema deberá <<acción o acciones a realizar>><<casos de uso y /o acciones correctivas>>. (Esto para cada una de las opciones anormales y / o combinación de estas). Tener en cuenta que a veces ciertas situaciones excepcionales son excepcionales si están acompañadas de unos ciertos factores. FINALIZADOR: <<Accion que siempre se va a realizar en forma independiente que se presente o no la excepcion>>. ACTORES ENTIDADES O SISTEMAS QUE RECIBEN EXCEPCION. <<Actor, entidad o sistema que es capaz de atrapar la excepcion>> LA Ejemplo: 1. En el caso en el que un estudiante ya esté registrado en la base de datos, pero halla sido ingresado el mismo día de la actualización de datos, el sistema deberá informarle al usuario que ya existe uno y darle la posibilidad para que cree uno nuevo con los datos ingresados actualmente, pero con distinto identificador NIP (numero de identificación personal) o también le da la opción para que guarde en un archivo los datos, pero que de ninguna manera los ingrese al sistema con este código. FINALIZADOR: A pesar que el estudiante este o no registrado en la base de datos, de todas formas, siempre se emite un mensaje al final, en el que se muestra al usuario los resultados del ingreso o no ingreso del estudiante al sistema por medio de alertas. ACTORES ENTIDADES O SISTEMAS QUE RECIBEN LA EXCEPCION. Si el estudiante ya esta registrado, se notifica al actor “AUDITOR” para que el conozca por lo menos el código de los estudiantes a los cuales se les ha hecho intentos varios de ingresarlos en forma duplicada con el animo que este tenga conocimiento de mencionados estudiantes. 2. En el caso en el que un estudiante ya esté registrado en la base de datos, pero NO halla sido ingresado el mismo día de la actualización de datos, el sistema deberá informarle al usuario que ya existe uno y darle la posibilidad para que cree uno nuevo con los datos ingresados actualmente, pero con distinto identificador NIP (numero de identificación personal) o también le da la opción para que guarde en un archivo los datos, pero que de ninguna manera los ingrese al sistema con este código. FINALIZADOR: A pesar que el estudiante este o no registrado en la base de datos, de todas formas, siempre se emite un mensaje al final, en el que se muestra al usuario los resultados del ingreso o no ingreso del estudiante al sistema por medio de alertas. ACTORES ENTIDADES O SISTEMAS QUE RECIBEN LA EXCEPCION. Se notifica al sistema, se crea un archivo de log o si ya existe se le anade una línea con la explicación del error presentado y se le da la posibilidad al usuario que guarde o que no guarde los datos digitados hasta el momento para un posterior ingreso. Esto se hace por medio de una carpeta llamada la carpeta de “No Enviados”. Cambios de estado Rendimien to <<Recuerde que toda acción es acción si cambia el estado de alguna entidad o de algún actor>>(Las cosas se hacen para transformar el estado de algo o de alguien y si no lo logra no es una acción que tenga una funcionalidad interesante, es decir que de no cambiarse el estado de algo, se podría decir que este caso de uso no es un caso de uso) Ejemplo: El estado del estudiante se cambia de inactivo en el sistema a activo en el sistema. Paso Cota de tiempo Ejemplo: 1 2 Ejemplo: N segundos N segundos Frecuencia esperada <<No de veces>>veces <<unidad de tiempo>> Importanci a Urgencia <<sin importancia o importancia vital>>. (Recuerde “o” excluyente) Comentari <<Comentarios adicionales>> <<Puede esperar, hay presión, inmediatamente>> os Periodicidad 9. MODELAMIENTO UML Y SU IMPLEMENTACIÓN EN JAVA UML es uno de los lenguajes de modelado más importantes hoy en día utilizado principalmente para modelar aplicaciones y sistemas orientados a objetos. Por esta razón fundamental es preciso anotar que si el lenguaje a utilizar no presenta características verdaderamente orientadas a objetos, no es muy claro el poder utilizar en todo su esplendor este lenguaje para modelar sistemas desarrollados con estos lenguajes. Por fortuna la mayoría de lenguajes de programación actuales presentan características verdaderamente orientadas a objetos e incluso lenguajes como java obligan que se tenga una concepción muy clara a cerca de lo que es el modelado orientado a objetos, por cuanto desde su concepción se ha visto como un lenguaje orientado a objetos para la web. Precisamente hablando del lenguaje java, se ha querido tomar este como la base para comprender muchos conceptos de orientación a objetos y para comprende el modelado orientado a objetos. Es sabido por muchos estudiantes que los libros dedicados a la parte de orientación de objetos con énfasis en el análisis y/o en el diseño, carecen de la parte de programación que aterrice los conceptos allí expuestos. De otra parte la mayoría de textos de referencia o tutoriales sobre un lenguaje en particular carecen de secciones que expliquen como se podría modelar una aplicación con dicho lenguaje. En últimas podemos observar que la parte de programación y la parte de análisis y diseño se encuentran verdaderamente aisladas en muchos textos y son pocos los libros y tutoriales que intentan dar una visión en conjunto de estas dos cosas que en sí, van de la mano, por cuanto del tipo de lenguaje a utilizar depende del tipo de modelamiento a utilizar. Con todo lo expuesto anteriormente, el autor de la enciclopedia conociendo ha querido desarrollar un material que de las bases generales del lenguaje UML, pero orientando al estudiante sobre la forma de ir de una vez haciendo sus implementaciones en lenguaje java. Se ha tomado el lenguaje java para este fin, por ser uno de los lenguajes más utilizados en el mundo para la programación en internet y últimamente para la programación de aplicaciones móviles, de voz, de correo, de dispositivos, etc. 9.1. DEFINICIÓN DE RELACIONES Las relaciones se pueden definir como el tipo de conexiones entre las diferentes clases necesarias para la implementación de una aplicación o de un sistema. Este concepto viene entonces íntimamente ligado con el concepto de relaciones que se ve en el mundo real entre los diversos objetos que se pueden encontrar en el mismo. Por ejemplo un carro es un tipo de automóvil y un automóvil es a su vez un tipo de medio de transporte y un medio de transporte es a su vez un objeto inventado por el hombre y entre estos conceptos podríamos entonces definir un tipo de relaciones específicas para modelar esta forma de percibir al carro con respecto a otros términos reales o abstractos inventados por el hombre. Existen a su vez varios tipos de relaciones entre los objetos, las cuales se irán describiendo con mayor detalle en las siguientes secciones, pero por el momento nos limitaremos a decir que las más importantes son: TIPOS DE RELACIONES Relaciones de DEPENDENCIA Relaciones de GENERALIZACIÓN 9.2. GENERALIZACIÓN VS HERENCIA Supongamos el siguiente diagrama de clase: Relaciones de ASOCIACIÓN La implementación de dicho diagrama de clase se hace en dos archivos, los cuales se muestran a continuación: // Archivo: MATERIA.java public class MATERIA { protected Integer COD_MAT; private String NOM_MAT; MATERIA() { } } y el archivo: // Archivo: ASIGNATURA.java public class ASIGNATURA extends MATERIA { private Integer COD_ASIG; private String NOM_ASIG; ASIGNATURA() { } } Observemos que esto es en esencia una herencia simple, debido a que existe una clase base denominada MATERIA y una clase que hereda de ésta, la cual se llama ASIGNATURA. En realidad los términos generalización, nos indican que una clase es la base para las demás y el término herencia, nos indica que una clase hereda características de otra, la cual es una clase generalización con respecto a la mencionada. En vista de éste tipo de discusiones, podemos ver que en realidad estamos hablando de lo mismo, lo que sucede es que para referirnos a la clase de la que se hereda usamos el término generalización y para referirnos a la que utiliza dicha clase para heredar, utilizamos el término herencia. 9.3. EL ACCESO PRIVADO Para no ir tan lejos con la parte teórica, diremos que una función que sea privada en una clase solamente puede ser accedida por otra función en la misma clase. Es decir que una función privada no puede ser llamada desde una instancia de la clase y mucho menos desde una instancia de una clase heredada de esta. Bueno, con el ánimo de ir explicando todos estos conceptos, a continuación se muestra una clase denominada “MATERIA”, la cual tiene tres funciones privadas (getCOD_MAT(), getNOM_MAT() y getDES_MAT() ) y una función pública (getCODIGO() ). Veamos: // Archivo: MATERIA.java public class MATERIA { protected Integer COD_MAT; MATERIA() { COD_MAT = new Integer(5); } private Integer getCOD_MAT(){ return COD_MAT; } // Por defecto la funcion es publica Integer getCODIGO(){ Integer aux = getCOD_MAT(); return aux; } } Observemos que podemos llamar a la función getCOD_MAT() desde una función que haga parte de la clase y no ocurre ningún error: Pues bien, si intentáramos acceder a la función getCOD_MAT() desde una instancia de la clase MATERIA, tal como se muestra a continuación: MATERIA obj_materia = new MATERIA(); Integer cod_materia = obj_materia.getCOD_MAT(); Tendríamos un error al compilar el programa y este error sería: getCOD_MAT() has private access in MATERIA Integer cod_materia = obj_materia.getCOD_MAT(); 1 error La anterior situación se puede modelar en UML mediante el siguiente diagrama: Recordemos que la flecha punteada tambien se puede usar para especificar la relacion entre una clase y una instancia de la misma. Tambien fijemonos que el hecho de invocar un metodo al que no se tiene acceso no se puede modelar con el diagrama de clases, anterior, puesto que el diagrama muestra la vista estatica y no la vista dinamica que si permite mostrar como y que tipo de metodos se invocan. De todas formas se aprovecha el momento para indicar que el anterior diagrama es mejor no hacerlo debido a que se puede presentar para confusion y algunas herramientas de modelamiento no permiten incorporar objetos al interior de un diagrama de clases, situación esta que se presenta, con lo cual el diagrama anterior es inconveniente para este tipo de situaciones. El diagrama de secuencia que muestra la intencion de querer invocar el metodo “getCOD_MAT()” es el siguiente: obj_materia : MATERIA getCOD_MAT( ) Y si solamente uno se limita a observar el diagrama de secuencia tampoco logra percibir el error, pero si se observan los dos diagramas con detenimiento, es decir el último diagrama de clases mostrado y el presente diagrama de secuencia, veremos que es facil detectar el error. De todas si la aplicación es demasiado grande, es posible que el modelamiento no llegue a estos detalles y con seguridad el error no sea visible, sino solamente en tiempo de codificacion del software. Como se imaginará el amigo lector / estudiante, si no es posible acceder a una función como la anterior desde una instancia de la clase, mucho menos será posible acceder a la función desde una clase heredada. Para mostrar este concepto, a continuación se muestra una clase que hereda de la clase MATERIA, y que se denomina ASIGNATURA, la cual tiene una instrucción que intenta acceder a la función getCOD_MAT() y obviamente no puede. Veamos: // Archivo: ASIGNATURA.java public class ASIGNATURA extends MATERIA { private Integer COD_ASIG; private String NOM_ASIG; ASIGNATURA() { Intege codigo_mat = getCOD_MAT(); } } Para este caso el compilador sacará un error similar al siguiente: getCOD_MAT() has private access in MATERIA Intege codigo_mat = getCOD_MAT(); 1 errors Hasta ahora el diagrama de clases del caso expuesto toma la siguiente forma: Y podemos observar que con solo visualizar este diagrama de clases no se puede detectar el error. En cambio si observamos el anterior diagrama junto con el siguiente diagrama de secuencia: : ASIGNATURA getCOD_MAT( ) Podemos ver que si es factible detectar el error. Pero antes de continuar con nuestra explicación es bueno observar que en el diagrama de secuencia anterior se menciona que un objeto de la clase “ASIGNATURA” que no tiene un nombre definido intenta acceder al metodo “getCOD_MAT()” del mismo. Observe tambien que el anterior diagrama se puede bosquejar antes de haber creado los objetos. Yo sé que puede sonar bastante canzón y molesto decir que las instancias de la clase heredada tampoco podrán acceder a la función getCOD_MAT(), pero por experiencia docente se que es necesario hacer todo este tipo de aclaraciones con el ánimo no de repetir cosas, sino de lograr la mayor comprensión de los conceptos. Veamos las siguientes instrucciones: ASIGNATURA ojb_asignatura = new ASIGNATURA(); Integer cod_asignatura = ojb_asignatura.getCOD_MAT(); De las cuales solamente nos resta decir que generan un error similar al siguiente: getCOD_MAT() has private access in MATERIA Integer cod_asignatura = ojb_asignatura.getCOD_MAT(); 1 errors El diagrama de clases de esta última situacion, seria muy similar al siguiente: Pero nuevamente llegamos a la conclusión que dado que aquí el error es el resultado de invocar un metodo por parte de un objeto, esta situación es algo dinamica y no tiene porque reflejarse en los diagramas de clases, viene entonces la pregunta: ¿En que diagrama podemos mostrar este tipo de situaciones anormales, de tal forma que con solo ver el diagrama sepamos que estamos haciendo algo mal y no tengamos que esperar a la codificacion para detectar el error?. La respuesta se resuelve recurriendo una vez mas a los diagramas de secuencia, el cual, para el caso del ejercicio que estamos haciendo toma un aspecto similar al siguiente: ojb_asignatura : ASIGNATURA getCOD_MAT( ) Y volvemos nuevamente a lo que se ha dicho varias veces en esta seccion y es que hay errores que no se ven solo con el diagrama de secuencia unicamente, o con el diagrama de clases unicamente, sino con los dos, ya que entre los dos, dan una vision mas completa del sistema, obviamente es posible que existan errores que tampoco se puedan ver incluso con diagrama alguno y en estos casos tenemos errores de codificacion que solo se ven en tiempo de compilación o gravemente en ejecución. Se dice que gravemente en ejecución, porque la idea de todos estos modelamientos es disminuir el numero de errores que se presenten a la hora de codificar y de implementar el sistema.(Sin embargo los diagramas no son perfectos y siempre existiran errores en el momento de la codificacion). 9.4. EL ACCESO PROTECTED El atributo “PROTECTED” aplicado a un miembro dato, indica que las funciones de la clase base pueden accederlo sin ningún problema, y más aún, que las funciones miembro de las clases derivadas de esta también lo pueden acceder. Hay que tener en cuenta que se comportan como si fueran “PRIVATE” para las funciones miembro de clases que no tengan relación de herencia con la misma. Conclusión: “Lo protegido, no es tan protegido para los hijos, como en la vida real, las personas protegen sus cosas, pero le dan muchas veces confianza de utilización de los bienes a los hijos” Bueno, a continuación se muestra una clase base: // Archivo: MATERIA.java public class MATERIA { protected Integer COD_MAT; private String NOM_MAT; public String DES_MAT; MATERIA() { COD_MAT = new Integer(5); } protected Integer getCOD_MAT(){ return COD_MAT; } // Por defecto la funcion es publica void setCODIGO(){ COD_MAT =new Integer(20); } } Observemos que esta clase tiene una función denominada setCODIGO(), la cual modifica el tipo de objeto de dato llamado COD_MAT. Pues bien, es posible crear una instancia de esta clase y por medio de la misma modificar nuevamente la variable de objeto de dato, tal como se muestra a continuación: MATERIA obj_materia = new MATERIA(); obj_materia.COD_MAT = new Integer(35); Esto deja al recolector de memoria de Java la responsabilidad de eliminar la memoria usada para almacenar los objetos cuyas referencias ya se han perdido, sin embaro en la medida de lo possible no es aconsejable dejarle toda la carga al recolector de memoria de Java. Hasta ahora el diagrama de clases de nuestro ejercicio toma la siguiente forma: Y el diagrama de secuencia que muestra la forma conceptual en la que se invocaron los metodos toma el siguiente aspecto: ojb_m ateria : MATERIA Bueno, la pregunta es: ¿esto es realmente un diagrama de secuencia?, la respuesta es: “Este es el diagrama de secuencia de lo que se hizo hasta ahora”. Entonces viene otra pregunta: ¿Si estamos modificando un atributo desde un objeto esto acaso no es una accion?, la respuesta es si, pero lo que sucede es que en los diagramas de secuencia unicamente se colocan las acciones producto de invocación de metodos y en este caso, la accion de alterar el contenido de un atributo no se hizo por medio de un metodo. Con todo lo anterior nos queda bien claro que una buena practica de programación obliga a que los cambios de atributos de los objetos se hagan a traves de metodos de dichos objetos que se encarguen de recibir valores y que reemplacen el valor del atributo interno por el valor que se ha pasado como parámetro al metodo. Esto tiene entre otras razones a parte de un buen encapsulamiento, la razon que si no se usan estas tecnicas de programación, no es posible que dichas alteraciones queden reflejadas en diagramas de secuencia y como consecuencia habran cosas que haga el sistema que no pueden ser documentadas ni con los diagramas de clases, ni con los diagramas de secuencia. En otras palabras hay que construir software que pueda ser fácilmente modelable con UML y verificable mediante la visualizacion de dichos modelos, porque para eso fueron creados, no solo para documentar el sistema, sino para corregir errores antes que se llegue a fases avanzados como las de de construccion y transición. Ahora vamos pues a crear una clase heredada de la clase anterior, denominada ASIGNATURA, la cual se muestra a continuación: // Archivo: ASIGNATURA.java public class ASIGNATURA extends MATERIA { private Integer COD_ASIG; private String NOM_ASIG; ASIGNATURA() { // Integer codigo_mat = getCOD_MAT(); COD_MAT = new Integer(10); } } Como podemos observar, esta clase también puede modificar el objeto de datos COD_MAT en forma directa, sin mayores problemas. Podemos entonces ver que es factible modificar la misma variable desde una instancia de la clase ASIGNATURA, tal como se muestra a continuación: ASIGNATURA obj_asignatura = new ASIGNATURA(); obj_asignatura.COD_MAT = new Integer(30); pero nuevamente insistimos en que no es la major forma para modificar atributos hacerlo directamente accediendo al atributo, sino que es major usar un metodo que se encargue de recibir un valor y asignarselo al atributo, esto dara al codigo mayor encapsulamiento y menor probabilidad de propagacion de errores. 9.5. ACCESO A LOS ATRIBUTOS: PRIVATE, PROTECTED O PUBLIC A los diversos atributos se les puede colocar tres palabras reservadas que los preceden con el fin de especificar el tipo de acceso que se va a tener de los mismos desde otras clases. A continuación se presenta un cuadro en el que se muestra el tipo de acceso que se tiene a un atributo si se declara como “private”, “protected” o “public”. Acceso desde: private protected public (package) la propia clase S S S S subclase en el mismo paquete N S S S otras clases en el mismo paquete N S S S subclases en otros paquetes N X S N otras clases en otros paquetes N N S N En este cuadro la “S”, significa: Puede acceder “N”: No puede acceder. X: puede acceder al atributo en objetos que pertenezcan a la subclase, pero no en los que pertenecen a la clase madre. Es un caso especial 9.6. ASOCIACIONES Las asociaciones son uno de los temas más tratados en bases de datos y la verdad es que es necesario tratar este tema con mucho cuidado y detenimiento, puesto que de nada sirve crear y estructurar bien las clases, si la asociaciones entre las mismas no se hacen de la mejor forma. En el siguiente ejercicio, se muestra la asociación entre una ASIGNATURA y un ESTUDIANTE: En el anterior diagrama de clases, se está intentando decir: Un estudiante puede inscribir o no una materia Un estudiante puede inscribir como máximo seis materias Una asignatura puede estar asociada con un cero o hasta 35 estudiantes El nombre de la asociación entre el objeto ASIGNATURA y el objeto ESTUDIANTE es INSCRIPCIÓN, debido básicamente a que una asignatura es inscrita por un ESTUDIANTE y un estudiante inscribe una ASIGNATURA. Es importante reconocer que a simple vista las asociaciones permiten la comunicación y el paso de información entre un objeto y otro, pero no por ello se debe estar de acuerdo con las personas que argumentan que las asociaciones violan el principio de encapsulación de información propio de la programación orientada a objetos. Esto lo digo porque es probable que una asociación tenga atributos inherentes a ésta que no se puedan adjudicar directamente a cualquiera de las clases involucradas. Pero bueno, veamos en primera medida la solución al diagrama anterior: // Archivo: ASIGNATURA.java public class ASIGNATURA { private Integer COD_ASIGN; private String NOM_ASIGN; public ESTUDIANTE inscribe[]; ASIGNATURA() { } } // Archivo: ESTUDIANTE.java public class ESTUDIANTE { private Integer COD_ESTU; private String NOM_ESTU; public ASIGNATURA tomada_por[]; ESTUDIANTE() { } } 9.7. LAS AGREGACIONES Se dice que entre dos objetos hay una relación de agregación cuando uno es parte de otro. En general la relación de agregación es un tipo de asociación pero más fuerte, dado por el carácter de una relación de composición de algo en partes que son otras clases. Para comprender estos conceptos, a continuaciones muestra un ejemplo con las partes de un computador. Veamos: La implementación del anterior diagrama se muestra a continuación en donde se especifica el contenido y el nombre de cada archivo de java que es necesario crear para implementar el anterior diagrama: // Archivo: COMPUTADOR.java public class COMPUTADOR { private Integer COD_COMP; private String NOM_COMP; public public public public MONITOR muestra; TECLADO manipula; CPU procesa; IMPRESORA imprime[]; COMPUTADOR() { } } Un COMPUTADOR está relacionado con cero a un monitor por medio del rol muestra. Un COMPUTADOR está relacionado con cero o una CPU por medio del rol procesa Un COMPUTADOR está relacionado con cero o un TECLADO por medio del rol manipula. Un COMPUTADOR está relacionado con cero o varias EMPRESORAS // Archivo: CPU.java public class CPU { private Integer COD_CPU; private String NOM_CPU; public COMPUTADOR envia2; CPU() { } } Una CPU, está relacionada con uno y con sólo un COMPUTADOR por medio del rol envia2 // Archivo: IMPRESORA.java public class IMPRESORA { private Integer CO_IMPR; private String NOM_IMP; public COMPUTADOR envia4; IMPRESORA() { } } Una IMPRESORA, está relacionada con cero o un COMPUTADOR por medio del rol envia4 // Archivo: MONITOR.java public class MONITOR { private Integer COD_MON; private String NOM_MON; public COMPUTADOR envia1; MONITOR() { } } Un MONITOR está relacionado con cero o un COMPUTADOR, por medio del rol envia1 // Archivo: TECLADO.java public class TECLADO { private Integer COD_TECL; private String NOM_TECL; public COMPUTADOR envia3; TECLADO() { } } Un TECLADO está relacionado con cero o un COMPUTADOR por medio del rol envia3 9.8. RELACIONES DE DEPENDENCIA Los archivos en java que implementan el anterior diagrama son: // Archivo: ESTUDIANTE.java public class ESTUDIANTE { private Integer COD_ESTU; private String NOM_ESTU; public NOTA tomada_por[]; ESTUDIANTE() { } } // Archivo: NOTA.java public class NOTA { private Integer COD_NOTA; private Integer VALOR_NOTA; private String DESCRIPCION; public ESTUDIANTE inscribe[]; NOTA() { } } Observemos que los valores que determinan la cardinalidad se pueden especificar más adelante a medida que se vayan creando los diversos objetos. A las dependencias en muchas ocasiones se les conoce como relaciones de uso y esto se debe a que son utilizadas comúnmente para especificar que una clase utiliza a otra para realizar determinadas operaciones y obviamente la clase que usa a la otra es una clase que depende de la inicial. En términos gráficos, la situación se puede comprender de la siguiente manera: COORDINACIÓN COORDINADOR Dependencia Un cambio en el coordinador afecta a la coordinación, es decir la coordinación depende del coordinador. (Bueno, en la vida real, la coordinación depende también de muchos otros elementos y de muchas clases como se diría en programación orientada a objetos). La situación anterior, indicaría por tanto, alguna de las siguientes situaciones: o Existe una función en la clase COORDINACIÓN que utiliza un objeto de tipo COORDINADOR para realizar alguna operación. o Existe una función que recibe un parámetro por valor en la clase COORDINACIÓN, que es una instanciación de la clase COORDINADOR. 9.9. HERENCIA MÚLTIPLE EN JAVA La herencia múltiple en java no está permitida. En términos sencillos la herencia múltiple hace referencia a la capacidad de una clase de heredar de dos o más clases. 10. ESTEREOTIPOS DE LAS CLASES EN UML 2.0 Los estereotipos de las clases son distintos a los tipos de clases. En esta sección se muestran los estereotipos de las clases según la versión 2.0 de UML. No existen mas estereotipos, con lo cual si se colocan estereotipos distintos se podría hacer a menos que se especifique en alguna parte del documento que están haciendo extensiones al lenguaje UML, que esto es valido, pero siempre y cuando se especifique en el documento. 10.1. LAS CLASES CON ESTEREOTIPO VIEW Clases como la siguiente: ConsultaEstudiantesEx celentes Son clases consulta. Es decir que se están relacionadas con consultas a bases de datos que se hacen en el sistema. La anterior tabla también se pude modelar como se muestra a continuación: <<<<View>>>> ConsultaEstudiantes Excelentes 10.2. LAS CLASES CON ESTEREOTIPO TABLE Clases como la siguiente: Estudiante Son clases tabla. Es decir que estas clases tienen su equivalente en una base de datos y son clases que manipulan la información de una tabla de una base de datos. También se puede dibujar la anterior clase de la siguiente forma: <<<<Table>>>> Estudiante 10.3. LAS CLASES CON ESTEREOTIPO SERVICE La siguiente clase es una clase tipo “Service”. Estudiante Se usa cuando se quiere modelar una clase que globalice un servicio. Esto puede ser útil tanto en la parte del modelo del dominio como en cualquier diagrama de clases de análisis o de diseño. De forma análoga a las anteriores clases, es posible diagramar la clase con la convención que siempre usamos para las clases que es un cuadro dividido en tres secciones, pero adicionándole la etiqueta <<service>>. <<<<Service>>>> Estudiante 10.4. LAS CLASES CON ESTEREOTIPO RESOURCE Se usan para especificar que guardan relación estrecha con un recurso o para especificar que manipulan algún recurso. Se pueden diagramar así: Estudiante O también se pueden diagramar así: <<<<Resource>>>> Estudiante 10.5. OTROS ESTEREOTIPOS DE CLASES En la siguiente tabla resumimos los diversos estereotipos de clases que faltan por explicar y hacemos un breve comentario de su uso. FORMA DIAGRAMAR LA CLASE SIN EL ESTEREOTIPO FORMA DE DIAGRAMAR LA CLASE CON EL ESTEREOTIPO BREVE EXPLICA CION Trabajador <<<<Physical Worker>>>> físico Estudiante Estudiante <<<<Location>>>> Edificio Clase que especifica una localizació n Edificio <<<<Interface>>>> Edificio Interface <<<<entity>>>> Edificio Entity. Especifica que es una entidad. <<<<Domain>>>> Mundo Domain. Generalme nte son clases que aparecen en el dominio del problema. Control Edificio Edificio Mundo <<<<control>>>> Mundo Mundo Business <<<<Business Worker>>>> Worker Mundo Mundo <<<<Business Goal>>>> Business Goal. Mundo Meta de negocio Mundo <<<<Business Event>>>>Business Event. Mundo Evento de negocio. Mundo <<<<Business Entity>>>>Business Entity. Mundo Entidad e negocio. Mundo Business <<<<Business Document>>>> Document. Mundo Document o de negocio Mundo <<<<Business Actor>>>>Business Actor. Mundo Actor de negocio Mundo <<<<boundary>>>> Mundo Boundary <<<<Actor>>>> Mundo Actor. Esta clase es mas comúnmen te modelada con la figura similar a la humana Mundo Mundo 11. DIAGRAMAS DE CLASE Y CONCEPTOS Una bonita definición de lo que es un diagrama de clases, se encuentra en el libro de “UML Gota a gota” de Martin Fowler, la cual se muestra a continuación: “Un diagrama de clases describe los tipos de objetos que hay en el sistema y las diversas clases de relaciones estáticas que existen entre ellos. Los diagramas de clases también muestran los atributos y operaciones de una clase y las restricciones a que se ven sujetos, según la forma en que se conecten los objetos”. Existen tres perspectivas para dibujar diagramas de clase, tal como se muestra en la siguiente figura: Perspectiva Conceptual Perspectiva Especificación Perspectiva Implementación Con el diagrama anterior la pirámide lo que indica es el nivel de abstracción del sistema, en la cúspide se encuentra el nivel de abstracción mas grande, es decir un primer bosquejo de la vista estática del sistema y a este primer bosquejo se le conoce con el nombre de diagrama de clases desde la perspectiva conceptual. En el segundo nivel, es decir un nivel mas detallado de la estructura estática del sistema se encuentra la perspectiva de especificación, por lo general en esta vista se pone mas énfasis en cuales serán las interfaces del sistema y no tanto la forma como se implementaran estas interfaces, y en un tercer nivel se encuentra la vista mas detallada de especificación en la que se encuentra el diagrama de clases desde la perspectiva de implementación, el cual es un diagrama que brinda no solo las interfaces, sino también un bosquejo de las implementaciones de la mismas. 11.1. CASO 1: CUANDO NO SE PUEDE COLOCAR ESPECIFICADOR DE ACCESO A UNA CLASE Una clase que este al interior de un método publico no puede tener especificador de acceso. Por ejemplo el siguiente programa: public class MyApp { public MyApp() { saludar(); } public void saludar(){ class ClaseInterna{ } // Cierra class ClaseInterna } // Cierra metodo1() public static void main(String args[]) { MyApp f = new MyApp(); } } No produce error alguno, pero si le colocamos el especificador de acceso a la clase “ClaseInterna”, es decir agregamos la palabra “public” de tal forma que el programa anterior quede como se muestra a continuación: public class MyApp { public MyApp() { saludar(); } public void saludar(){ public class ClaseInterna{ } // Cierra class ClaseInterna } // Cierra metodo1() public static void main(String args[]) { MyApp f = new MyApp(); } } Obtenemos un error similar al siguiente cuando se compila: D:\MyApp.java:9: illegal start of expression public class ClaseInterna{ ^ D:\MyApp.java:14: class, interface, or enum expected public static void main(String args[]) ^ D:\MyApp.java:17: class, interface, or enum expected } ^ 3 errors NOTA: Cuando se dice que no se puede colocar especificador de acceso a una clase interna a un método, es porque no se puede colocar “protected”, “private”, ni “public”, a pesar que cuando no se coloca, se asume que es tipo “public”, pero explícitamente no se puede colocar. 11.2. ASOCIACIONES CON CARDINALIDAD FINITA Cuando se habla de asociaciones entre clases se esta refiriendo a la relación entre dos clases. Supongamos dos clases, la clase “SALON” y la clase “SILLA” y digamos que estas dos clases tienen una relación de cardinalidad finita “10”, tal como se muestra en la siguiente figura: 10 SALON SILLA mueblePertecenaAUn Decimos que el nombre “mueblePertecenaAUn” es el nombre que a nivel de código se le dará al objeto de la clase “SILLA”. En realidad el siguiente programa: public class MyApp { public class SALON{ private SILLA mueblePerteneceAUn[]; public SALON(){ mueblePerteneceAUn = new SILLA[10]; } // Cierra constructor SALON } // Cierra class SALON public class SILLA{ } // Cierra class SILLA public MyApp(){ } // Cierra MyApp public static void main(String args[]){ MyApp f = new MyApp(); } } // Cierra class MyApp Implementa la relación de cardinalidad finita al interior de otra clase llamada la clase “MyApp”, tal como lo muestra la siguiente figura: SALON MYAPP 10 mueblePertecenaAUn SILLA NOTA: En los ejemplos del presente material, la mayoría de las veces no se tendrá en cuenta la clase contenedora, en caso de tenerse en cuenta se hará la correspondiente aclaración. El diagrama de clases del ejercicio elaborado en esta seccion es similar al siguiente: 11.3. ASOCIACIONES CON CARDINALIDAD INFINITA Podemos hacer una pequeña modificación al programa de la sección anterior para que permita especificar una cardinalidad en la cual un objeto de la clase “SALON”, se pueda relacionar con un numero variable e indeterminado de objetos tipo “SILLA”. La modificación es simplemente asociar el objeto tipo “SILLA” a un vector, tal como se muestra en el siguiente programa: import java.util.Vector; public class MyApp { public class SALON{ private Vector mueblePerteneceAUn; public SALON(){ mueblePerteneceAUn = new Vector(); } // Cierra constructor SALON } // Cierra class SALON public class SILLA{ } // Cierra class SILLA public MyApp(){ } // Cierra MyApp public static void main(String args[]){ MyApp f = new MyApp(); } } // Cierra class MyApp De tal forma que el programa anterior se pueda modelar de la siguiente manera: SALON * SILLA mueblePertecenaAUn NOTA: Observe amigo lector / estudiante que en este caso, la variable “mueblePerteneceAUn” se les puede asignar elementos que no necesariamente sean de tipo “SILLA” y esto se debe a que la clase “Vector” de Java, permite que se le coloque un objeto de cualquier tipo. Esta situación se puede corregir, al recuperar los elementos, en los cuales se haría necesario hacerle casting al objeto que devuelve el vector a un objeto tipo “SILLA”, cosa muy común con el manejo de este tipo de vectores. El diagrama de clases de lo hecho hasta el momento es el siguiente: A continuación se muestra una implementación de los métodos necesarios para añadir objetos tipo “SILLA” a un objeto “SALON” y para Mostar los objetos del vector con el método “mostrarElementos()”. import java.util.Vector; public class MyApp { public class SALON{ private Vector mueblePerteneceAUn; public SALON(){ mueblePerteneceAUn = new Vector(); } // Cierra constructor SALON public void anadir(SILLA objeto){ try{ mueblePerteneceAUn.addElement(objeto); } catch(Exception e){ System.out.println("Errores ingresando"); } // Cierra catch } // Cierra public void anadir() public void mostrar(){ int numeroElementos; numeroElementos = mueblePerteneceAUn.size(); int contador = 0; while(contador<numeroElementos){ SILLA objetoReferenciaSilla = (SILLA)mueblePerteneceAUn.elementAt(contador); System.out.println(objetoReferenciaSilla.toString()); } // Cierra while } // Cierra public void mostrar() } // Cierra class SALON public class SILLA{ } // Cierra class SILLA public MyApp(){ } // Cierra MyApp public static void main(String args[]){ MyApp f = new MyApp(); } } // Cierra class MyApp Obviamente para probar por completo el código anterior se requiere invocar los métodos “anadir()” y “mostrar()”, lo cual no es el objetivo de la presente explicación. NOTA: La palabra infinito, es una forma de decir que acepta relaciones de 1 a “N”, donde “N” puede tomar diversos valores, pero en verdad si el numero fuera infinito en el estricto sentido de la palabra, no seria capaz de procesar esta información, por cuanto tocaría crear infinitos objeto, cosa imposible en cualquier sistema informático. 11.4. CLASES TIPO UTILITY Una clase es de tipo utilitario cuando sus variables y métodos son estáticas. Por ejemplo para que la siguiente clase sea “utility”: <<utility>> Aritmetica sumar() restar() multiplicar() divider() Tendríamos que crear un archivo llamado “Aritmetica.java” que contenga un código similar al siguiente: Archivo Aritmetica.java public class Aritmetica{ public static int resultado; public static void sumar(int a, int b){ resultado = a + b; } // Cierra static void sumar() public static void restar(int a, int b){ resultado = a - b; } // Cierra static void restar() public static void multiplicar(int a, int b){ resultado = a * b; } // Cierra static void multiplicar() public static void dividir(int a, int b){ resultado = (int)(a / b); } // Cierra static void dividir() public static void imprimirResultado(){ System.out.println(resultado); } // Cierra static void imprimirResultado() } // Cierra public class Aritmetica En donde podemos apreciar que esta clase tiene solo atributos y métodos estáticos. Ahora bien, para probar la clase anterior creamos un programa principal que tenga un código similar al siguiente: Archivo MyApp.java import java.util.Vector; public class MyApp { public MyApp(){ Aritmetica.sumar(2,6); Aritmetica.imprimirResultado(); Aritmetica.restar(2,6); Aritmetica.imprimirResultado(); Aritmetica.multiplicar(6,5); Aritmetica.imprimirResultado(); Aritmetica.dividir(16,3); Aritmetica.imprimirResultado(); } // Cierra MyApp public static void main(String args[]){ MyApp f = new MyApp(); } } // Cierra class MyApp Que presentara los resultados al momento de su ejecución: 8 -4 30 5 Exit code: 0 Con lo cual vemos que no hubo necesidad de crear un objeto de tipo “Aritmetica”, sino que simplemente invocando los métodos directamente de esta clase se puede usar esta. Un utilitario es algo que se puede usar sin necesidad de estar creando objetos de clases, sino invocando directamente sus métodos y modificando o invocando sus atributos directamente. NOTA: Podemos verificar que la clase utilitaria que creamos no se puede colocar en forma interna al programa principal porque generaría error. Esta situación se explicara en detalle en la siguiente sección. 11.5. LAS CLASES UTILITARIAS NO PUEDEN ESTAR CONTENIDAS EN OTRAS Supongamos la clase utilitaria “Aritmetica” de la sección anterior: Archivo Aritmetica.java public class Aritmetica{ public static int resultado; public static void sumar(int a, int b){ resultado = a + b; } // Cierra static void sumar() public static void restar(int a, int b){ resultado = a - b; } // Cierra static void restar() public static void multiplicar(int a, int b){ resultado = a * b; } // Cierra static void multiplicar() public static void dividir(int a, int b){ resultado = (int)(a / b); } // Cierra static void dividir() public static void imprimirResultado(){ System.out.println(resultado); } // Cierra static void imprimirResultado() } // Cierra public class Aritmetica Al incluirla dentro del programa principal tendríamos un programa similar al siguiente: Archivo MyApp.java import java.util.Vector; public class MyApp { public class Aritmetica{ public static int resultado; public static void sumar(int a, int b){ resultado = a + b; } // Cierra static void sumar() public static void restar(int a, int b){ resultado = a - b; } // Cierra static void restar() public static void multiplicar(int a, int b){ resultado = a * b; } // Cierra static void multiplicar() public static void dividir(int a, int b){ resultado = (int)(a / b); } // Cierra static void dividir() public static void imprimirResultado(){ System.out.println(resultado); } // Cierra static void imprimirResultado() } // Cierra public class Aritmetica public MyApp(){ Aritmetica.sumar(2,6); Aritmetica.imprimirResultado(); Aritmetica.restar(2,6); Aritmetica.imprimirResultado(); Aritmetica.multiplicar(6,5); Aritmetica.imprimirResultado(); Aritmetica.dividir(16,3); Aritmetica.imprimirResultado(); } // Cierra MyApp public static void main(String args[]){ MyApp f = new MyApp(); } } // Cierra class MyApp Y podemos constatar el compilarlo que tenemos unos errores similares a los siguientes: D:\MyApp.java:6: inner classes cannot have static declarations public static int resultado; ^ D:\MyApp.java:8: inner classes cannot have static declarations public static void sumar(int a, int b){ ^ D:\MyApp.java:12: inner classes cannot have static declarations public static void restar(int a, int b){ ^ D:\MyApp.java:16: inner classes cannot have static declarations public static void multiplicar(int a, int b){ ^ D:\MyApp.java:20: inner classes cannot have static declarations public static void dividir(int a, int b){ ^ D:\MyApp.java:24: inner classes cannot have static declarations public static void imprimirResultado(){ ^ 6 errors Exit code: 1 There were errors 11.6. LAS AGREGACIONES En forma teórica una agregación es una forma de asociación, en la cual se esta diciendo que la relación entre dos clases es del tipo “todo/parte”. Si queremos hacer una relación de este tipo dado que UML no es bien claro en este tipo de relaciones podríamos hacerla como se muestra en el siguiente programa: Archivo MyApp.java import java.util.Vector; public class MyApp { public class COMPUTADOR{ private TECLADO tecladoPerteneceAUn[]; private PANTALLA pantallaPerteneceAUn[]; private Vector procesadorPerteneceAUn; public COMPUTADOR(){ tecladoPerteneceAUn = new TECLADO[1]; pantallaPerteneceAUn = new PANTALLA[1]; procesadorPerteneceAUn = new Vector(); } // Cierra constructor COMPUTADOR } // Cierra class COMPUTADOR public class TECLADO{ } // Cierra class TECLADO public class PANTALLA{ } // Cierra class PANTALLA public class PROCESADOR{ } // Cierra class PROCESADOR public MyApp(){ } // Cierra MyApp public static void main(String args[]){ MyApp f = new MyApp(); } } // Cierra class MyApp Y estaríamos implementando el siguiente diagrama de clases: COMPUTADOR TECLADO PANTALLA PROCESADOR Pero si el amigo lector / estudiante examina detenidamente la implementación mostrada anteriormente puede comprobar que la relación entre “COMPUTADOR” y “TECLADO” es una relación de asociación finita, que la relación entre “PANTALLA” y “COMPUTADOR” es una relación también es una relación de asociación finita y que la relación entre “PROCESADOR” y “COMPUTADOR” es una relación de asociación no finita. Con lo cual podemos concluir que no es bien claro como implementar la lógica en la cual un computador esta formado por teclado, pantalla y procesador(es). Fijémonos que UML no es bien claro en la implementación de este tipo de asociaciones de agregación y da al programador libertad para que haga implementaciones como las siguientes: Archivo MyApp.java import java.util.Vector; public class MyApp { public class COMPUTADOR{ private private private private TECLADO teclado1; PANTALLA pantalla1; PROCESADOR procesador1; PROCESADOR procesador2; public class TECLADO{ } // Cierra class TECLADO public class PANTALLA{ } // Cierra class PANTALLA public class PROCESADOR{ } // Cierra class PROCESADOR public COMPUTADOR(){ teclado1 = new TECLADO(); pantalla1 = new PANTALLA(); procesador1 = new PROCESADOR(); procesador2 = new PROCESADOR(); } // Cierra constructor COMPUTADOR } // Cierra class COMPUTADOR public MyApp(){ } // Cierra MyApp public static void main(String args[]){ MyApp f = new MyApp(); } } // Cierra class MyApp Y tal vez, el no ser tan claro en implementar las agregaciones fue lo que motivo a que en UML 2.0 se halla eliminado este tipo de relaciones. 11.7. EN LAS AGREGACIONES UN TODO NO PUEDE SER UNA PARTE DE SI MISMO En la sección anterior veíamos que las agregaciones han sido eliminadas de UML 2.0, pero de todas formas, a modo personal no es tan malo usar relaciones de agregación en algunos casos. Diría que este tipo de relaciones dan una orientación del sentido que se le quiere dar a la asociación y para aquellas personas que deseen seguir usando relaciones de agregación en sus modelos UML, les muestro a continuación algunas relaciones de agregación no validas para implementar. En esta sección comenzamos diciendo que “un todo no puede ser al mismo tiempo una parte”. Para explicar esta parte veamos el siguiente diagrama: CHIP Y una posible implementación seria como la mostrada a continuación: Archivo MyApp.java import java.util.Vector; public class MyApp { public class CHIP{ private CHIP chip1; public CHIP(){ chip1 = new CHIP(); } // Cierra constructor COMPUTADOR } // Cierra class COMPUTADOR public MyApp(){ CHIP objetoChip = new CHIP(); } // Cierra MyApp public static void main(String args[]){ MyApp f = new MyApp(); } } // Cierra class MyApp A pesar que el programa anterior compila, genera un error en tiempo de ejecución muy similar al siguiente: at MyApp$CHIP.<init>(MyApp.java:8) at MyApp$CHIP.<init>(MyApp.java:8) at MyApp$CHIP.<init>(MyApp.java:8) at MyApp$CHIP.<init>(MyApp.java:8) at MyApp$ en el cual la línea del error se repite demasiadas veces, hasta que la maquina virtual se da cuanta que una redundancia infinita y aborta el programa. 11.8. CICLO ILEGAL DE AGREGACION ENTRE DOS INSTANCIAS DE DISTINTA CLASE Este es otro ejemplo de relaciones de agregación no validas. Veamos primero el siguiente diagrama de clases: A B La implementación del anterior diagrama se puede hacer de la siguiente forma: Archivo MyApp.java import java.util.Vector; public class MyApp { public class A{ private B objetoB; public A(){ objetoB = new B(); } // Cierra constructor A } // Cierra class A public class B{ private A objetoA; public B(){ objetoA = new A(); } // Cierra constructor B } // Cierra class B public MyApp(){ B objeto = new B(); } // Cierra MyApp public static void main(String args[]){ MyApp f = new MyApp(); } } // Cierra class MyApp Y pesar de no obtener errores en tiempo de compilación, si se presentan errores en tiempo de ejecución. El error que se nos presento al ejecutar el siguiente programa fue similar al siguiente: at MyApp$B.<init>(MyApp.java:15) at MyApp$A.<init>(MyApp.java:8) at MyApp$B.<init>(MyApp.java:15) at MyApp$A.<init>(MyApp.java:8) at MyApp$B.<init>(MyApp.java:15) at MyApp$A.<init>(MyApp.java:8) at MyApp$B.<init>(MyApp.java:15 Este error se presenta debido a que en tiempo de ejecución se detectan dos líneas que causan problemas, las cuales se muestran en negrilla en el siguiente código: Archivo MyApp.java import java.util.Vector; public class MyApp { public class A{ private B objetoB; public A(){ objetoB = new B(); } // Cierra constructor A } // Cierra class A public class B{ private A objetoA; public B(){ objetoA = new A(); } // Cierra constructor B } // Cierra class B public MyApp(){ B objeto = new B(); } // Cierra MyApp public static void main(String args[]){ MyApp f = new MyApp(); } } // Cierra class MyApp 11.9. DIAGRAMAS DE CLASES DE EJEMPLOS Con el animo de acercar al amigo lector / estudiante a tener un pensamiento orientado a objetos a continuación se muestran algunos conceptos en parejas, después de lo cual se debe intentar colocar el tipo de relacion que se le asignaria a dichos objetos con el fin de finalmente establecer un pequeño diagrama de clases entre estas parejas de conceptos. Comencemos mostrando los conceptos: CONCEPTO 1 Zapato Una Una Estudiante Mesa Comedor Madre Auto Auto Carro CONCEPTO 2 Pie Mugre Dedo Profesor Florero Silla Bebe Motor Radio Gris Basados en los conceptos anteriores detallaremos en forma textual y con palabras como se relaciona el concepto 1 con el concepto 2. CONCEPTO 1 CONCEPTO 2 Zapato Pie Una Mugre Una Dedo COMO SE RELACIONAN LOS CONCEPTOS Los pies se protegen con los zapatos al momento de caminar y los zapatos se fabrican a la medida para ser colocados en los pies. Las unas cuando quedan grandes, tienden a atrapar mugre, pareciera que lo generan pero lo que hacen es acumularlo. Cuando el mugre se adhiere a la una y no se busca el mecanismo para quitarlo, se dice que la una esta sucia Las unas crecen siempre y cuando existan dedos y un dedo que no tiene una es un dedo desprotegido, tambien la accion de quitarle la una al dedo puede ser tomada como corte de una o como desmadrarse una una, dependiendo si la cantidad de la una que se va a quitar es mayor que la disponible para Estudiante Profesor Mesa Florero Comedor Silla Madre Bebe Auto Motor Auto Radio Carro Gris quitar. Los profesores llegan a ser profesores cuando han estudiado bastante, un profesor le dicta clases a un estudiante y los estudiantes reciben clases de los profesores. No todo profesor puede relacionarse desde el punto de vista academico con cualquier estudiante, sino que se requiere que tengan afinidad de carrera o que el estudiante este cursando una materia que sea de dominio del profesor. Los floreros se colocan casi siempre sobre las mesas y las mesas sostienen los objetos que se colocan sobre ella, entre ellos a los floreros. Los comedores estan por lo general conformados por sillas y mesas. Comúnmente son varias sillas las que forman un comedor. Las Madres dan a luz a los bebes, es decir que los bebes nacen gracias a que las madres lo desean. Los bebes duran aproximadamente 9 meses en el vientre de las Madres y poco a poco van siendo independientes. El ser bebe se va perdiendo con el tiempo y cuando ha pasado mucho tiempo incluso los bebes se convierten en madres. Los autos estan compuestos por una serie de partes entre las que figuran los motores y a veces parece que el autor depende de algunas partes tanto que si el motor del carro no existe o no funciona correctamente el carro no funciona correctamente. Los autos pueden llevar radios, pero si no los llevan siguen siendo radios. Es importante notar que los radios son llamados accesorios del auto. Los carros pueden tener cualquier color. El color gris es uno de los tantos colores que puede tener un carro. Mas que el carro se asocie con un color gris es que el color gris es una propiedad del carro. Ahora partiendo del texto sobre como se relacionan los conceptos anteriores, vamos a llenar la siguiente tabla en la que se coloca con una equis si se especifica que existe la relacion de asociación, composición, agregación o dependencia. Veamos pues la tabla: CONCEP TO 1 Zapato Una Una Estudiante Mesa Comedor Madre Auto Auto Carro CONCEP TO 2 Pie Mugre Dedo Profesor Florero Silla Bebe Motor Radio Gris ASOCIACI ÓN X X X X X X X X X COMPOSIC IÓN AGREGACI ÓN DEPENDEN CIA X X X X X X Con la anterior tabla podemos plantear los diagramas de clase para cada pareja. DIAGRAMA DE CLASE PARA PAREJA ZAPATO PIE ZAPATO PIE DIAGRAMA DE CLASE PARA PAREJA UNA MUGRE UNA MUGRE DIAGRAMA DE CLASE PARA PAREJA UNA DEDO UNA DEDO DIAGRAMA DE CLASE PARA PAREJA ESTUDIANTE PROFESOR ESTUDIANTE PROFESOR DIAGRAMA DE CLASE PARA PAREJA MESA FLORERO MESA FLORERO DIAGRAMA DE CLASE PARA PAREJA COMEDOR SILLA COMEDOR SILLA DIAGRAMA DE CLASE PARA PAREJA MADRE BEBE MADRE BEBE DIAGRAMA DE CLASE PARA PAREJA AUTO MOTOR AUTO MOTOR DIAGRAMA DE CLASE PARA PAREJA AUTO RADIO AUTO RADIO DIAGRAMA DE CLASE PARA PAREJA CARRO GRIS 12. P.O.O. EN JAVA Y CLASES ABSTRACTAS 12.1. LAS CLASES ABSTRACTAS TIPO DE CLASE abstract interface COMO UTILIZARLA Extends implements Las clases tipo abstract, son clases que describen como se tienen que declarar los métodos, sin tener que implementarlos. Es más, si los métodos son declarados abstract en una clase abstract, es porque no pueden ser implementados en la misma clase, sino en una clase que herede de la misma. Otra cuestión bien importante a tener en cuenta es el hecho que una clase que herede de una clase tipo abstract, está obligada a implementar todos los métodos que la clase antecesora en cuestión tenga definidos como de tipo abstract. Para lograr que el amigo lector / estudiante comprenda estos conceptos a continuación se muestra un ejercicio que muestra dos archivos en cada uno de los cuales hay una clase. Estos archivos describen en forma sencilla la forma de crear una clase abstracta y la forma de utilizarla. Veamos: // Archivo: uml1.java package uml2; import java.awt.*; import java.awt.event.*; public abstract class uml1 { public abstract void printf(); } // Archivo: MyApp.java package uml2; import java.awt.*; import java.awt.event.*; public class MyApp extends uml1{ public void printf(){ System.out.println("probando"); } } Observe el amigo lector que la implementación del método “printf()” es obligatoria en la clase “MyApp” 12.2. CASO 1: SOBRE LAS CLASES ABSTRACTAS Veamos el siguiente programa que genera un error: import java.applet.*; public class MyApp extends Applet { public abstract class padre{ public int estatura(){ return 5; } } } padre obj_padre = new padre(); // Cierra public class MyApp El error dependiendo el compilador java es algo similar al siguiente: MyApp.padre is abstract; cannot be instantiated padre obj_padre = new padre(); 1 error Exit code: 1 There were errors Las clases abstractas no pueden ser instanciadas directamente, pues fueron creadas para que otras hereden de ellas y éstas últimas si pueden ser instanciadas. 12.3. CASO 2: SOBRE LAS CLASES ABSTRACTAS El siguiente programa es totalmente válido. Veamos: import java.applet.*; public class MyApp extends Applet { public abstract class padre{ public int estatura(){ return 5; } } public class hijo extends padre{ } hijo obj_hijo = new hijo(); } // Cierra public class MyApp Una clase no abstracta que herede de una clase abstracta puede ser instanciada directamente 12.4. CASO 3: SOBRE LAS CLASES ABSTRACTAS Observemos el siguiente programa: import java.applet.*; public class MyApp extends Applet { public abstract class bisabuelo{ public int estatura(){ return 5; } } public class abuelo extends bisabuelo{ } public abstract class padre extends abuelo{ } public class hijo extends padre{ } public abstract class nieto extends hijo{ } abuelo obj_abuelo = new abuelo(); hijo obj_hijo = new hijo(); } // Cierra public class MyApp El programa anterior es totalmente válido debido a que la clase “bisabuelo” es una clase abstracta, pero su función “estatura()” no lo es, lo que quiere decir que una clase que herede de la clase “bisuabuelo”, no está obligada a implementar el método “estatura()”. De otra parte la clase “abuelo” hereda de bisabuelo y no por ello está obligada a ser una clase abstracta. En últimas vemos que el árbol de herencia puede seguirse prolongando hasta que no aparezca el identificador “final” (el cual se explicará más adelante.). Por último vemos que las únicas clases que se están instanciando directamente son las clases “abuelo” e “hijo”, quienes no son abstractas y por lo tanto es perfectamente válido instanciarlas. Una clase abstracta puede heredar de una abstracta o de una no abstracta. Una clase no abstracta puede heredar de una clase abstracta o de una no abstracta. 12.5. CASO 4: SOBRE LAS CLASES ABSTRACTAS Observemos el siguiente ejercicio: import java.applet.*; public class MyApp extends Applet { public abstract class padre{ public int estatura(){ return 161; // cm } } public abstract class madre{ public int estatura(){ return 154; // cm } } } public class hijo extends padre extends madre{ } // Cierra public class MyApp El programa anterior genera un error, debido a que no es posible hacer una clase que herede de dos clases abstractas. El error que genera al anterior programa al compilarlo es similar al siguiente: '{' expected public class hijo extends padre extends madre{ Aunque muchos compiladores no colocan explícito el error de intentar heredar simultáneamente de dos clases mediante la palabra reservada “extends”, es importante tener en cuenta que no es posible heredar de dos clases abstractas al mismo tiempo debido a que por este mecanismo no se permite la herencia múltiple. 12.6. CASO 5: SOBRE LAS CLASES ABSTRACTAS Observemos el siguiente programa que define una clase abstracta denominada padre: import java.applet.*; public class MyApp extends Applet { public abstract class padre{ public abstract int estatura(){ return 161; // cm } } } // Cierra public class MyApp Como podemos observar en este programa, se crea una clase abstracta llamada “padre”, la cual define un método que devuelve un valor entero y dicho método se llama “estatura()”, el error surge porque se están abriendo y cerrando corchetes después del método lo cual estaría indicando que se va a implementar dicho método y recordemos que los métodos abstractos de una clase abstracta no se pueden implementar en dicha clase, sino en las clases que hereden de la misma. Algunas personas piensan que el error surge porque se están colocando instrucciones dentro del método. Pues para las personas que piensan esto, veamos el siguiente programa: import java.applet.*; public class MyApp extends Applet { public abstract class padre{ public abstract int estatura(){ } } } // Cierra public class MyApp Vemos entonces que este programa también genera errores, y eso que no hay nada de instrucciones en medio de los corchetes. La razón es muy sencilla a pesar de no tener instrucciones en dicho método el solo hecho de colocar corchetes le está indicando a java que es posible colocar instrucciones y esto provoca un error. En los dos programas anteriores mostrados se presenta pues el mismo error, el cual es algo similar al siguiente: abstract methods cannot have a body public abstract int estatura(){ Las clases abstractas no pueden contener instrucciones y es más, ni siquiera deben tener corchetes de apertura y cierre, sino únicamente la sola definición (no declaración) del método seguido por un punto y coma. Para corregir el problema presentado en los dos anteriores programas se muestra un programa que declara el método abstracto en una clase abstracta pero que no da pie para su definición y mucho menos su implementación. Veamos: import java.applet.*; public class MyApp extends Applet { public abstract class padre{ public abstract int estatura(); } } // Cierra public class MyApp 12.7. CASO 6: SOBRE LAS CLASES ABSTRACTAS Observemos detenidamente el siguiente programa: import java.applet.*; public class MyApp extends Applet { public abstract class padre{ public abstract int estatura(); } } public class hijo extends padre{ } // Cierra public class MyApp El anterior programa define una clase abstracta denominada “padre”, la cual tiene un método abstracto llamado “estatura()”. El problema con este programa radica no en la clase “padre”, sino en la clase “hijo”, la cual hereda de la clase “padre”, pero no implementa el método abstracto “estatura()” proveniente de su clase ancestra. Por todo lo anterior a continuación se muestra el error generado por java al compilar el anterior programa: MyApp.hijo should be declared abstract; it does not define estatura() in MyApp.padre public class hijo extends padre{ Si una clase no abstracta hereda de una clase abstracta y dicha ancestra declara métodos abstractos, es obligación de la clase no abstracta definir los métodos abstractos de sus clases antecesoras. Para corregir el problema del programa anterior, a continuación se muestra la nueva definición de la clase “hijo” para lograr que el programa no tenga errores. Veamos: import java.applet.*; public class MyApp extends Applet { public abstract class padre{ public abstract int estatura(); } } public class hijo extends padre{ public int estatura(){ return 165; // cm } } // Cierra public class MyApp Es bueno que el amigo lector y/o estudiante tenga en cuenta que al definir el método abstracto en la clase que hereda de la clase abstracta se omite la palabra “abstract” en el método y el resto se deja igual. También es bueno que se tenga en cuenta que el abrir y cerrar corchetes en el método “estatura()” de la clase “hijo” es supremamente importante. Algunos estudiantes han preguntado si es obligatorio que se coloquen instrucciones en el método “estatura()” del programa anterior. La respuesta es que no. Y para comprobarlo, puede compilar el siguiente programa que no genera ningún error y que sintácticamente es correcto. Veamos: import java.applet.*; public class MyApp extends Applet { public abstract class padre{ public abstract void saludo(); } } public class hijo extends padre{ public void saludo(){ } } // Cierra public class MyApp Pero bueno, obviamente para lograr que esto funcionase, hubo necesidad de cambiar la declaración del método “saludo()” de la clase “padre”, con el ánimo de lograr que dicho método no devolviera un valor entero, porque el hacerlo obligaría a que al momento de definir el método “saludo()” en la clase hija fuera necesaria la instrucción “return” y de lo que se trataba era de mostrar que era posible definir métodos en la clase “hijo” que no tuvieran instrucciones algunas en medio de los corchetes de apertura y cierre de la función “saludo()”. 12.8. CASO 7: SOBRE LAS CLASES ABSTRACTAS Observemos el siguiente programa: import java.applet.*; public class MyApp extends Applet { public abstract class padre{ public abstract void saludo(); } public abstract class hijo extends padre{ public abstract void saludo1(); } } public class nieto extends hijo{ public void saludo1(){ } public void saludo(){ } } // Cierra public class MyApp En el anterior programa no se presenta error alguno, debido a que las clases abstractas pueden declarar métodos, y no están obligadas a declarar métodos abstractos de sus clases abstractas ancestras. Por ejemplo para este caso, la clase “hijo” declara un método abstracto llamado “saludo1()” y no está obligada a declarar el método abstracto “saludo()”, por ser ésta clase hija una clase también abstracta. De otra parte la clase llamada “nieto” como no es clase abstracta, está obligada a definir (no declarar) el método abstracto “saludo1()” de la clase “hijo” y además está obligada a definir el método abstracto “saludo()” de la clase “padre”, por ser una clase que implícitamente hereda de esta también. Recordemos que si “C” hereda de “B” y “B” hereda de “A”, implícitamente “C” hereda de “A”. Esto se podría pensar como una ley de transitividad en la herencia, pero bueno, no es el tema hablar en términos matemáticos de estos aspectos. Por lo pronto basta con que se entienda que para nuestro ejercicio, la clase “nieto” hereda implícitamente de “padre”. Las clases abstractas que hereden de otras clases abstractas pueden o no declarar métodos que tengan el mismo nombre y parámetros de sus clases abstractas antecesoras 12.9. CASO 8: SOBRE LAS CLASES ABSTRACTAS Observemos el siguiente programa: import java.applet.*; public class MyApp extends Applet { public abstract class padre{ public int estatura(); } } // Cierra public class MyApp Este programa genera un error similar al siguiente: missing method body, or declare abstract public int estatura(); La razón es que la clase abstracta “padre” posee un método llamado “estatura()”, el cual no es abstracto y por tanto no solamente debe declararse, sino definirse. Los métodos que no sean abstractos y que se encuentren en clases abstractas deben definirse y no solamente declararse. Para corregir el problema del programa anterior, se podría definir el método “estatura()” tal como se muestra en el siguiente programa: import java.applet.*; public class MyApp extends Applet { public abstract class padre{ public int estatura(){ return 165; }; } } // Cierra public class MyApp 13. P.O.O. EN JAVA Y LAS INTERFACES Como decíamos en secciones anteriores: TIPO DE CLASE Abstract Interface COMO UTILIZARLA Extends implements Una clase tipo abstract describe como se tienen que declarar los métodos, sin tener que implementarlos, pero tengamos en cuenta que la clase que va a implementar estos métodos es una clase que hereda de la clase abstract. En cambio cuando se declara una clase como de tipo interface y es utilizada por otra por medio de la instrucción implements, estamos dijéramos copiando los métodos de la clase interfaz a la clase que la implementa. Con ello, estamos pues evitando el problema de tener que heredar y esto obviamente será muy útil cuando veamos la necesidad de heredar de varias clases, no haremos esto, sino simplemente crearemos varias clases tipo interfaz y otras clases serán las que implementan la funcionalidad de las anteriores y así evitaremos el gran problema que describíamos en apartados anteriores: El problema que java no permite la herencia múltiple. Bien, y ahora con el ánimo de lograr que el amigo lector / estudiante adquiera la destreza para crear este tipo de clases, a continuación se muestra un ejercicio que tiene dos archivos cada uno con una clase, en donde habrá una clase que es de tipo interface y otra que la implementa. Veamos: // Archivo: MyApp.java package uml2; import java.awt.*; import java.awt.event.*; class MyApp implements uml1{ public void printf(){ System.out.println("probando"); } } // Archivo: uml1.java package uml2; import java.awt.*; import java.awt.event.*; public interface uml1 { public void printf(); } 13.1. LAS INTERFACES DEBEN INICIALIZAR SUS ATRIBUTOS El siguiente código es correcto // Esta clase no genera error public interface transporte{ public int posicion_x=2; public int posicion_y=0; } // Cierra interface transporte Debido a que inicializa el valor de las variables “posición_x” y “posición_y” con los valores 2 y 0 respectivamente Pero con el ánimo de lograr la mayor comprensión de este tema, por parte del estudiante a continuación se muestra un ejemplo que genera un error. Veamos: // ESTA CLASE GENERA UN ERROR public interface transporte{ public int posicion_x; public int posicion_y; } // Cierra interface transporte La razón por la que genera un error es debido básicamente a que en una interfaz se necesita que se le asigne un valor a cada una de las variables que se declaren en dicha clase. 13.2. EN LAS INTERFACES NO ES OBLIGATORIO MODIFICADORES DE ATRIBUTOS En las clases tipo interface, no es obligatorio colocar el modificador de cada uno de los atributos de una clase. Para mostrar este concepto a continuación se muestra una clase en la cual se tiene un primer atributo denominado “posición_x” con modificador y otro atributo denominado “posición_y” sin modificador. Veamos pues: // Esta clase no genera un error public interface transporte{ public int posicion_x=2; int posicion_y=0; } // Cierra interface transporte 13.3. EL MODIFICADOR DE ATRIBUTO POR DEFECTO ES PUBLIC EN LAS INTEFACES En el siguiente código: // Esta clase no genera un error public interface transporte{ public int posicion_x=2; // declara posicion_y como public int posicion_y=0; } // Cierra interface transporte Se deja en claro que el modificador por defecto en las interfaces es “public”. 13.4. EL MODIFICADOR DE ATRIBUTO PROTECTED NO ESTA PERMITIDO EN LAS INTERFACES En las interfaces se tiene una limitación en cuanto al modificador permitido para los atributos de dicha clase, por cuanto no se permite el modificador “protected”. A continuación se muestra una clase que genera un error por cuanto define un atributo con el modificador “protected”. Veamos pues: // ESTA CLASE GENERA UN ERROR public interface transporte{ public int posicion_x=2; // genera error por tener el // modificador protected protected int posicion_y=0; } // Cierra interface transporte 13.5. EL MODIFICADOR DE ATRIBUTO PRIVATE NO ESTA PERMITIDO EN LAS INTERFACES Otra limitación importante de las interfaces es que no permiten la declaración de atributos con el modificador private. Veamos entonces una clase que incurre en este error y que por tanto no permite que la aplicación por lo menos compile: // ESTA CLASE GENERA UN ERROR public interface transporte{ public int posicion_x=2; // genera error por tener el // modificador private private int posicion_y=0; } // Cierra interface transporte para corregir el problema necesitaríamos cambiarle el modificador private por el modificador public o de otra manera también podríamos quitarle el modificador debido a que como se mencionaba anteriormente el modificador por defecto para los atributos de una interfaces es público, con lo cual el quitarle el atributo bastaría para solucionar el problema de compilación. 13.6. UNA INTERFAZ NO PUEDE SER INSTANCIADA DIRECTAMENTE El término instanciación hace referencia a la posibilidad de crear objetos a partir de una clase, en este caso, a partir de una interfaz. Diremos entonces que no pueden existir objetos que se creen directamente a partir de una interfaz. El siguiente ejemplo muestra un error debido básicamente a ésta situación: /* Autor: Tipo: Clase: Descripción: Luis Felipe Wanumen Silva Orientación a objetos Interface Manipulación de clases tipo interface */ import java.awt.*; import java.awt.event.*; public class MyApp extends Frame { public MyApp() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); } // Esta clase no genera un error public interface transporte{ public int posicion_x=2; public int posicion_y=0; } // Cierra interface transporte public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(100,100); f.show(); // Aqui el compilador genera error porque // NO PUEDE INSTANCIAR LA INTERFACE // transporte transporte zorra = new transporte(); } } 13.7. UNA CLASE NO INTERFAZ PUEDE IMPLEMENTAR UNA CLASE INTERFAZ Recordemos que la implementación es un concepto análogo a la herencia, en cuanto a que se aplica a la forma en la que una clase puede heredar cuestiones establecidas en una clase base tipo interface. De otra parte, es bueno tener en cuenta que la clase que implementa la clase interface no necesita ser necesariamente interface. El siguiente ejemplo ilustra un caso de éxito en el que se define una clase denominada transporte tipo interface y una clase vaca que no es de tipo interface, pero que implementa una clase tipo interface y este programa según lo mencionado hasta el momento no genera ningún error. Veamos entonces el ejemplo: /* Autor: Tipo: Clase: Descripción: Luis Felipe Wanumen Silva Orientación a objetos Interface Manipulación de clases tipo interface 9 de Mayo de 2005 Fecha: */ import java.awt.*; import java.awt.event.*; public class MyApp extends Frame { // Esta clase no genera un error public interface transporte{ public int posicion_x=2; public int posicion_y=0; } // Cierra interface transporte // Esta clase se crea correctamente public class vaca implements transporte{ } // Cierra class vaca public MyApp() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); // YA NO HAY ERROR AL CREAR EL OBJETO vaca pintada = new vaca(); } public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(100,100); f.show(); } } 13.8. UNA CLASE INTERFAZ NO PUEDE IMPLEMENTAR UNA CLASE INTERFAZ Recordemos que cuando una clase implementa una clase interfaz, lo que se está diciendo implícitamente es que se contrae una obligación con la clase tipo interfaz. Dicha obligación consiste en el compromiso de implementar los métodos de la clase interfaz en la clase que la implementa. En otras palabras, la clase interfaz dice qué métodos se deben implementar o desarrollar en las clases que implementen dicha clase. De otra parte una clase interfaz, no desarrolla métodos, con lo cual no es posible que una clase interfaz implemente otra clase interfaz debido a que de una la responsabilidad de implementar los métodos le queda restringida por el simple hecho de ser la clase también una clase interfaz. A continuación se muestra un ejemplo en el que se un error debido a que se infringe con ésta norma de programación en java. Veamos: /* Autor: Tipo: Clase: Descripción: Luis Felipe Wanumen Silva Orientación a objetos Interface Manipulación de clases tipo interface 9 de Mayo de 2005 Fecha: */ import java.awt.*; import java.awt.event.*; public class MyApp extends Frame { // Esta clase no genera un error public interface transporte{ public int posicion_x=2; public int posicion_y=0; } // Cierra interface transporte // ESTA CLASE NO SE PUEDE CREAR // debido a que una interfaz no puede // implementar otra interfaz public interface vaca implements transporte{ } // Cierra class vaca public MyApp() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); } public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(100,100); f.show(); } } En caso de ser necesario que una clase interface adquiera la funcionalidad especificada en otra clase tipo interfaz, se puede observar el siguiente ítem que muestra como se solucionaría éste problema. 13.9. UNA CLASE INTERFAZ PUEDE EXTENDER DE UNA CLASE INTERFAZ En el ítem anterior, se tenía un problema tenaz, cuando una clase “interface” intentaba implementar otra clase “interface”. Pues bien, ahora se plantea la solución a éste tipo de problemas, y esto se hace diciendo en primera medida que una clase “interface” puede extender de una clase “interface”. Para aclarar este punto, veamos en primera medida el ejemplo: /* Autor: Tipo: Clase: Descripción: Luis Felipe Wanumen Silva Orientación a objetos Interface Manipulación de clases tipo interface 9 de Mayo de 2005 Fecha: */ import java.awt.*; import java.awt.event.*; public class MyApp extends Frame { // Esta clase no genera un error public interface transporte{ public int posicion_x=2; public int posicion_y=0; } // Cierra interface transporte // Esta clase se puede crear puesto que // UNA INTERFAZ PUEDE EXTENDER DE OTRA // interfaz public interface vaca extends transporte{ } // Cierra class vaca public MyApp() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); } public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(100,100); f.show(); } } Cuando se dice que una clase extiende, quiere decir que la clase hija adquiere la funcionalidad de la clase padre y en este caso la clase padre es una clase tipo “interface”, con lo cual la clase hija al extender dicha funcionalidad lo puede hacer debido a que ella misma también es una clase “interface”. 13.10. UNA CLASE NO INTERFAZ PUEDE IMPLEMENTAR VARIAS CLASES TIPO INTERFAZ En ocasiones se hace necesario que una clase implemente la funcionalidad especificada en más de una clase y esto es perfectamente válido en java, con lo cual se puede dar un simulacro de herencia múltiple a nivel de interfaz. A continuación se muestra un ejemplo en el que se tiene una clase denominada “vaca” que implementa de dos clases tipo “interface” denominadas “transporte” y “animal”. Veamos el ejercicio: /* Autor: Tipo: Clase: Descripción: Luis Felipe Wanumen Silva Orientación a objetos Interface Manipulación de clases tipo Fecha: interface 9 de Mayo de 2005 */ import java.awt.*; import java.awt.event.*; public class MyApp extends Frame { // Esta clase no genera un error public interface transporte{ public int posicion_x=2; public int posicion_y=0; } // Cierra interface transporte // Esta clase no genera un error public interface animal{ public String tipo="mamifero"; } // Cierra interface animal public class vaca implements transporte, animal{ } // Cierra class vaca public MyApp() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); // NO HAY PROBLEMA CREANDO OBJETO PINTADA vaca pintada = new vaca(); } public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(100,100); f.show(); } } Es importante notar que en el ejercicio anterior se creó un objeto denominado “pintada” que es un objeto de tipo “vaca”, la cual a su vez es una clase que implementa de las interfaces “transporte” y “animal”. Recordemos que se pueden crear objetos directamente de clases que no sean “interface”, pero indirectamente el objeto “vaca” tiene pues la funcionalidad de las interfaces. Esto es lo que se conoce como herencia múltiple en java, pero si el amigo lector / estudiante observa con cuidado podrá descubrir que no existe como tal la verdadera herencia múltiple, debido a que no se pueden heredar implementaciones de métodos de varias clases y esto en vez de ser una limitación del lenguaje java a veces se convierte en un gran beneficio a la hora de programar, aunque cuando se comienza con el mundo de la programación pareciera ser una desventaja. 13.11. UNA CLASE INTERFAZ PUEDE EXTENDER DE VARIAS CLASES TIPO INTERFAZ Aunque suene un poco raro, es importante no dejarse confundir con ésta parte del manual, debido básicamente a que se podría pensar que dado que en java no se permite la herencia múltiple pura en su concepción más amplia, y dicha herencia se realiza mediante la palabra reservada “extends”, podríamos deducir que la extensión de varias clases, si no se permite en otros contextos, no se debería permitir en éste. La verdad es que este es un caso muy especial y tiene que ver con el simple hecho que el compilador verifica si las clases que extienden de una clase tipo “interface” son clases tipo “interface” lo permite, y en caso contrario no lo permite. El significado de extender de varias clases tipo interfaz, no quiere decir que se esté heredando, sino que se hace un compromiso de implementar los métodos declarados en las clases interfaces de las que se extiende. Veamos un ejemplo en el que se muestra una clase tipo “interface” denominada “vaca” que extiende de dos clases tipo “interface” denominadas “transporte” y “animal”: /* Autor: Tipo: Clase: Descripción: Luis Felipe Wanumen Silva Orientación a objetos Interface Manipulación de clases tipo interface 9 de Mayo de 2005 Fecha: */ import java.awt.*; import java.awt.event.*; public class MyApp extends Frame { // Esta clase no genera un error public interface transporte{ public int posicion_x=2; public int posicion_y=0; } // Cierra interface transporte // Esta clase no genera un error public interface animal{ public String tipo="mamifero"; } // Cierra interface animal // ESTA CLASE NO GENERA UN ERROR public interface vaca extends transporte, animal{ } // Cierra class vaca public MyApp() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); } public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(100,100); f.show(); } } 13.12. UNA CLASE NO INTERFAZ NO PUEDE EXTENDER DE UNA CLASE TIPO INTERFAZ En este punto se hace hincapié en el análisis que hace el compilador de java al verificar que se puede extender de una clase tipo “interface” o de varias clases tipo “inteface” siempre y cuando la clase que extienda la funcionalidad de éstas sea una clase tipo no “interface”, de lo contrario no. La razón es bien sencilla y radica en el hecho principal de saber que para poder extender es porque se tiene la garantía que tendrá un comportamiento similar a la clase padre y este comportamiento similar a la clase padre, no se puede asegurar cuando la clase que la extiende no es una clase tipo “interface”, por cuanto puede tener comportamientos que no corresponden con una clase tipo “interface” y esto dañaría o deterioraría el concepto de la extensión de clases. El ejemplo siguiente muestra un programa que genera un error, debido a que se viola el concepto anteriormente explicado: /* Autor: Tipo: Clase: Descripción: Luis Felipe Wanumen Silva Orientación a objetos Interface Manipulación de clases tipo interface 9 de Mayo de 2005 Fecha: */ import java.awt.*; import java.awt.event.*; public class MyApp extends Frame { // Esta clase no genera un error public interface transporte{ public int posicion_x=2; public int posicion_y=0; } // Cierra interface transporte // ESTA CLASE GENERA UN ERROR // POR CUANTO UNA CLASE NO INTERFACE // NO PUEDE EXTENDER NI DE UNA, NI // MUCHO MENOS DE VARIAS CLASES TIPO // INTERFACE public class vaca extends transporte{ } // Cierra class vaca public MyApp() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); } public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(100,100); f.show(); } } 13.13. NO SE PUDE MODIFICAR VARIABLE DE UNA CLASE TIPO INTERFAZ Es importante tener en cuenta que las variables en una clase tipo “interface” son tomadas como variables “final”, con lo cual cualquier intento por modificarlas generará un error inmediatamente. A continuación se muestra un programa que incurre en este error: /* Autor: Tipo: Clase: Descripción: Luis Felipe Wanumen Silva Orientación a objetos Interface Manipulación de clases tipo interface 9 de Mayo de 2005 Fecha: */ import java.awt.*; import java.awt.event.*; public class MyApp extends Frame { // Esta clase no genera un error public interface transporte{ public int posicion_x=2; public int posicion_y=0; } // Cierra interface transporte // Esta clase no genera un error public class animal implements transporte{ public String tipo="mamifero"; } // Cierra interface animal public MyApp() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); // El objeto se crea correctamente animal vaca = new animal(); // No se puede asignar valor a variable // de tipo final vaca.posicion_x = 3; } public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(100,100); f.show(); } } En el anterior ejemplo, vemos que la variable “posición_x” es una variable que pertenece a la interfaz “transporte” y por lo tanto es como si se hubiese declarado de tipo “final”, con lo cual cualquier intento por modificar su valor generaría un error por parte del compilador, incluso si el valor que se le quisiese asignar fuere el mismo valor que tuviese en la declaración de la clase. El siguiente ejemplo también presenta problemas y no se puede compilar: /* Autor: Tipo: Clase: Descripción: Luis Felipe Wanumen Silva Orientación a objetos Interface Manipulación de clases tipo interface Fecha: 9 de Mayo de 2005 */ import java.awt.*; import java.awt.event.*; public class MyApp extends Frame { // Esta clase no genera un error public interface transporte{ public int posicion_x=2; public int posicion_y=0; public void moverse(); } // Cierra interface transporte // Esta clase no genera un error public class animal implements transporte{ public String tipo="mamifero"; public void moverse(){ // Esta asignación genera error debido a que // variable final no puede ser modificada posicion_x = posicion_x + 1; } // Cierra void moverse } // Cierra interface animal public MyApp() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); } public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(100,100); f.show(); } } Cabe anotar que verdaderamente la variable dentro de una clase “interface” es una variable tipo “final” por lo que no podrá ser modificada ni siquiera por algún método de las clases que implementen dicha interface. Se podría pensar que las variables de las clases tipo “interface” se comportan como constantes 13.14. CLASE QUE IMPLEMENTE CLASE TIPO INTERFAZ DEBE DEFINIR SUS MÉTODOS Es importante notar que toda clase no interface que implemente otra clase tipo interface debe implementar todos sus métodos. Por ejemplo el siguiente programa genera un error: /* Autor: Tipo: Clase: Descripción: Luis Felipe Wanumen Silva Orientación a objetos Interface Manipulación de clases tipo interface 9 de Mayo de 2005 Fecha: */ import java.awt.*; import java.awt.event.*; public class MyApp extends Frame { // Esta clase no genera un error public interface transporte{ public int posicion_x=2; public int posicion_y=0; public void moverse(); } // Cierra interface transporte // Esta clase no genera un error public class animal implements transporte{ public String tipo="mamifero"; // SE REQUIERE QUE AQUI SE HUBIESE // IMPLEMENTADO EL MÉTODO moverse() } // Cierra interface animal public MyApp() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); } public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(100,100); f.show(); } } Lo interesante del asunto es que con sólo indicar que se está implementando el método del programa anterior, ya el compilador no genera error, así en verdad no se esté implementando dicho método. Veamos pues ésta corrección en el programa mejorado con respecto al mencionado: /* Autor: Tipo: Clase: Descripción: Luis Felipe Wanumen Silva Orientación a objetos Interface Manipulación de clases tipo interface 9 de Mayo de 2005 Fecha: */ import java.awt.*; import java.awt.event.*; public class MyApp extends Frame { // Esta clase no genera un error public interface transporte{ public int posicion_x=2; public int posicion_y=0; public void moverse(); } // Cierra interface transporte // Esta clase no genera un error public class animal implements transporte{ public String tipo="mamifero"; // El compilador no genera error // porque cree que se está implementando // el método cuando en verdad no se // está implementando public void moverse(){ } // Cierra void moverse } // Cierra interface animal public MyApp() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); } public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(100,100); f.show(); } } 14. SOBRE LAS CLASES Y ATRIBUTOS TIPO FINAL Inicialmente podemos decir que una clase tipo final es una clase que no puede tener subclases asociadas. Por ejemplo la siguiente clase: public final class Clase1{ } // Cierra final class Clase1 No pude tener la siguiente subclase asociada: public class Clase2 extends Clase1{ } En términos de UML podemos decir que el siguiente diagrama UML de clases no es valido como parte de un diagrama de clases. <<<<final>>>> Clase1 Clase2 Tampoco son validos diagramas de clases como el siguiente: <<<<final>>>> Clase1 <<<<final>>>> Clase2 14.1. LOS ATRIBUTOS FINAL DEBEN ESTAR INICIALIZADOS La siguiente clase no genera errores: public final class Clase1{ final int atributo1 = 2; } // Cierra final class Clase1 Vemos pues que si le hacemos una modificación a la anterior clase y la dejamos como se muestra a continuación: public final class Clase1{ final int atributo1; } // Cierra final class Clase1 Tendremos un error similar al siguiente: D:\Compensar\MyApp.java:3: variable atributo1 might not have been initialized public final class Clase1{ ^ 1 error Podemos decir que diagramas de clases como el siguiente no son validos en UML. En cambio clases UML como la siguiente si son validos. 14.2. ATRIBUTOS FINAL Y CLASES NO FINAL Entre los atributos tipo “final” y las clases tipo “final” se han establecido tres casos: Caso 1: Clase no final con atributo final. Caso 2: Clase final con atributo no final. Clase 3: Clase final con atributo final. A continuación se detallan cada uno de estos casos; CASO 1: Veamos primero el siguiente código: public class Clase1{ final int atributo1=4; } // Cierra final class Clase1 El cual no genera ningun error, lo cual indica que es posible declarar variables tipo “final” al interior de clases no “final”. CASO 2: Y también tenemos la situación inversa, es decir clases final que no tengan atributos final, tal como lo muestra el siguiente programa: public class MyApp { public MyApp(){ } // Cierra MyApp public final class Clase1{ int atributo1=4; } // Cierra final class Clase1 public static void main(String args[]){ MyApp f = new MyApp(); } // Cierra void main() } // Cierra class MyApp El cual no presente errores. CASO 3: También es bueno tener en cuenta que clase tipo “final” pueden tener atributos tipo “final” tal como se muestra en el siguiente programa: public class MyApp { public MyApp(){ } // Cierra MyApp public final class Clase1{ final int atributo1=4; } // Cierra final class Clase1 public static void main(String args[]){ MyApp f = new MyApp(); } // Cierra void main() } // Cierra class MyApp Los tres casos plasmados en esta sección pueden ser modelados mediante los siguientes diagramas UML. Diagrama UML caso1: Diagrama UML caso2: Diagrama UML caso3: Los cuales son diagramas perfectamente validos en UML. 14.3. RECUPERACION DE ATRIBUTOS FINALES Los valores de los atributos que se encuentren al interior de clases, pueden ser recuperados por medio de objetos que instancien dichas clases. Para comprender este concepto, veamos primero el siguiente código: public class MyApp { public class Clase1{ public final int atributo1=4; } // Cierra final class Clase1 public MyApp(){ Clase1 objeto = new Clase1(); System.out.println(objeto.atributo1); } public static void main(String args[]){ MyApp f = new MyApp(); } // Cierra static void main() } // Ciera class MyApp El diagrama se clases del anterior programa, sin tener la clase contenedora “MyApp” es similar al siguiente: El diagrama anterior es perfectamente valido 14.4. ASIGNACION DE VALORES A LOS ATRIBUTOS TIPO FINAL Si observamos el siguiente programa: public class MyApp public class Clase1{ public final int atributo1=4; } // Cierra final class Clase1 public MyApp(){ Clase1 objeto = new Clase1(); objeto.atributo1 = 500; } public static void main(String args[]){ MyApp f = new MyApp(); } // Cierra static void main() } // Ciera class MyApp Vemos que tenemos un error porque estamos tratando de asignar valores a un atributo tipo final, con lo cual podemos concluir que a una variable tipo final se le puede asociar con el concepto de una constante que solamente se puede recuperar este valor, mas no se puede volver a alterar dicho valor. Lo interesante del asunto es que el diagrama de clases sin tener en cuenta la clase contenedora es similar al siguiente: Y este diagrama de clases es valido. La pregunta que viene es: ¿Por qué el diagrama de clases es valido y sin embargo el código genera error?. La respuesta es sencilla: “No siempre los diagramas de clases muestran errores, existen otros diagramas que muestran otras vistas del software”. En nuestro caso particular el diagrama de secuencia del anterior programa es el siguiente: objeto : Clase1 La pregunta que viene es: ¿Por qué el diagrama de secuencia no muestra interacciones si se esta tratando de ejecutar la acción de asignar un valor a un atributo?. La respuesta es la siguiente: No se están invocando métodos y la acción de intentar modificar el valor de un atributo no queda registrada en el diagrama de clases, razón por la cual el diagrama de secuencia al que hacemos relación no tiene interacciones. De lo anterior podemos comprender que es una buena practica crear métodos que permitan asignar valores a los atributos y también devolver valores a los atributos con el fin que este tipo de acciones queden documentadas en los diagramas de secuencia y al compararlos con los diagramas de clases permitan detectar los errores en tiempo de diseño antes de tener que llegar a la implementación y darnos cuenta de los errores en el flujo de implementación. 14.5. CREACION DE METODOS TIPO FINAL Una clase no final puede contener métodos tipo “final”. La siguiente declaración de clase es valida en el lenguaje Java: public class Clase1{ int x=6; final void metodo1(){ } // Cierra void metodo1() } // Cierra class Clase1 La pregunta que viene es: ¿Qué quiere decir que un método sea de tipo final al interior de una clase?. Antes de responder esta pregunta veamos el siguiente programa: public class MyApp { public MyApp(){ Clase1 objeto1 = new Clase1(); objeto1.x=45; } // Cierra MyApp public class Clase1{ int x=6; final void metodo1(){ } // Cierra void metodo1() } // Cierra class Clase1 public class Clase1 extends Clase2{ void metodo1(){ } } // Cierra class Clase2 public static void main(String args[]){ MyApp f = new MyApp(); } // Cierra void main() } // Cierra class MyApp El cual esta intentando crear una clase llamada “Clase2” que hereda de la clase “Clase1”, pero genera un error similar al siguiente: D:\Compensar\MyApp.java:14: MyApp.Clase1 is already defined in MyApp public class Clase1 extends Clase2{ ^ 1 error Exit code: 1 Y este error se presenta debido a que un método “X” tipo final en una clase “A”, no puede ser sobrescrito en una subclase2 “Y”. 2 El termino subclase es usado para especificar que una clase es clase hija de otra clase. 14.6. TALLER PROPUESTO SOBRE CLASES Y ATRIBUTOS TIPO FINAL 1. 2. 3. 4. 5. 6. 7. 8. 9. Elaborar un documento sobre el significado de crear clases tipo “static final”. Elaborar un documento sobre el significado de crear metodos tipo “static final”. Elaborar un documento sobre el significado de crear atributos tipo “static final”. Investigar en lenguaje c, si el concepto de clases tipo static existe y si es igual el concepto al existente en el lenguaje Java. Investigar en lenguaje c, si el concepto de clases tipo final existe y si es igual el concepto al existente en el lenguaje Java. Investigar en lenguaje c, si el concepto de métodos tipo static existe y si es igual el concepto al existente en el lenguaje Java. Investigar en lenguaje c, si el concepto de métodos tipo final existe y si es igual el concepto al existente en el lenguaje Java. Investigar en lenguaje c, si el concepto de atributos tipo static existe y si es igual el concepto al existente en el lenguaje Java. Investigar en lenguaje c, si el concepto de atributos tipo final existe y si es igual el concepto al existente en el lenguaje Java. 15. CASOS VARIADOS SOBRE CLASES INTERFACE, FINALES Y ABSTRACTAS 15.1. CASO 1: Se pueden declarar clases tipo “interface” al interior de clases normales, tal como se muestra a continuación: public class MyApp { public interface Interface{ } public static void main(String args[]) { } } 15.2. CASO 2: No se pueden crear clases tipo “interface” al interior de clases tipo final. Por ejemplo el siguiente programa: public class MyApp { public final class Base{ public interface Interface{ } } // Cierra final class Base public static void main(String args[]) { } } Genera un error de compilación y el error es básicamente debido a que existe una clase tipo “interface” al interior de la clase llamada “Base” que es de tipo “final”. ¿Cuál es el motivo para que el programa anterior presente errores?. Se deja a amigo lector / estudiante la tarea de averiguar la razón por la que el anterior programa presenta errores. El error producido por el compilador es similar al siguiente: D:\MyApp.java:5: inner classes cannot have static declarations public interface Interface{ ^ 1 error 15.3. CASO 3: Si es posible declarar clases tipo “final” al interior de clases tipo “interface” y para demostrar esto, veamos el siguiente programa: public class MyApp { public interface Interface{ public final class Base{ } } // Cierra interface Interface public class Hija{ } public static void main(String args[]) { } } El cual compila sin errores. En este punto es bueno notar que el programa anterior compila y no genera errores, pero hagamos la siguiente pregunta: ¿Qué utilidad tiene declarar una clase final al interior de una clase tipo interface? 15.4. CASO 4: En los dos anteriores casos, se vio que si se declara una clase tipo “final” al interior de una clase tipo “interface” no se presentan errores, pero si se declara al revés, es decir una clase tipo “interface” al interior de una clase tipo “final” se presentan errores. Lo curioso del asunto es que si se declaran relaciones de contención en las que se va alternando la contención entre clases “interface” y clases “final”, las relaciones de contención son validas. Para explicar este concepto veamos el siguiente programa: public class MyApp { public interface Clase1{ public final class Clase2{ public interface Clase3{ public final class Clase4{ public interface Clase5{ } // Cierra interface Clase5 } // Cierra final class Clase4 } // Cierra interface Clase3 } // Cierra final class Clase2 } // Cierra interface Clase1 public static void main(String args[]) { } } El cual no genera error, a pesar que la clase interface “Clase5” se encuentra al interior de una clase tipo “final”, que en este caso se llama “Clase4” y la razon para que no se genere el error es porque la clase “Clase4” se encuentra a su vez al interior de una clase “Clase3” que es de tipo “interface”. Con todo esto estamos diciendo que realmente la clase “Clase5” se encuentra al interior de la clase “Clase3” y esto es valido, debido a que una clase tipo “interface”, puede estar dentro de otra clase tipo “interface”. En el programa anterior podemos decir que la clase interface “Clase3” deberia generar un error por estar dentro de la clase “Clase2” por esta ultima ser de tipo “interface”, pero la verdad tampoco se genera error alguno debido a que la clase final “Clase2”, se encuentra a su vez dentro de la clase interface “Clase1”, con lo cual se permite que la clase “Clase3”, este dentro de la clase “Clase2”, pero solo en estas circunstancias. En pocas palabras, estamos diciendo que si la clase de mayor alcance, es decir la clase que contiene a la todas las clases fuera de tipo “final” se presentaria error de compilación. Para probar que este tipo de recursion si causaria errores, observemos el siguiente programa: public class MyApp { public final class Clase2{ public interface Clase3{ public final class Clase4{ public interface Clase5{ } // Cierra interface Clase5 } // Cierra final class Clase4 } // Cierra interface Clase3 } // Cierra final class Clase2 public static void main(String args[]) { } } El cual genera errores de compilación, por cuanto la clase que contiene a las demás clases es de tipo “final”. Los errores del anterior programa son similares a los siguientes: D:\MyApp.java:4: inner classes cannot have static declarations public interface Clase3{ ^ 1 error 15.5. CASO 5: Es posible crear clases estáticas al interior de clases tipo “interface”, con lo cual el siguiente programa: public class MyApp { public interface Interface{ public static class EstaticaInterna{ } } // Cierra interface Interface public static void main(String args[]) { } } Compila y no presenta error alguno. 15.6. CASO 6: Es posible crear clases tipo “interface” al interior de clases tipo “static”, tal como lo muestra el siguiente programa: public class MyApp { public static class EstaticaInterna{ public interface Interface{ } } // Cierra static class EstaticaInterna public static void main(String args[]) { } } 15.7. CASO 7: Es posible crear objetos de clases estáticas al interior de métodos estáticos tal como lo muestra el siguiente programa: public class MyApp { public static class EstaticaInterna{ } // Cierra static class EstaticaInterna public static void main(String args[]) { EstaticaInterna objetoEstatico = new EstaticaInterna(); } } El cual compila perfectamente. De otra parte, si un objeto de una clase no estática se crea al interior de un método estático se producen errores tal como lo muestra el siguiente programa: public class MyApp { public class EstaticaInterna{ } // Cierra class EstaticaInterna public static void main(String args[]) { EstaticaInterna objetoEstatico = new EstaticaInterna(); } } El cual produce un error similar al siguiente: D:\MyApp.java:8: non-static variable this cannot be referenced from a static context EstaticaInterna objetoEstatico = new EstaticaInterna(); ^ 1 error 15.8. CASO 8: Es posible crear una clase final al interior de otra clase tipo final, y esta relación se puede presentar recursivamente cualquier cantidad de veces. Para demostrar esta afirmación, a continuación mostramos un programa que implementa este tipo de relacion de anidamiento en tres niveles en donde en cada nivel tenemos una clase tipo final. En el nivel superior una clase llamada “ClaseExterna”, al interior de esta, una clase llamada “ClaseIntermedia” y al interior de esta otra clase llamada “ClaseInterna”. public class MyApp { public final class ClaseExterna{ public final class ClaseIntermedia{ public final class ClaseInterna{ } } // Cierra final class ClaseIntermedia } // Cierra final class ClaseExterna public static void main(String args[]) { } } 15.9. CASO 9: Es posible declarar una clase tipo “interface” al interior de otra clase tipo “interface”. Para demostrar esta afirmación mostramos el siguiente programa: public class MyApp { public interface ClaseExterna{ public interface ClaseInterna{ } // Cierra interface ClaseInterna } // Cierra interface ClaseExterna public static void main(String args[]) { } } El cual al ser compilado no presenta errores 15.10. TALLER Explicar la razón por la cual los casos exitosos, expuestos anteriormente funcionan. Explicar la razón por la cual los casos no exitosos, expuestos anteriormente no funcionan. Inventarse 10 casos exitosos adicionales sobre clases interface, final y abstracta y explicarlos no solamente con código, sino también por medio de un diagrama de clases. Inventarse 10 casos no exitosos adicionales sobre clases interface, final y abstracta y explicarlos no solamente con código, sino también por medio de un diagrama de clases. 16. EL POLIMORFISMO PARECE NO SER EXLUSIVO DE LA HERENCIA NI DE LA ORIENTACION A OBJETOS En el libro UML para programadores Java el señor Rober C. Martin plantea que el polimorfismo permite que los módulos invoquen funciones si depender de los módulos que las contienen (pag67), pero queremos dar una definición mas acercada a la programación orientada a objetos, con lo cual diremos que el polimorfismo permite que las clases invoquen métodos sin depender de las clases que tienen estos métodos. En pocas palabras estamos diciendo que el método tiene el mismo estereotipo o comúnmente llamada interfaz del método en varias clases, es decir existen varias implementaciones del mismo método pero en distintas clases. La ultima frase, nos da una idea de lo interesante que suena el implementar un método con el mismo nombre pero de diversas formas en diversas clases. En un principio sonaría algo extraño hacer este tipo de cosas, pero la verdad es que esto da la posibilidad de tener unos tipos de comportamientos iguales en nombre, pero con implementaciones distintas de acuerdo a la clase que se este invocando. La parte final del párrafo anterior se parece mas a la definición de polimorfismo dada por el señor Francisco Javier Ceballos en su libro de “Enciclopedia de Microsoft. Visual C#” en el cual plantea que el polimorfismo significa “la facultad de asumir muchas formas” refiriéndose a la facultad de llamar a las distintas versiones que adopta un método definido en una superclase y redefinido en sus clases derivadas. 16.1. UNA DEFINICION MÁS FORMAL Si analizamos los dos párrafos anteriores tenemos que dicen lo mismo, salvo una ligera acepción. Ambos párrafos están de acuerdo en que dos clases distintas tienen distinta implementación de un mismo método, lo que pasa es que en el primer párrafo no se establece la relación entre estas clases, mientras que en el segundo se establece que estas clases tienen una relación de herencia. Para perfeccionar nuestra definición de polimorfismo tenemos que solucionar la acepción del párrafo anterior y para ello vamos a tener en cuenta dos observaciones. Primera: Si el concepto de polimorfismo entre módulos existe para invocación de funciones que no dependen de funciones que las contienen, da la idea de ser aplicable a entidades que no necesariamente tengan que tener una relación de herencia, puesto que en la programación funcional pura no existe este concepto(Este concepto no solo es de programación orientada a objetos). Segunda: El señor James Rumbaugh en su libro modelado y diseño orientados a objetos, metodología OMT dice que si una operación puede aplicarse a muchas clases distintas, tal operación será polimórfica y en ningún caso habla de la relación entre estas clases, es mas hace énfasis en “muchas clases distintas”(pag 50). Teniendo en cuenta las dos observaciones anteriores podemos decir que el concepto es aplicable indistintamente si las clases tienen relaciones de herencia. 16.2. UN EJEMPLO DE NO POLIMORFISMO Antes de mostrar el ejemplo de polimorfismo es necesario aclarar el término de “signatura”. Diremos que la signatura de un método es el nombre completo del mismo que incluye los tipos de los argumentos, el orden de los mismos, el tipo de valor de retorno y el número de argumentos. Finalmente decimos que se presenta polimorfismo cuando dos clases tienen cada una su propia implementación de un mismo método con la misma signatura. Según lo mencionado anteriormente podemos concluir que el método “imprimir” entre las siguientes dos clases no es polimórfico. Archivo Documento.java public class Documento{ public void imprimir(String contenido){ if(contenido!=null){ System.out.println(contenido); } // Cierra if } // Cierra void imprimir() } // Cierra class Documento A continuación la clase Triangulo.java Archivo Triangulo.java public class Triangulo{ public void imprimir(){ System.out.println("Imprimiendo triangulo"); } // Cierra void imprimir() } // Cierra class Triangulo La razón para que estos métodos no sean polimórficos se obtiene analizando la signatura de los métodos, la cual se muestra en el siguiente diagrama de clases: El método “imprimir()” de la clase “Documento” recibe un parámetro tipo “String”, en tanto que el método “imprimir()” de la clase “Triangulo” no recibe valor alguno y por esta sencilla diferencia los métodos no son polimórficos. Obviamente lo anterior no quiere decir que el programa no funcione y para probar que si funciona a continuación se muestra el programa que usa las dos anteriores clases para imprimir. Veamos pues: Archivo MyApp.java public class MyApp { public MyApp(){ Triangulo objeto1 = new Triangulo(); Documento objeto2 = new Documento(); try{ objeto1.imprimir(); objeto2.imprimir("Para imprimir"); } catch(Exception e){ } // Cierra catch } // Cierra constructor MyApp public static void main(String args[]){ MyApp f = new MyApp(); } // Cierra static void main() } // Cierra class MyApp 16.3. UN EJEMPLO DE POLIMORFISMO Basándonos en el ejercicio anterior, pero haciéndole una modificación al archivo “Documento.java” podemos hacer que el método “imprimir()” sea polimórfico Archivo Documento.java public class Documento{ public void imprimir(){ System.out.println("Imprimiendo Documento"); } // Cierra void imprimir() } // Cierra class Documento Con lo cual nuestro diagrama de clases toma una forma similar a la siguiente: Y esto hará que estos métodos sean polimórficos. 16.4. TALLER PROPUESTO SORE POLIMORFISMO 1. Investigar diez definiciones de polimorfismo. 2. Hacer una investigación sobre la forma de aplicar polimorfismo en lenguajes orientados a objetos y lenguajes funcionales. 3. Hacer 5 ejercicios de polimorfismo en lenguaje C. 4. Hacer 5 ejercicios de polimorfismo en lenguaje C++. 5. Hacer 5 ejercicios de polimorfismo en lenguaje C#. 6. Hacer 5 ejercicios de polimorfismo en lenguaje Java. 7. Hacer 5 ejercicios de polimorfismo con herencia simple. 8. Hacer 5 ejercicios de polimorfismo con herencia múltiple 9. Investigar 5 casos en los que sea conveniente usar polimorfismo. 10. Investigar 5 casos en los que no sea conveniente usar polimorfismo.. 11. Investigar el origen de la palabra polimorfismo. 12. Investigar si existen métricas relacionadas con el polimorfismo. 17. REDEFINICIÓN Y ANULACION DE METODOS EN LA HERENCIA En la sección anterior se hablaba del polimorfismo como una forma de definir métodos con la misma signatura para diversas clases. También se aclaraba que estas clases no necesariamente tenían que estar relacionadas por medio de lazos de herencia, pero si este polimorfismo se aplica de la mano con el concepto de herencia tenemos un nuevo concepto llamado redefinición. El siguiente diagrama explica bien la situación: POLIMORFISMO + HERENCIA = REDEFINICION Podemos pensar entonces que la redefinición es un tipo de polimorfismo aplicado a la herencia. El concepto de redefinición se conoce con otros nombres tal como se indica en la siguiente figura: Reemplazamiento Sustitución REDEFINICION Overriding Invalidación La pregunta que viene es: ¿es posible que costumbres de redefinición hagan que el uso de la herencia no sea el más apropiado? La respuesta es si. 17.1. ANULACION POR EXTENSION Anulación por extensión hace referencia a la posibilidad de anadir funcionalidad a un método de una clase “padre” 17.2. ANULACION POR RESTRICCION Por lo general se desarrolla este tipo de anulación cuando se especifica con mayor precisión los tipos de los argumentos. 17.3. ANULACION POR OPTIMACIÓN Se presenta anulación por optimación cuando se mejora el rendimiento en la ejecución de un método aprovechando las limitaciones impuestas por una restricción. 17.4. INVALIDACION POR CONVENIENCIA Existe una tendencia en el desarrollo de aplicaciones orientadas a objetos, que en al momento de crear nuevas clases, se asocien estas clases por medio de herencia a alguna clase ya existente, pero no siempre se hace esto de la mejor forma y esto acarrea que a veces los métodos de las subclases invaliden métodos de las superclases. A veces se anulan métodos convenientemente, pero a veces se va la mano y se invalidan métodos que no se deberían invalidar. 17.5. TALLER SOBRE REDEFINICION DE METODOS EN LA HERENCIA 1. Desarrollar cinco ejercicios en lenguaje C donde se desarrollen ejercicios diferentes a los planteados en la presente unidad sobre anulación por extensión 2. Desarrollar cinco ejercicios en lenguaje C donde se desarrollen ejercicios diferentes a los planteados en la presente unidad sobre anulación por restricción 3. Desarrollar cinco ejercicios en lenguaje C donde se desarrollen ejercicios diferentes a los planteados en la presente unidad sobre anulación por optimación 4. Desarrollar cinco ejercicios en lenguaje C donde se desarrollen ejercicios diferentes a los planteados en la presente unidad sobre anulación por conveniencia 5. Desarrollar cinco ejercicios en lenguaje C++ donde se desarrollen ejercicios diferentes a los planteados en la presente unidad sobre anulación por extensión 6. Desarrollar cinco ejercicios en lenguaje C++ donde se desarrollen ejercicios diferentes a los planteados en la presente unidad sobre anulación por restricción 7. Desarrollar cinco ejercicios en lenguaje C++ donde se desarrollen ejercicios diferentes a los planteados en la presente unidad sobre anulación por optimación 8. Desarrollar cinco ejercicios en lenguaje C++ donde se desarrollen ejercicios diferentes a los planteados en la presente unidad sobre anulación por conveniencia 9. Desarrollar cinco ejercicios en lenguaje C# donde se desarrollen ejercicios diferentes a los planteados en la presente unidad sobre anulación por extensión 10. Desarrollar cinco ejercicios en lenguaje C# donde se desarrollen ejercicios diferentes a los planteados en la presente unidad sobre anulación por restricción 11. Desarrollar cinco ejercicios en lenguaje C# donde se desarrollen ejercicios diferentes a los planteados en la presente unidad sobre anulación por optimación 12. Desarrollar cinco ejercicios en lenguaje C# donde se desarrollen ejercicios diferentes a los planteados en la presente unidad sobre anulación por conveniencia 13. Desarrollar cinco ejercicios en lenguaje Java donde se desarrollen ejercicios diferentes a los planteados en la presente unidad sobre anulación por extensión 14. Desarrollar cinco ejercicios en lenguaje Java donde se desarrollen ejercicios diferentes a los planteados en la presente unidad sobre anulación por restricción 15. Desarrollar cinco ejercicios en lenguaje Java donde se desarrollen ejercicios diferentes a los planteados en la presente unidad sobre anulación por optimación 16. Desarrollar cinco ejercicios en lenguaje Java donde se desarrollen ejercicios diferentes a los planteados en la presente unidad sobre anulación por conveniencia 17. Investigar si existen métricas relacionadas con anulación por extensión 18. Investigar si existen métricas relacionadas con anulación por restricción 19. Investigar si existen métricas relacionadas con anulación por optimación 20. Investigar si existen métricas relacionadas con invalidación por conveniencia 18. TODO A CERCA DE CLASES Las clases son lo más simple de Java. Todo en Java forma parte de una clase, es una clase o describe como funciona una clase. El conocimiento de las clases es fundamental para poder entender los programas Java. Todas las acciones de los programas Java se colocan dentro del bloque de una clase o un objeto. Todos los métodos se definen dentro del bloque de la clase, Java no soporta funciones o variables globales. Esto puede despistar a los programadores de C++, que pueden definir métodos fuera del bloque de la clase, pero esta posibilidad es más un intento de no separarse mucho y ser compatible con C, que un buen diseño orientado a objetos. Así pues, el esqueleto de cualquier aplicación Java se basa en la definición de una clase. Todos los datos básicos, como los enteros, se deben declarar en las clases antes de hacer uso de ellos. En C la unidad fundamental son los ficheros con código fuente, en Java son las clases. De hecho son pocas las sentencias que se pueden colocar fuera del bloque de una clase. La palabra clave import (equivalente al #include) puede colocarse al principio de un fichero, fuera del bloque de la clase. Sin embargo, el compilador reemplazará esa sentencia con el contenido del fichero que se indique, que consistirá, como es de suponer, en más clases. 18.1. TIPOS DE CLASES Hasta ahora sólo se ha utilizado la palabra clave public para calificar el nombre de las clases que hemos visto, pero hay tres modificadores más. Los tipos de clases que podemos definir son: abstract Una clase abstract tiene al menos un método abstracto. Una clase abstracta no se instancia, sino que se utiliza como clase base para la herencia. final Una clase final se declara como la clase que termina una cadena de herencia. No se puede heredar de una clase final. Por ejemplo, la clase Math es una clase final. public Las clases public son accesibles desde otras clases, bien sea directamente o por herencia. Son accesibles dentro del mismo paquete en el que se han declarado. Para acceder desde otros paquetes, primero tienen que ser importadas. synchronizable Este modificador especifica que todos los métodos definidos en la clase son sincronizados, es decir, que no se puede acceder al mismo tiempo a ellos desde distintos threads; el sistema se encarga de colocar los flags necesarios para evitarlo. Este mecanismo hace que desde threads diferentes se puedan modificar las mismas variables sin que haya problemas de que se sobreescriban. 18.2. VARIABLES Y METODOS DE INSTANCIA Una clase en Java puede contener variables y métodos. Las variables pueden ser tipos primitivos como int, char, etc. Los métodos son funciones. Por ejemplo, en el siguiente trozo de código podemos observarlo: public MiClase { int i; public MiClase() { i = 10; } public void Suma_a_i( int j ) { i = i + j; } } La clase MiClase contiene una variable (i) y dos métodos, MiClase que es el constructor de la clase y Suma_a_i( int j ). 18.3. AMBITO DE UNA VARIABLE Los bloques de sentencias compuestas en Java se delimitan con dos llaves. Las variables de Java sólo son válidas desde el punto donde están declaradas hasta el final de la sentencia compuesta que la engloba. Se pueden anidar estas sentencias compuestas, y cada una puede contener su propio conjunto de declaraciones de variables locales. Sin embargo, no se puede declarar una variable con el mismo nombre que una de ámbito exterior. El siguiente ejemplo intenta declarar dos variables separadas con el mismo nombre. En C y C++ son distintas, porque están declaradas dentro de ámbitos diferentes. En Java, esto es ilegal. Class Ambito { int i = 1; { int i = 2; } } // ámbito exterior // crea un nuevo ámbito // error de compilación 18.4. METODOS Y CONSTRUCTORES Los métodos son funciones que pueden ser llamadas dentro de la clase o por otras clases. El constructor es un tipo específico de método que siempre tiene el mismo nombre que la clase. Cuando se declara una clase en Java, se pueden declarar uno o más constructores opcionales que realizan la inicialización cuando se instancia (se crea una ocurrencia) un objeto de dicha clase. Utilizando el código de ejemplo anterior, cuando se crea una nueva instancia de MiClase, se crean (instancian) todos los métodos y variables, y se llama al constructor de la clase: MiClase mc; mc = new MiClase(); La palabra clave new se usa para crear una instancia de la clase. Antes de ser instanciada con new no consume memoria, simplemente es una declaración de tipo. Después de ser instanciado un nuevo objeto mc, el valor de i en el objeto mc será igual a 10. Se puede referenciar la variable (de instancia) i con el nombre del objeto: mc.i++; // incrementa la instancia de i de mc Al tener mc todas las variables y métodos de MiClase, se puede usar la primera sintaxis para llamar al método Suma_a_i() utilizando el nuevo nombre de clase mc: mc.Suma_a_i( 10 ); y ahora la variable mc.i vale 21. 18.5. FINALIZADORES Java no utiliza destructores (al contrario que C++) ya que tiene una forma de recoger automáticamente todos los objetos que se salen del alcance. No obstante proporciona un método que, cuando se especifique en el código de la clase, el reciclador de memoria (garbage collector) llamará: // Cierra el canal cuando este objeto es reciclado protected void finalize() { close(); } 18.6. ALCANCE DE OBJETOS Y RECICLADO DE MEMORIA Los objetos tienen un tiempo de vida y consumen recursos durante el mismo. Cuando un objeto no se va a utilizar más, debería liberar el espacio que ocupaba en la memoria de forma que las aplicaciones no la agoten (especialmente las grandes). En Java, la recolección y liberación de memoria es responsabilidad de un thread llamado automatic garbage collector (recolector automático de basura). Este thread monitoriza el alcance de los objetos y marca los objetos que se han salido de alcance. Veamos un ejemplo: String s; s = new String( "abc" ); s = "def"; // // // // no se ha asignado todavia memoria asignada se ha asignado nueva memoria (nuevo objeto) Más adelante veremos en detalle la clase String, pero una breve descripción de lo que hace esto es; crear un objeto String y rellenarlo con los caracteres "abc" y crear otro (nuevo) String y colocarle los caracteres "def". En esencia se crean dos objetos: Objeto String "abc" Objeto String "def" Al final de la tercera sentencia, el primer objeto creado de nombre s que contiene "abc" se ha salido de alcance. No hay forma de acceder a él. Ahora se tiene un nuevo objeto llamado s y contiene "def". Es marcado y eliminado en la siguiente iteración del thread reciclador de memoria. 19. EJERCICIO DEL PIRATA RESULADO DE LA PRIMERA ITERACION CON RUP 19.1. PLANTEAMIENTO DEL ENUNCIADO Un pirata ebrio se tambalea al subir por una rampa del muelle a su barco. La rampa tiene cinco pasos de ancho y 15 de largo. Comenzamos a observar al pirata cuando está en el extremo de la rampa que se apoya sobre el muelle. Si da más de dos pasos hacia la izquierda o la derecha, caerá en el agua y se ahogará, pero si da más de 15 pasos hacia delante estará a salvo a bordo de su barco. 19.2. ESTABLECIMIENTO DE FRASES IMPORTANTES. Un pirata ebrio se tambalea Un pirata sube por una rampa La rampa tiene cinco pasos de ancho y 15 de largo. Observamos al pirata cuando está en el extremo de la barca La rampa se apoya sobre el muelle Si el pirata da mas de dos pasos hacia la izquierda se cae Si el pirata da mas de dos pasos hacia la derecha se cae. Cuando el pirata se cae, se ahoga Si el pirata da mas de 15 pasos hacia delante estará a salvo. Cuando está a salvo no se ahoga El pirata en el barco estará a salvo. 19.3. ESTABLECIMIENDO DE CLASES 19.4. PROGRAMA EN JAVA import java.awt.*; import java.awt.event.*; import java.applet.*; public class MyApp extends Applet { GridLayout grilla = new GridLayout(15,5,1,1); BorderLayout borde = new BorderLayout(4,4); Panel paneles[][] = new Panel[5][15]; Graphics gp[][] = new Graphics[5][15]; int actual_x, actual_y; Panel superior = new Panel(); Panel arriba = new Panel(); Panel inferior = new Panel(); TextArea ta = new TextArea(5,30); TextField t1 = new TextField("EL PIRATA PESA"); pirata IngSistemas = new pirata(); rampa Rampa = new rampa(); mar Mar = new mar(); boolean salvado = false; barco Barco = new barco(); muelle Muelle = new muelle(); public void paint(Graphics g) { for(int x = 0; x<5; x++){ for(int y = 0; y<15; y++){ gp[x][y] = paneles[x][y].getGraphics(); if(x == actual_x && y == actual_y){ paneles[x][y].setBackground(Color.red); } else{ paneles[x][y].setBackground(Color.white); } // Cierra else } // cierra for interno } // cierra for externo } // cierra paint() public class mar{ public void ahogar(pirata hombre){ String cadena = ta.getText().trim(); cadena = cadena + "\n EL MAR HABLA: \n"; cadena = cadena + "ESTOY AHOGANDO AL MUERTO"; ta.setText(cadena); IngSistemas.dejarse_ahogar(); } } // Cierra class mar public void init(){ actual_x = 2; actual_y = 0; setLayout(borde); superior.setLayout(new BorderLayout(4,5)); superior.add("Center", arriba); add("Center", superior); add("South", inferior); inferior.add(ta); inferior.add(t1); arriba.setLayout(grilla); setBackground(Color.black); for(int x = 0; x<5; x++){ for(int y = 0; y<15; y++){ paneles[x][y] = new Panel(); } } for(int y = 0; y<15; y++){ for(int x = 0; x<5; x++){ arriba.add(paneles[x][y]); } } Muelle.soportar_peso(IngSistemas.peso); Muelle.informar_peso(); } // Cierra funcion init() public class barco{ String mensaje = ""; public void salvar_pirata(){ salvado = true; mensaje = ta.getText().trim(); mensaje = mensaje + "\n EL BARCO HABLA \n"; mensaje = mensaje + "SALVADO EL PIRATA"; ta.setText(mensaje); } } // Cierra class barco public class muelle{ int peso_actual = 70; String peso_cadena = ""; public void soportar_peso(int valor){ peso_actual = valor; } // Cierra void soportar_peso public void informar_peso(){ peso_cadena = t1.getText().trim(); peso_cadena = peso_cadena + " "; peso_cadena = peso_cadena + peso_actual; peso_cadena = peso_cadena + "KILOS "; t1.setText(peso_cadena); }// int informar_peso } // Cierra class muelle public class rampa{ int pos_x=0; int pos_y=0; String mensaje = "EL MUELLE HABLA; \n"; public void validar_salida(int x, int y){ pos_x = x; pos_y = y; if(pos_y<0){ mensaje = mensaje + "Fuera del rango y"; ta.setText(mensaje); tirar_al_mar(); } if(pos_x<0){ mensaje = mensaje + "Fuera del rango x"; ta.setText(mensaje); tirar_al_mar(); } if(pos_x>=5){ mensaje = mensaje + "Fuera del rango x"; ta.setText(mensaje); tirar_al_mar(); } if(pos_y>=15){ mensaje = mensaje + "NO LO DEJE CAER"; ta.setText(mensaje); Barco.salvar_pirata(); } } // Cierra void validar_salida() public void tirar_al_mar(){ Mar.ahogar(IngSistemas); } // Cierra void tirar_al_mar() } // Cierra class rampa public class pirata{ int pos_x; int pos_y; int peso = 75; // Kilos boolean estado_vida = true; public void moverse(int i, int j){ if(estado_vida){ pos_x = i; pos_y = j; Rampa.validar_salida(pos_x, pos_y); } // Cierra if } // Cierra moverse public void dejarse_ahogar(){ estado_vida = false; } //Cierra void dejarse_ahogar } // Cierra clase pirata public boolean keyDown(Event evt, int key){ if(IngSistemas.estado_vida && salvado==false){ switch(key){ case Event.RIGHT: actual_x++; IngSistemas.moverse(actual_x, actual_y); repaint(); break; case Event.LEFT: actual_x--; IngSistemas.moverse(actual_x, actual_y); repaint(); break; case Event.UP: actual_y--; IngSistemas.moverse(actual_x, actual_y); repaint(); break; case Event.DOWN: actual_y++; IngSistemas.moverse(actual_x, actual_y); repaint(); break; } return true; } // Cierra if externo return false; } // Cierra boolean } // Cierra clase MyApp 19.5. EJECUCIÓN DEL PROGRAMA: El programa anterior muestra una grilla en donde se encuentra una celda que tiene un color rojo a diferencia de las demás celdas. Esto para el caso del programa que estamos explicando indica que el pirata se encuentra en dicha posición. Ahora bien, el usuario, puede desplazarse mediante las teclas de dirección del teclado y de esta manera podrá mover el pirata. (que en este caso es la posición roja). Si el usuario no lo deja desbordarse por alguna posición de la derecha o de la izquierda y llega a la posición de debajo de la figura, se obtiene un resultado similar al siguiente: Pero si el usuario lo deja desbordarse por la derecha o por la izquierda, aparecerá una pantalla similar a la siguiente: Con lo cual se indica que efectivamente se ha caido el pirata al mar y por supuesto se ha ahogado. 20. EJERCICIO DEL AVION 20.1. DIAGRAMA DE CLASE 20.2. EXPLICACIÓN DE LA IMPLEMENTACIÓN La implementación del ejercicio anterior se hizo basándose en el concepto que la mejor forma para trabajar orientado a objetos es crear una clase en un archivo a medida que el programa que se va ha realizar crezca de complejidad. En últimas ésta técnica ayuda a un buen mantenimiento de los aplicativos y aunque a nivel de máquina no siempre resulta ser la mejor opción, por lo menos si asegura ser la mejor opción cuando se requieran hacer modificaciones al respecto. A continuación se muestran pues los contenidos de cada uno de los archivos que llevan a solucionar el problema del avión. Veamos pues: avion.java import java.awt.*; import java.awt.event.*; import java.applet.*; public class avion{ Graphics h; int x = 150; int y = 400; rectangulo cuerpo = new rectangulo(); rectangulo cola = new rectangulo(); triangulo ala_superior = new triangulo(); triangulo ala_inferior = new triangulo(); triangulo punta = new triangulo(); int matriz[][] = new int[17][4]; int colita[][]; int cuerpito[][]; int puntica[][]; int alita_arriba[][]; int alita_abajo[][] = new int[3][4]; int trompíta[][] = new int[3][4]; public avion(){ // Por medio de punta se establece // el tamaño del avion punta.alto = 40; }// Cierra public avion public void alejarse(){ if(punta.alto>10){ punta.alto = punta.alto - 1; }// Cierra ir } // Cierra void alejarse public void ascender(){ if(y>20){ y = y - 5; }// Cierra ir } // Cierra void alejarse public int[][] devolver_grafica(){ // punta.alto = 20; punta.posx = x; punta.posy = y; punta.ajustarse("punta"); cuerpo.alto = punta.alto; cuerpo.ancho = cuerpo.alto*6; cuerpo.posx = punta.posx1-cuerpo.ancho; cuerpo.posy = punta.posy - (int)punta.alto/2; cola.posicionar(cuerpo); ala_superior.ajustarse("ala_superior", cuerpo); ala_inferior.ajustarse("ala_inferior", cuerpo); colita = cola.devolver_grafica(); puntica = punta.devolver_grafica(); cuerpito = cuerpo.devolver_grafica(); alita_arriba = ala_superior.devolver_grafica(); alita_abajo = ala_inferior.devolver_grafica(); for(int i = 0; i<4; i++){ for(int j = 0; j<4; j++){ matriz[i][j] = colita[i][j]; } // Cierra for interno for(int k = 0; k<4; k++){ matriz[i+4][k] = cuerpito[i][k]; } // Cierra for interno for(int m = 0; m<3; m++){ matriz[m+8][i] = puntica[m][i]; } // Cierra for interno for(int n = 0; n<3; n++){ matriz[n+11][i] = alita_arriba[n][i]; } // Cierra for interno for(int p = 0; p<3; p++){ matriz[p+14][i] = alita_abajo[p][i]; } // Cierra for interno } // Cierra for externo return matriz; } // Cierra devolver_grafica public void moverse(){ x = x+8; }// Cierra void moverse } // Cierra class avion canvitas.java import java.awt.*; import java.awt.event.*; import java.applet.*; public class canvitas extends Canvas{ Graphics gra; int pintar = 0; int puntos[][]; int apariciones = 100; avion referencia_avion; public void pintar(avion obj_volador){ puntos = obj_volador.devolver_grafica(); referencia_avion = obj_volador; repaint(); } // Cierra pintar public void paint(Graphics g){ this.gra = g; g.setColor(Color.blue); while(apariciones>0){ referencia_avion.moverse(); referencia_avion.alejarse(); referencia_avion.ascender(); puntos = referencia_avion.devolver_grafica(); g.setColor(Color.blue); for(int i = 0; i<17; i++){ g.drawLine(puntos[i][0], puntos[i][1], puntos[i][2], puntos[i][3]); } try{ Thread.sleep(40); } catch(InterruptedException e){ } // Cierra catch g.setColor(Color.yellow); for(int i = 0; i<17; i++){ g.drawLine(puntos[i][0], puntos[i][1], puntos[i][2], puntos[i][3]); } setBackground(Color.yellow); g.drawString("ESTO ES EL CANVAS", 200,300); apariciones--; } // Cierra while } // Cierra public void paint } // Cierra class canvitas MyApp.java import java.awt.*; import java.awt.event.*; public class MyApp extends Frame { canvitas tablero = new canvitas(); avion avioncito = new avion(); int apariciones = 500; public MyApp() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); add(tablero); tablero.pintar(avioncito); } public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(960,600); f.show(); } } rectangulo.java import java.awt.*; import java.applet.*; public class rectangulo{ Graphics h; int posx, posy, ancho, alto; int rectangulillo[][] = new int[4][4]; public rectangulo(){ } // Cierra public rectangulo public int[][] devolver_grafica(){ rectangulillo[0][0] = posx; rectangulillo[0][1] = posy; rectangulillo[0][2] = posx+ancho; rectangulillo[0][3] = posy; rectangulillo[1][0] rectangulillo[1][1] rectangulillo[1][2] rectangulillo[1][3] = = = = posx; posy; posx; posy+alto; rectangulillo[2][0] rectangulillo[2][1] rectangulillo[2][2] rectangulillo[2][3] = = = = posx+ancho; posy; posx+ancho; posy+alto; rectangulillo[3][0] = posx; rectangulillo[3][1] = posy+alto; rectangulillo[3][2] = posx+ancho; rectangulillo[3][3] = posy+alto; return rectangulillo; } // Cierra int[][] devolver_grafica public int posicion_derecha(){ return posx+ ancho; } // Cierra int posicion_derecha public int posicion_superior(){ return posy; } // Cierra int posicion_superior public int posicion_inferior(){ return posy+alto; } // Cierra int posicion_inferior public void posicionar(rectangulo rect){ ancho = (int)rect.ancho/5; alto = rect.alto*3; posx = rect.posx -ancho; posy = rect.posy - (rect.alto); } // Cierra mover_derecha public void actualizar_rectangulo(int x, int y, int ancho, int alto){ posx = x; posy = y; this.ancho = ancho; this.alto = alto; } // Cierra public rectangulo public void alargar(int valor){ ancho = ancho + valor; } // Cierra alargar public void adelgazar(int valor){ alto = alto - valor; } // Cierra adelgargar } // Cierra class rectangulo triangulo.java import java.applet.*; public class triangulo{ int posx; int posy; int int int int int int posx1; posy1; posx2; posy2; pos[][] = new int[3][4]; alto; public int[][] devolver_grafica(){ pos[0][0] = posx; pos[0][1] = posy; pos[0][2] = posx1; pos[0][3] = posy1; pos[1][0] pos[1][1] pos[1][2] pos[1][3] = = = = posx; posy; posx2; posy2; pos[2][0] pos[2][1] pos[2][2] pos[2][3] = = = = posx1; posy1; posx2; posy2; return pos; } // Cierra int[][] devolver_grafica public void ajustarse(String tipo){ if(tipo.equals("punta")){ posx1 = posx - (int)alto; posy1 = posy - (int)alto/2; posx2 = posx - (int)alto; posy2 = posy + (int)alto/2; System.out.println("posx = "+ posx ); System.out.println("posy = "+ posy ); System.out.println("posx1 = "+ posx1 ); System.out.println("posy1 = "+ posy1 ); System.out.println("posx2 = "+ posx2 ); System.out.println("posy2 = "+ posy2 ); } }// Cierra if tipo == "punta" public void ajustarse(String tipo, rectangulo body){ if(tipo.equals("ala_superior")){ posy = body.posy - body.alto*2; posx = body.posx + (int )body.ancho/3; posx1 = body.posx + (int)body.ancho/3 + (int)body.ancho/6; posy1 = body.posy; posx2 = body.posx + (int)body.ancho/3 + (int)body.ancho/3; posy2 = body.posy; }// Cierra if tipo == "ala_superior" if(tipo.equals("ala_inferior")){ posy = body.posy + body.alto + body.alto*2; posx = body.posx + (int )body.ancho/3; posx1 = body.posx + (int)body.ancho/3 + (int)body.ancho/6; posy1 = body.posy + body.alto; posx2 = body.posx + (int)body.ancho/3 + (int)body.ancho/3; posy2 = body.posy + body.alto; System.out.println("ESTOY EN EL FI"); System.out.println("posx = "+ posx); System.out.println("posy = "+ posy); System.out.println("posx1 = "+ posx1); System.out.println("posy1 = "+ posy1); System.out.println("posx2 = "+ posx2); System.out.println("posy2 = "+ posy2); }// Cierra if tipo == "ala_superior" } // Cierra void ajustarse public triangulo(){ } // Cierra triangulo } // Cierra class triangulo 20.3. EJECUCIÓN DEL PROGRAMA Inicialmente el programa aparece el avión de la siguiente manera: Y a medida que pasa el tiempo se va elevando el avión, tal como se muestra en la siguiente gráfica: Finalmente el avión llega a un punto en el que alcanza la altura máxima y continúa volando. 21. LA CLONACION DE OBJETOS La clonación es uno de los temas que mas se olvida a la hora de trabajar con aplicaciones JAVA, pero es uno de los temas que estudiándolos a profundidad dan la fundamentación para hacer aplicaciones de gran versatilidad, distribuidas y sobretodo aplicaciones que conserven estados de objetos, que manejen mayor seguridad al tener objetos que conservan el estado en el que se encontraba otro objeto cuando se le clono. En pocas palabras podemos pensar que la clonación trae muchas ventajas que por lo general no son tan claras, ni tan evidentes, pero que abren la puerta hacia mejores y mas robustas aplicaciones JAVA. 21.1. COPIA DE OBJETOS LIMITADA Uno de los problemas más interesantes de la programación orientada a objetos es el tema de la copia de objetos. Supongamos que creamos un objeto llamado “origen” (“El programa completo se muestra al final de esta sección”) que es de la clase “Original”, podríamos pensar que este objeto en su ciclo de vida sufre en algún momento algunas modificaciones en sus atributos y en fin en sus estados, cosa que es inherente a todo objeto. La cuestión que nos interesa es que después de saber que el objeto “origen” ya ha cambiado de estado, se desea hacer una copia de dicho objeto, pero que la copia sea completa, es decir que el nuevo objeto tenga los valores que tenia el objeto copiado. Esto aparentemente es algo sencillo que eventualmente se podría solucionar de cualquier forma, pero es importante que el amigo lector / estudiante comprenda que la solución planteada en esta sección es bastante limitada y no será muy útil cuando los objetos que se deseen duplicar tengan una complejidad mayor. Por el momento decimos que tenemos una clase “Original” que tiene el siguiente código fuente: public class Original{ int parametro1 = 1; int parametro2 = 2; int parametro3 = 3; int parametro4 = 4; boolean estado = true; public void printPar1(){ System.out.println("Parametro 1 = "+parametro1); } // Cierra setParametro1 public void printPar2(){ System.out.println("Parametro 2 = "+parametro2); } // Cierra setParametro1 public void printPar3(){ System.out.println("Parametro 3 = "+parametro3); } // Cierra setParametro1 public void printPar4(){ System.out.println("Parametro 4 = "+parametro4); } // Cierra setParametro1 public void printEstado(){ if(estado){ System.out.println("Estado = true"); } else{ System.out.println("Estado = false"); } } public void cambiarEstado(){ if(estado){ estado = false; } else{ estado = true; } } public void printParametros(String objetin){ System.out.println("Parametros de "+objetin); printPar1(); printPar2(); printPar3(); printPar4(); printEstado(); } // Cierra void printParametros() public void modificarParametros(){ parametro1 = 10; parametro2 = 20; parametro3 = 30; parametro4 = 40; cambiarEstado(); } // Cierra void modificarParametros() public Object copiar(){ // Original objOriginal = new Original(); Original objOriginal = this; System.out.println("Copiando objeto"); Original retornar = new Original(); retornar.parametro1 = objOriginal.parametro1; retornar.parametro2 = objOriginal.parametro2; retornar.parametro3 = objOriginal.parametro3; retornar.parametro4 = objOriginal.parametro4; retornar.estado = objOriginal.estado; return retornar; } // Cierra void copiar() } // Cierra class Original En la cual encontramos que se tienen cinco atributos a saber: “Parametro1”, “Parametro2”, “Parametro3”, “Parametro4” y “estado”, los cuales tienen inicialmente los siguientes valores: parámetro parametro1 parametro2 parametro3 parametro4 estado Valor 1 2 3 4 true Decimos que queremos modificar los atributos de dicho objeto y esto se hace ejecutando del código anterior las siguientes instrucciones: Es decir ejecutando las instrucciones parametro1 parametro2 parametro3 parametro4 = = = = 10; 20; 30; 40; junto con las instrucciones: public void cambiarEstado(){ if(estado){ estado = false; } else{ estado = true; } } Obviamente estas instrucciones cambian el estado del objeto “ObjOriginal” definido en el método “ejecutarCopia()”: public void ejecutarCopia(){ Original origen = new Original(); origen.printParametros("Original "); origen.modificarParametros(); origen.printParametros("Original "); Original destino; destino = (Original)origen.copiar(); destino.printParametros("Destino "); } // Cierra void ejecutarCopia() Y este es precisamente el método que tiene toda la lógica del programa que queremos explicar. El programa crea el objeto llamado “origen”: Original origen = new Original(); Después de lo cual imprime los datos de dicho objeto, con lo cual se produce por la vista consola una salida que muestra los datos contenidos en la siguiente tabla: parámetro parametro1 parametro2 parametro3 parametro4 estado Valor 1 2 3 4 true Después modifica los parámetros del mencionado objeto, con lo cual modifica el estado del objeto cuando ejecuta la instrucción: origen.modificarParametros(); La cual modifica los parámetros expuestos en la anterior tabla y luego se vuelven a imprimir los parámetros del mismo objeto para tener la certeza que realmente se han cambiado los parámetros del objeto tal como venían desde la creación del objeto. Esto se logra con las instrucciones: public void modificarParametros(){ parametro1 = 10; parametro2 = 20; parametro3 = 30; parametro4 = 40; cambiarEstado(); } // Cierra void modificarParametros() Y para tener la certeza que efectivamente se han cambiado los parámetros del objeto, se imprimen nuevamente los parámetros del objeto “origen”: public void ejecutarCopia(){ Original origen = new Original(); origen.printParametros("Original "); origen.modificarParametros(); origen.printParametros("Original "); Original destino; destino = (Original)origen.copiar(); destino.printParametros("Destino "); } // Cierra void ejecutarCopia() Con lo cual se producen unos resultados por consola similar a los mostrados en la siguiente tabla: parámetro parametro1 parametro2 parametro3 parametro4 estado Valor 10 20 30 40 false Y finalmente se saca una copia al objeto “origen”, invocando el método “copiar()” del mencionado objeto. public void ejecutarCopia(){ Original origen = new Original(); origen.printParametros("Original "); origen.modificarParametros(); origen.printParametros("Original "); Original destino; destino = (Original)origen.copiar(); destino.printParametros("Destino "); } // Cierra void ejecutarCopia() El procedimiento de copia crea un objeto nuevo llamado “destino” con los atributos que aparecen en la declaración de la clase del objeto, es decir con los datos: parámetro parametro1 parametro2 parametro3 parametro4 estado Valor 1 2 3 4 true Pero para simular que la copia es del objeto llamado “original” es cierta, se copian uno a uno los valores de los atributos del objeto “original” al objeto “destino”. Lo cual se encuentra en el método copiar: public Object copiar(){ // Original objOriginal = new Original(); Original objOriginal = this; System.out.println("Copiando objeto"); Original retornar = new Original(); retornar.parametro1 = objOriginal.parametro1; retornar.parametro2 = objOriginal.parametro2; retornar.parametro3 = objOriginal.parametro3; retornar.parametro4 = objOriginal.parametro4; retornar.estado = objOriginal.estado; return retornar; } // Cierra void copiar() Claro, la pregunta que viene es: ¿Qué pasa si el numero de atributos es mas grande?. La respuesta podría ser aumentar el numero de instrucciones en nuestro programa que ejecute estas instrucciones, pero la verdad hay otras soluciones mejores como la de crear un vector con los valores iniciales, para que al modificarlos, será simple cosa de hacer un ciclo “for”. Obviamente esta solución es bastante limitada debido a que si el tipo de atributos del objeto son variados, la cuestión es un poco mas compleja, pero si el objeto a su vez esta conformado por objetos internos que tienen un estado particular, la cuestión de sacarle copia a un objeto será cosa bastante complicada. Y para finalizar la explicación es bueno tener en cuenta que el programa completo al que estamos haciendo referencia en esta sección es el siguiente: /****************************************************************** Nombre : CopiaObjetos.java Descripcion : El siguiente programa muestra como se : pueden sacar copias de objetos en forma : manual y artesanal Tipo: : No Maneja apuntadores, maneja referencias : Es de tipo AUTONOMO : El programa no usa la interfaz CLONABLE : para sacar copias de objetos Autor : Luis Felipe Wanumen [email protected] Revision : No hay revisiones por el momento. Agradecimientos : No hay D.Historico : 03/08/2007 ******************************************************************/ import java.awt.*; import java.awt.event.*; public class CopiaObjetos extends Frame { public class Original{ int parametro1 = 1; int parametro2 = 2; int parametro3 = 3; int parametro4 = 4; boolean estado = true; public void printPar1(){ System.out.println("Parametro 1 = "+parametro1); } // Cierra setParametro1 public void printPar2(){ System.out.println("Parametro 2 = "+parametro2); } // Cierra setParametro1 public void printPar3(){ System.out.println("Parametro 3 = "+parametro3); } // Cierra setParametro1 public void printPar4(){ System.out.println("Parametro 4 = "+parametro4); } // Cierra setParametro1 public void printEstado(){ if(estado){ System.out.println("Estado = true"); } else{ System.out.println("Estado = false"); } } public void cambiarEstado(){ if(estado){ estado = false; } else{ estado = true; } } public void printParametros(String objetin){ System.out.println("Parametros de "+objetin); printPar1(); printPar2(); printPar3(); printPar4(); printEstado(); } // Cierra void printParametros() public void modificarParametros(){ parametro1 = 10; parametro2 = 20; parametro3 = 30; parametro4 = 40; cambiarEstado(); } // Cierra void modificarParametros() public Object copiar(){ // Original objOriginal = new Original(); Original objOriginal = this; System.out.println("Copiando objeto"); Original retornar = new Original(); retornar.parametro1 = objOriginal.parametro1; retornar.parametro2 = objOriginal.parametro2; retornar.parametro3 = objOriginal.parametro3; retornar.parametro4 = objOriginal.parametro4; retornar.estado = objOriginal.estado; return retornar; } // Cierra void copiar() } // Cierra class Original public void ejecutarCopia(){ Original origen = new Original(); origen.printParametros("Original "); origen.modificarParametros(); origen.printParametros("Original "); Original destino; destino = (Original)origen.copiar(); destino.printParametros("Destino "); } // Cierra void ejecutarCopia() public CopiaObjetos() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); } // Cierra CopiaObjetos() public static void main(String args[]) { System.out.println("Starting App"); CopiaObjetos f = new CopiaObjetos(); f.setSize(100,100); f.setVisible(true); f.ejecutarCopia(); } // Cierra void main } Y para lograr la mayor comprensión de este tema, a continuación se muestran los resultados obtenidos de la ejecución del programa anterior: Starting App Parametros de Original Parametro 1 = 1 Parametro 2 = 2 Parametro 3 = 3 Parametro 4 = 4 Estado = true Parametros de Original Parametro 1 = 10 Parametro 2 = 20 Parametro 3 = 30 Parametro 4 = 40 Estado = false Copiando objeto Parametros de Destino Parametro 1 = 10 Parametro 2 = 20 Parametro 3 = 30 Parametro 4 = 40 Estado = false En el cual queda claro que los datos del objeto “original” eran inicialmente los siguientes: OBJETO “ORIGINAL” VALOR PARÁMETRO parametro1 1 parametro2 2 parametro3 3 parametro4 4 Estado true Se modificaron artesanalmente los datos del objeto en cuestión y se obtuvieron los siguientes datos: OBJETO “ORIGINAL” VALOR PARÁMETRO parametro1 10 parametro2 20 parametro3 30 parametro4 40 Estado false Y después de ello se saco una copia del objeto “ORIGINAL” en el objeto “DESTINO”, con lo cual al imprimir los datos del nuevo objeto creado se obtuvieron los siguientes resultados: OBJETO “DESTINO” VALOR PARÁMETRO parametro1 10 parametro2 20 parametro3 30 parametro4 40 Estado false En el caso del presente ejercicio, era factible sacarle una copia al objeto debido a que los elementos que contenían se les podía sacar copia, pero el problema es cuando los atributos que tiene un objeto no son tan sencillos como del ejercicio en cuestión. 21.2. COPIAR OBJETOS CON INTERFAZ CLONEABLE La sección anterior mostraba un ejercicio en el cual se podía sacar una copia a un objeto sin necesidad de hacer cosas extrañas, pero la verdad es muy posible que en aplicaciones reales los objetos tengan una complejidad mas grande, que hagan que sus atributos sean tan complejos que sacarle una copia a dicho objeto sea cosa complicada. Para solucionar esta problemática, JAVA incorpora en sus APIS la posibilidad de usar la interfaz “Cloneable”. El siguiente ejercicio muestra como hacer la copia del ejemplo de la sección anterior, pero esta vez usando la interfaz “Cloneable”, veamos: /****************************************************************** Nombre : Cloncito.java Descripcion : El siguiente programa muestra como se : pueden sacar copias de objetos al estilo : JAVA, es decir usando las APIS de JAVA : para este proposito. Tipo: : No Maneja apuntadores, maneja referencias : Es de tipo AUTONOMO : El programa usa la interfaz CLONABLE : para sacar copias de objetos Autor : Luis Felipe Wanumen [email protected] Revision : No hay revisiones por el momento. Agradecimientos : No hay D.Historico : 03/08/2007 ******************************************************************/ import java.awt.*; import java.awt.event.*; public class Cloncito extends Frame { public class Original implements Cloneable{ int parametro1 = 1; int parametro2 = 2; int parametro3 = 3; int parametro4 = 4; boolean estado = true; public void printPar1(){ System.out.println("Parametro 1 = "+parametro1); } // Cierra setParametro1 public void printPar2(){ System.out.println("Parametro 2 = "+parametro2); } // Cierra setParametro1 public void printPar3(){ System.out.println("Parametro 3 = "+parametro3); } // Cierra setParametro1 public void printPar4(){ System.out.println("Parametro 4 = "+parametro4); } // Cierra setParametro1 public void printEstado(){ if(estado){ System.out.println("Estado = true"); } else{ System.out.println("Estado = false"); } } public void cambiarEstado(){ if(estado){ estado = false; } else{ estado = true; } } public void printParametros(String objetin){ System.out.println("Parametros de "+objetin); printPar1(); printPar2(); printPar3(); printPar4(); printEstado(); } // Cierra void printParametros() public void modificarParametros(){ parametro1 = 10; parametro2 = 20; parametro3 = 30; parametro4 = 40; cambiarEstado(); } // Cierra void modificarParametros() public Object copiar(){ // Original objOriginal = new Original(); Original objOriginal = this; System.out.println("Copiando objeto"); Object retornar; try{ Object objeto = (Original)objOriginal.clone(); retornar = objeto; return retornar; } catch(Exception e){ return null; } } // Cierra void copiar() public Object Clone(){ try{ return super.clone(); } catch(CloneNotSupportedException e){ return null; } } // Cierra public Object Clone } // Cierra class Original public void ejecutarClonacion(){ Original origen = new Original(); origen.printParametros("Original "); origen.modificarParametros(); origen.printParametros("Original "); Original destino; destino = (Original)origen.copiar(); destino.printParametros("Destino "); } public Cloncito() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); } // Cierra Cloncito() public static void main(String args[]) { System.out.println("Starting App"); Cloncito f = new Cloncito(); f.setSize(100,100); f.setVisible(true); f.ejecutarClonacion(); } // Cierra void main } Observe amigo lector / estudiante que en el ejemplo anterior no hay necesidad de sacarle copia a cada uno de los atributos que componen el objeto “original”, debido a que la interfaz “Cloneable” se encarga de hacer esta labor. Es interesante observar que el tipo de elementos que componen al objeto que se le va a sacar un clon, no hay que programarlo y esto se vuelve una labor transparente al programador. A manera de aclarar la ejecución del programa anterior, a continuación se muestran los resultados generados por el mencionado: Starting App Parametros de Original Parametro 1 = 1 Parametro 2 = 2 Parametro 3 = 3 Parametro 4 = 4 Estado = true Parametros de Original Parametro 1 = 10 Parametro 2 = 20 Parametro 3 = 30 Parametro 4 = 40 Estado = false Copiando objeto Parametros de Destino Parametro 1 = 10 Parametro 2 = 20 Parametro 3 = 30 Parametro 4 = 40 Estado = false Exit code: 0 21.3. LA INTERFAZ CLONEABLE ABARCA SUBOBJETOS Cuando se clona un objeto, tambien se estan clonando los subobjetos que se encuentran dentro de dicho objeto. Para aclarar este concepto, a continuación se añade al ejemplo de la seccion anterior un subobjeto para verificar si la clonacion cobija a los subobjetos del objeto clonado. Veamos pues el programa modificado: /****************************************************************** Nombre : Cloncito1.java Descripcion : El siguiente programa muestra como se : pueden sacar copias de objetos al estilo : JAVA, es decir usando las APIS de JAVA : para este proposito. Tipo: : No Maneja apuntadores, maneja referencias : Es de tipo AUTONOMO : El programa usa la interfaz CLONABLE : para sacar copias de objetos Autor : Luis Felipe Wanumen [email protected] Revision : No hay revisiones por el momento. Agradecimientos : No hay D.Historico : 03/08/2007 ******************************************************************/ import java.awt.*; import java.awt.event.*; public class Cloncito1 extends Frame { public class Original implements Cloneable{ int parametro1 = 1; int parametro2 = 2; int parametro3 = 3; int parametro4 = 4; public class Interna{ int p1 = 11; int p2 = 22; int p3 = 33; } // Cierra class Interna Interna objInterno = new Interna(); boolean estado = true; public void printPar1(){ System.out.println("Parametro 1 = "+parametro1); } // Cierra setParametro1 public void printPar2(){ System.out.println("Parametro 2 = "+parametro2); } // Cierra setParametro1 public void printPar3(){ System.out.println("Parametro 3 = "+parametro3); } // Cierra setParametro1 public void printPar4(){ System.out.println("Parametro 4 = "+parametro4); } // Cierra setParametro1 public void printEstado(){ if(estado){ System.out.println("Estado = true"); } else{ System.out.println("Estado = false"); } } // Cierra public void printEstado() public void cambiarEstado(){ objInterno.p1 = 111; objInterno.p2 = 222; objInterno.p3 = 333; if(estado){ estado = false; } else{ estado = true; } } // Cierra cambiarEstado() public void printParametros(String objetin){ System.out.println("Parametros de "+objetin); printPar1(); printPar2(); printPar3(); printPar4(); printEstado(); System.out.println("ATRIBUTOS DEL OBJETO INTERNO"); System.out.println("p1 = "+objInterno.p1); System.out.println("p2 = "+objInterno.p2); System.out.println("p3 = "+objInterno.p3); } // Cierra void printParametros() public void modificarParametros(){ parametro1 = 10; parametro2 = 20; parametro3 = 30; parametro4 = 40; cambiarEstado(); } // Cierra void modificarParametros() public Object copiar(){ // Original objOriginal = new Original(); Original objOriginal = this; System.out.println("Copiando objeto"); Object retornar; try{ Object objeto = (Original)objOriginal.clone(); retornar = objeto; return retornar; } catch(Exception e){ return null; } } // Cierra void copiar() public Object Clone(){ try{ return super.clone(); } catch(CloneNotSupportedException e){ return null; } } // Cierra public Object Clone } // Cierra class Original public void ejecutarClonacion(){ Original origen = new Original(); origen.printParametros("Original "); origen.modificarParametros(); origen.printParametros("Original "); Original destino; destino = (Original)origen.copiar(); destino.printParametros("Destino "); } public Cloncito1() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); } // Cierra Cloncito() public static void main(String args[]) { System.out.println("Starting App"); Cloncito1 f = new Cloncito1(); f.setSize(100,100); f.setVisible(true); f.ejecutarClonacion(); } // Cierra void main } El cual produce el siguiente resultado: Starting App Parametros de Original Parametro 1 = 1 Parametro 2 = 2 Parametro 3 = 3 Parametro 4 = 4 Estado = true ATRIBUTOS DEL OBJETO INTERNO p1 = 11 p2 = 22 p3 = 33 Parametros de Original Parametro 1 = 10 Parametro 2 = 20 Parametro 3 = 30 Parametro 4 = 40 Estado = false ATRIBUTOS DEL OBJETO INTERNO p1 = 111 p2 = 222 p3 = 333 Copiando objeto Parametros de Destino Parametro 1 = 10 Parametro 2 = 20 Parametro 3 = 30 Parametro 4 = 40 Estado = false ATRIBUTOS DEL OBJETO INTERNO p1 = 111 p2 = 222 p3 = 333 Exit code: 0 Con lo cual vemos que los valores del subojeto eran inicialmente: p1 = 11 p2 = 22 p3 = 33 y fueron modificados intencionalmente por los siguientes en su objeto “ORIGEN”: p1 = 111 p2 = 222 p3 = 333 pero lo interesante del asunto es que el objeto “DESTINO”, cuando se imprimen los valores de los subobjetos, también tiene en cuenta el subobjeto. Con todo esto se puede concluir que la clonación, tiene grandes ventajas cuando de sacarle copia a objetos complejos se trate. De tarea se deja al amigo / lector estudiante para compruebe por su propia cuenta que la clonación cobija a cualquier atributo de objeto incluido en la clase a ser clonable. 22. CLASES TIPO OBSERVER Y OBSERVABLE En el lenguaje JAVA, existen unas APIS que permiten crear nuestras propias clases que puedan ser observadas por otras clases, a este tipo de clases se les conoce con el nombre de clases “OBSERVABLE”, también existen clases que observan a las clases anteriormente mencionadas y a este tipo de clases se les denomina clases tipo “OBSERVER”. 22.1. ESTRUCTURA DE LAS CLASES OBSERVABLES Una de las características de las clases observables es que extienden de la clase Observable que se encuentra en el paquete “java.util”. Por lo general esta clase contiene propiedades del tipo “set” y “get” seguidas de un nombre con el fin de establecer y devolver los valores de dicha clase. Un ejemplo de una clase tipo “Observable” es la siguiente: import java.util.Observable; public class Persona extends Observable { private int edad; public Persona(){ edad = 0; } public int getEdad(){ return edad; } public void crecer(){ System.out.println("La edad era: "+edad); setEdad(getEdad()+1); System.out.println("La edad ahora es: "+edad); } // Propiedad para asignar el valor de la edad // Las clases que estan pendientes de cambios en edad // son notificadas de dicho cambio. public void setEdad(int edad) { this.edad = edad; setChanged(); notifyObservers(); } } // Cierra class Persona 22.2. ESTRUCTURA DE LAS CLASES OBSERVER Las clases tipo “OBSERVER” implementan de la clase “OBSERVER” que se encuentra en el paquete “java.util”, tienen principalmente un método que las caracteriza que es el método “update()”, el cual se ejecuta cuando la clase “OBSERVABLE” modifica su valor o sufre un cambio de estado. Un ejemplo de una clase “OBSERVER” es la siguiente: import java.util.Observer; import java.util.Observable; public class ObservadorPersona implements Observer{ private Persona personaObservable=null; private Observacion refVentana; public ObservadorPersona(Persona personaObservable){ this.personaObservable = personaObservable; } public void update(Observable observable, Object objeto){ if(observable == personaObservable){ this.refVentana.ta.setText("Edad vista por el observador: "+personaObservable.getEdad()); } } public void setVentana(Observacion refVentana){ this.refVentana = refVentana; } } // Cierra class ObservadorPersona 22.3. CREACION DE OBJETOS DE TIPO OBSERVER Y OBSERVABLE Supongamos que basados en las clases de las anteriores dos secciones creamos un objeto llamado “luisfelipe” de tipo “Persona” y otro objeto llamado “chismoso” de tipo “ObservadorPersona”, tendríamos que la creación de estos objetos se podría hacer tal como se muestra a continuación: public Persona luisfelipe = null; public Persona luisfelipe = null; luisfelipe = new Persona(); chismoso = new ObservadorPersona(luisfelipe); 22.4. VINCULACION DEL OBJETO OBSERVABLE AL OBJETO OBSERVER En la anterior sección se han creado los objetos de tipo “OBSERVER” y de tipo “OBSERVABLE”, pero en ningún momento se ha especificado que el objeto llamado “chismoso” es capaz de observar concretamente al objeto llamado “luisfelipe” esto se logra mediante la instrucción: luisfelipe.addObserver( chismoso ); 22.5. UN EJEMPLO COMPLETO CON OBSERVER Y OBSERVABLE Basados en las clases de las anteriores secciones relacionadas con objetos tipo “OBSERVER” y objetos tipo “OBSERVABLE”, vamos a mostrar un ejemplo completo que muestra el uso de este tipo de clases. Archivo llamado: “Observacion.java” import java.awt.*; import java.awt.event.*; public class Observacion extends Frame { public Persona luisfelipe = null; public static EventoModificarPersona evento = null; public Button b1; public TextField caja1; public TextArea ta; public Persona luisfelipe = null; public Observacion () { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); caja1 = new TextField(20); b1 = new Button("Crecer"); Panel panel1 = new Panel(); ta = new TextArea(); evento = new EventoModificarPersona(); // panel1.setLayout(new GridLayout(2,4)); add(panel1); panel1.add(caja1); panel1.add(b1); panel1.add(ta); luisfelipe = new Persona(); chismoso = new ObservadorPersona(luisfelipe); luisfelipe.addObserver( chismoso ); b1.addActionListener(evento); } public static void main(String args[]) { System.out.println("Starting App"); Observacion f = new Observacion (); f.setSize(200,200); f.setVisible(true); evento.setVentana(f ); chismoso.setVentana(f); } } Archivo llamado: “EventoModificarPersona.java” import java.awt.event.*; public class EventoModificarPersona implements ActionListener{ Observacion ventana = null; public void actionPerformed(ActionEvent ev){ if(ev.getSource()==ventana.b1){ int edadcilla = ventana.luisfelipe.getEdad(); ventana.caja1.setText("Edad vista por el evento "+edadcilla); ventana.luisfelipe.crecer(); System.out.println("Ejecutado EVENTO"); } } // Cierra void actionPerformed public void setVentana(Observacion ref){ ventana = ref; } } // Cierra class EventoModificarPersona Archivo llamado: “ObservadorPersona.java” import java.util.Observer; import java.util.Observable; public class ObservadorPersona implements Observer{ private Persona personaObservable=null; private Observacion refVentana; public ObservadorPersona(Persona personaObservable){ this.personaObservable = personaObservable; } public void update(Observable observable, Object objeto){ if(observable == personaObservable){ this.refVentana.ta.setText("Edad vista por el observador: "+personaObservable.getEdad()); } } public void setVentana(Observacion refVentana){ this.refVentana = refVentana; } } // Cierra class ObservadorPersona Archivo llamado: “Persona.java” import java.util.Observable; public class Persona extends Observable { private int edad; public Persona(){ edad = 0; } public int getEdad(){ return edad; } public void crecer(){ System.out.println("La edad era: "+edad); setEdad(getEdad()+1); System.out.println("La edad ahora es: "+edad); } // Propiedad para asignar el valor de la edad // Las clases que estan pendientes de cambios en edad // son notificadas de dicho cambio. public void setEdad(int edad) { this.edad = edad; setChanged(); notifyObservers(); } } // Cierra class Persona La ejecución del anterior programa produce una interfaz similar a la siguiente: Cuando se hace click sobre el botón con la etiqueta “crecer” se producen inicialmente los siguientes resultados: En la cual queda bien claro que el valor antes de ser modificado y visto por el evento es el valor “0”, pero el valor visto por el observador es “1”, debido a que este observador es notificado del cambio justamente después de modificado el valor de la variable “edad” en la clase “Persona”. 22.6. PREGUNTAS SOBRE OBSERVER Y OBSERVABLE En esta sección se muestran una serie de preguntas que pretenden comprobar que tan afianzados han quedado los conocimientos sobre el tema de clases tipo “OBSERVER” y tipo “OBSERVABLE”, veamos pues las preguntas: 1. ¿Es posible crear eventos en Java, sin usar las clases que tiene dicho lenguaje para tal fin, simplemente haciendo uso de las clases tipo “OBSERVER” y “OBSERVABLE”? 2. ¿Según lo visto en la sección sobre “OBSERVER” y OBSERVABLE“ es posible que un objeto tipo “OBSERVABLE” este asociado con varios “OBSERVER”? 3. ¿Es posible crear un solo objeto “OBSERVER” que observe a varios objetos “OBSERVABLES”, pero que dependiendo del objeto que halla sido modificado en su estado se comporte? Si responde afirmativamente a la afirmación: ¿Cómo haría un programa que implemente dicha funcionalidad? 4. Suponga un programa que tiene una clase que accede a un archivo plano y que dicha clase es usada por varios clientes del aplicativo. Se quiere tener acceso solamente al archivo por parte de un solo usuario y hasta que dicho usuario no halla desocupado y liberado los recursos relacionados con el acceso a dicho archivo no se puede permitir que otro usuario acceda a dicho archivo. También se quiere que la adjudicación sobre el uso del archivo se entregue por orden de entrada de los diversos usuarios al sistema. Explique mediante un grafico como implementaría una solución de este tipo usando clases tipo “OBSERVER” y clases tipo “OBSERVABLE”. 5. ¿Qué otras aplicaciones le ha encontrado a las clases “OBSERVER” y “OBSERVABLE” vistas en la unidad? 23. COMO DELEGAR CLASES 23.1. PLANTEAMIENTO TEORICO DE LA DELEGACION Imagínese por un momento que tengo una clase llamada “MAMIFERO”, de tal suerte que al momento de su creación se comporta como si fuera un “PERRO”. Esto se logra si tenemos una clase llamada “ANIMAL” que fuerce a que los que sean de este tipo implementen dicha funcionalidad. En términos de UML podríamos colocar esta situación tal como se muestra en el siguiente diagrama de clases: Y para lograr que se presente la condición de inicio que al momento de creación de un “MAMIFERO”, este se comporte como si fuese un “PERRO”, tendríamos que hacer un constructor en la clase “MAMIFERO” que defina una referencia a un objeto de tipo “ANIMAL” y se lo asigne a un objeto tipo “PERRO”. En términos de UML, vamos a colocar el constructor y diremos que el código colocado en método constructor de la clase “MAMIFERO” será el siguiente: public Mamifero() { super(); i=new Perro(); } Recordemos que la relación en UML que se coloca es la relación de realización que se simboliza con una flecha punteada y terminada en un triangulo sin rellenar que significa que la clase “MAMIFERO” implementa la funcionalidad especificada en la clase “ANIMAL”. Tambien es bueno mencionar que la clase “MAMIFERO” debe estar asociada con una relación de dependencia a la clase “PERRO”. Esto se coloca en UML, mediante el siguiente diagrama: Recordemos que la relación es dependencia debido a que la línea es punteada y la flecha es abierta. No es complicado pensar que la reacion sea de dependencia puesto que el objeto tipo “PERRO” debe poderse crear antes que se cree el objeto tipo “MAMIFERO” debido a que esta creación se especifica en el constructor de la clase “MAMIFERO” y como es bien sabido, si no se puede ejecutar el constructor, no se puede crear el objeto. De otra parte lo que se pretende hacer es tener un objeto que sea de un tipo por ejemplo en este caso que sea de tipo ”MAMIFERO” y concretamente que se comporte como si fuera un “PERRO”, pero que en tiempo de ejecución y en forma dinámica se pueda cambiar su tipo y pueda llegar a ser incluso de tipo “HUMANO”, lo cual obliga obviamente a que tanto la clase “PERRO” como la clase “ANIMAL” deben compartir una cierta funcionalidad y en este caso la funcionalidad compartida se especifica mediante la implementación de la clase “ANIMAL” por parte de ambas clases. En pocas palabras tenemos a nivel de UML, la siguiente situación: Ahora bien, queremos que cuando se cambie el tipo de objeto en tiempo de ejecución este cambio sea lo mas transparente para el sistema. En pocas palabras queremos que el objeto de tipo “MAMIFERO” pueda invocar un método que lo convierta a un objeto tipo “HUMANO” y también que le permita en un momento dado convertirse nuevamente en un objeto tipo “PERRO”. Para lograr esta funcionalidad tendríamos que definir dos métodos adicionales en la clase “MAMIFERO” que permitan hacer estas alteraciones en tiempo de ejecución y esta situación a nivel de UML se muestra a continuación: En donde los métodos “toPerro” y “toHombre” hagan uso de una variable tipo “interfaz” por ejemplo llamada “i” que pueda ser reasignada en tiempo de ejecución para el caso del método “toPerro” tal como se muestra a continuación: void toPerro() { i = new Perro(); } y para el metodo “toHombre”, como sigue en la siguiente línea: void toHombre() { i = new Hombre(); } 23.2. EJERCICIO PRÁCTICO SOBRE DELEGACION Para lograr la completa comprensión de la sección anterior sobre la delegación, vamos a continuación a mostrar el código completo de una aplicación que implementa la funcionalidad descrita en el anterior diagrama UML sobre delegación. Archivo Animal.java public interface Animal { void expresarse(); void caminar(); } Archivo Hombre.java public class Hombre implements Animal { public void expresarse() { System.out.println("Hombre expresarse hablando"); } public void caminar() { System.out.println("Hombre caminando en DOS PIES"); } } Archivo Main.java public class Main { public static void main(String[] args) { Mamifero c = new Mamifero(); c.expresarse(); c.caminar(); c.toHombre(); c.expresarse(); c.caminar(); } } Archivo Mamifero.java public class Mamifero implements Animal { Animal i ; public Mamifero() { super(); i=new Perro(); } public void expresarse() { i.expresarse(); } public void caminar() { i.caminar(); } // Con estos metodos se puede hacer casting // entre objetos tipo Perro y Hombre void toPerro() { i = new Perro(); } void toHombre() { i = new Hombre(); } } Archivo Perro.java El cual al ser ejecutado arroja unos resultados similares a los siguientes: Perro expresandose ladrando Perro caminando en DOS PATAS Hombre expresarse hablando Hombre caminando en DOS PIES En donde se puede apreciar que al ejecutar las líneas siguientes: Mamifero c = new Mamifero(); c.expresarse(); c.caminar(); c.toHombre(); c.expresarse(); c.caminar(); Inicialmente se estaba expresando el “PERRO”: Perro expresandose ladrando Perro caminando en DOS PATAS y después de convertirse a “HOMBRE” invocando el método “toHombre()”, en verdad estaba actuando un hombre debido a que se obtuvieron las dos ultimas líneas: Hombre expresarse hablando Hombre caminando en DOS PIES 23.3. PREGUNTAS SOBRE DELEGACION ¿Qué entendió por delegación? ¿En que casos utilizaría la delegación de clases? ¿Cree que la delegación puede decrementar el rendimiento de aplicaciones o incrementarlo? ¿Por que? ¿Qué ventajas le ve a la delegación? ¿Qué desventajas le ve a la delegación? 24. SERIALIZACION DE OBJETOS La serialización de objetos es una parte muy interesante de algunos lenguajes orientados a objetos, en la cual se puede guardar el estado de un objeto en un tiempo determinado. 24.1. SERIALIZAR UN OBJETO COMPLETAMENTE Para explicar este concepto imaginémonos un objeto que tenga las propiedades y los valores mostrados en la siguiente figura: Int edad = 0; String nombre = “Hugo”; Int numeroAmigos=0 Ahora, imaginémonos que han transcurrido 2 anos y el objeto tiene 3 amigos, tendríamos entonces la siguiente situación: Int edad = 0; Int edad = 2; String nombre = “Hugo”; String nombre = “Hugo”; Int numeroAmigos=0 Int numeroAmigos=0 Tiempo 0 NO ALMACENADO Tiempo 2 NO ALMACENADO Pensemos que queremos almacenar el estado del objeto en el tiempo 2. Gráficamente tendríamos la siguiente situación: Int edad = 0; Int edad = 2; String nombre = “Hugo”; String nombre = “Hugo”; Int numeroAmigos=0 Int numeroAmigos=3 Tiempo 0 NO ALMACENADO Tiempo 2 ALMACENADO Pensemos que transcurridos 5 anos, el objeto tiene 6 amigos, situación que puede verse gráficamente como se muestra a continuación: Int edad = 0; Int edad = 2; Int edad = 5; String nombre = “Hugo”; String nombre = “Hugo”; String nombre = “Hugo”; Int numeroAmigos=0 Int numeroAmigos=3 Int numeroAmigos=6 Tiempo 0 NO ALMACENADO Tiempo 2 ALMACENADO Tiempo 5 NO ALMACENADO Realicemos ahora una recuperación del objeto, basado en el objeto que se almaceno. Debería imprimirse pues, el objeto almacenado en el tiempo 2, tal como se muestra a continuación: edad = 0; nombre = “Hugo”; numeroAmigos=0 edad = 2; nombre = “Hugo”; numeroAmigos=3 edad = 5; nombre = “Hugo”; numeroAmigos=6 edad = 2; nombre = “Hugo”; numeroAmigos=3 Tiempo 0 NO ALMACENADO Tiempo 2 ALMACENADO Tiempo 5 NO ALMACENAO RECUPERADO DEL TIEMPO 2 En este caso obtenemos una socialización completa, debido a que todos los elementos contenidos en el objeto fueron almacenados durante el proceso de socialización y obviamente en el proceso de recuperación del objeto también llamado “deserialización” se volvieron a obtener los valores previamente almacenados. 24.2. SERIALIZAR UN OBJETO COMPLETAMENTE EN JAVA Siguiendo la lógica de la sección anterior sobre serialización completa. Veamos en Java como podemos implementar los pasos descritos en la sección anterior. Primero es bueno tener en cuenta que una clase se puede serializar siempre y cuando implemente la interfaz “Serializable”. A continuación se muestra la interfaz: Archivo InterfazSerializable.java import java.io.*; public interface InterfazSerializable extends Serializable{ } Y posteriormente el objeto que implementa esta interfaz: Archivo ClaseSerializable.java public class ClaseSerializable implements InterfazSerializable{ public int edad; public String nombre; public int numeroAmigos; public ClaseSerializable(String nombrecin){ this.nombre = nombrecin; edad = 0; numeroAmigos = 0; } public void crecer(int valor){ edad = valor; } public void imprimirDatosClase(){ System.out.println("edad = "+edad); System.out.println("nombre = "+nombre); System.out.println("numeroAmigos = "+numeroAmigos); } public void conseguirAmigos(int numero){ this.numeroAmigos = numero; } } En términos de UML tenemos la siguiente situación: Ahora tan solo resta mostrar el programa que crea un objeto de la clase “ClaseSerializable” lo usa: Archivo MyApp1.java import java.io.*; import java.awt.*; import java.awt.event.*; public class MyApp1 { ClaseSerializable objeto1 = null; public MyApp1() { objeto1 = new ClaseSerializable("Hugo"); System.out.println("Datos iniciales del objeto"); objeto1.imprimirDatosClase(); try{ // Creamos los flujos para leer y escribir en archivo.txt FileOutputStream flujoSalida = new FileOutputStream("archivo.txt"); FileInputStream flujoEntrada = new FileInputStream("archivo.txt"); ObjectOutputStream escritor = new ObjectOutputStream(flujoSalida); ObjectInputStream lector = new ObjectInputStream(flujoEntrada); // Transcurridos dos anos el objeto ha crecido y ha conocido // tres amigos // Lo hacemos crecer y lo imprimimos System.out.println("Transcurridos dos anos el objeto ha crecido"); System.out.println("y ha conocido 3 amigos"); objeto1.crecer(2); objeto1.conseguirAmigos(3); objeto1.imprimirDatosClase(); // Escribimos el objeto en archivo.txt System.out.println("Escribimos el objeto en archivo.txt"); escritor.writeObject(objeto1); // Transcurridos 5 anos el objeto ha crecido // Lo hacemos crecer 5 anos y lo imprimimos. // Tambien haremos que tenga 6 amigos System.out.println("Transcurridos 5 anos el objeto ha crecido"); System.out.println("y ha conocido 6 amigos"); objeto1.crecer(5); objeto1.conseguirAmigos(6); objeto1.imprimirDatosClase(); // Recuperamos el objeto System.out.println("Recuperamos el objeto"); objeto1 = (ClaseSerializable)lector.readObject(); // Imprimimos objeto recuperado System.out.println("Imprimimos objeto recuperado"); objeto1.imprimirDatosClase(); } catch(Exception e){ System.out.println("Errores en algo"); } } public static void main(String args[]) { MyApp1 f = new MyApp1(); } } En el anterior programa podemos ver primero se crea un objeto en tiempo “0”, después en el tiempo “2” se alteran sus valores y se almacena, en el tiempo “5” se alteran sus valores, pero no se almacena y finalmente en el siguiente tiempo se recupera, con lo cual se deberían ver los valores del objeto que fue guardado en el tiempo “2”. edad = 0; nombre = “Hugo”; numeroAmigos=0 edad = 2; nombre = “Hugo”; numeroAmigos=3 edad = 5; nombre = “Hugo”; numeroAmigos=6 edad = 2; nombre = “Hugo”; numeroAmigos=3 Tiempo 0 NO ALMACENADO Tiempo 2 ALMACENADO Tiempo 5 NO ALMACENAO RECUPERADO DEL TIEMPO 2 Finalmente para probar que la lógica funciona para el programa que estamos mostrando, simplemente vamos a decir que los resultados arrojados por el programa anterior son los siguientes: Datos iniciales del objeto edad = 0 nombre = Hugo numeroAmigos = 0 Transcurridos dos anos el objeto ha crecido y ha conocido 3 amigos edad = 2 nombre = Hugo numeroAmigos = 3 Escribimos el objeto en archivo.txt Transcurridos 5 anos el objeto ha crecido y ha conocido 6 amigos edad = 5 nombre = Hugo numeroAmigos = 6 Recuperamos el objeto Imprimimos objeto recuperado edad = 2 nombre = Hugo numeroAmigos = 3 Exit code: 0 No Errors En donde se observa que los datos iniciales del objeto eran: Datos iniciales del objeto edad = 0 nombre = Hugo numeroAmigos = 0 Fruto de crear el objeto tan solo con el valor de “Hugo” en el atributo “nombre” y de ejecutar las sentencias siguientes: objeto1 = new ClaseSerializable("Hugo"); System.out.println("Datos iniciales del objeto"); objeto1.imprimirDatosClase(); Transcurridos dos anos el objeto ha crecido y ha conocido 3 amigos System.out.println("Transcurridos dos anos el objeto ha crecido"); System.out.println("y ha conocido 3 amigos"); objeto1.crecer(2); objeto1.conseguirAmigos(3); objeto1.imprimirDatosClase(); lo cual produce el resultado: Transcurridos dos anos el objeto ha crecido y ha conocido 3 amigos edad = 2 nombre = Hugo numeroAmigos = 3 Procedemos pues a guardar los datos del objeto usando la instrucción: // Escribimos el objeto en archivo.txt System.out.println("Escribimos el objeto en archivo.txt"); escritor.writeObject(objeto1); Con lo cual los siguientes datos son guardados edad = 2 nombre = Hugo numeroAmigos = 3 DATOS ALMACENADOS USANDO SERIALIZACION Transcurridos 5 anos el objeto ha crecido y ha conocido 6 amigos, lo cual se hace con las instrucciones: // Transcurridos 5 anos el objeto ha crecido // Lo hacemos crecer 5 anos y lo imprimimos. // Tambien haremos que tenga 6 amigos System.out.println("Transcurridos 5 anos el objeto ha crecido"); System.out.println("y ha conocido 6 amigos"); objeto1.crecer(5); objeto1.conseguirAmigos(6); objeto1.imprimirDatosClase(); Y produce el resultado siguiente: edad = 5 nombre = Hugo numeroAmigos = 6 Despues restauramos los datos del objeto serializado y lo imprimimos usando las instrucciones: // Recuperamos el objeto System.out.println("Recuperamos el objeto"); objeto1 = (ClaseSerializable)lector.readObject(); // Imprimimos objeto recuperado System.out.println("Imprimimos objeto recuperado"); objeto1.imprimirDatosClase(); Las cuales producen el resultado siguiente: edad = 2 nombre = Hugo numeroAmigos = 3 DATOS RECUPARADOS DE LA SERIALIZACION 24.3. ATRIBUTOS TRANSIENTES EN LA SERIALIZACION Básicamente un objeto puede contener atributos transientes y atributos no transientes. El valor de los atributos transientes no es almacenado en el momento de la serialización del objeto y por tanto se pierde. Para comprender esto haremos una modificación a la “ClaseSerializable” de la sección anterior, en donde el atributo “numeroAmigos” dejara de ser declarada como se muestra en el siguiente diagrama: Y se declarará de tipo “transient”, con lo cual nuestro diagrama de clases toma la siguiente forma: Y nuestra clase “ClaseSerializable” tendrá las siguientes instrucciones: public class ClaseSerializable implements InterfazSerializable{ public int edad; public String nombre; public transient int numeroAmigos; public ClaseSerializable(String nombrecin){ this.nombre = nombrecin; edad = 0; numeroAmigos = 0; } public void crecer(int valor){ edad = valor; } public void imprimirDatosClase(){ System.out.println("edad = "+edad); System.out.println("nombre = "+nombre); System.out.println("numeroAmigos = "+numeroAmigos); } public void conseguirAmigos(int numero){ this.numeroAmigos = numero; } } Ahora supongamos que estamos usando la misma clase interfaz de la sección anterior, es decir que estamos usando el archivo mostrado a continuación: Archivo InterfazSerializable.java import java.io.*; public interface InterfazSerializable extends Serializable{ } Si ejecutamos un programa que haga uso de un objeto que sea del tipo “ClaseSerializable” y que puede ser un programa como el mostrado en las siguientes líneas: Archivo MyApp1.java import java.io.*; import java.awt.*; import java.awt.event.*; public class MyApp1 { ClaseSerializable objeto1 = null; public MyApp1() { objeto1 = new ClaseSerializable("Hugo"); System.out.println("Datos iniciales del objeto"); objeto1.imprimirDatosClase(); try{ // Creamos los flujos para leer y escribir en archivo.txt FileOutputStream flujoSalida = new FileOutputStream("archivo.txt"); FileInputStream flujoEntrada = new FileInputStream("archivo.txt"); ObjectOutputStream escritor = new ObjectOutputStream(flujoSalida); ObjectInputStream lector = new ObjectInputStream(flujoEntrada); // Transcurridos dos anos el objeto ha crecido y ha conocido // tres amigos // Lo hacemos crecer y lo imprimimos System.out.println("Transcurridos dos anos el objeto ha crecido"); System.out.println("y ha conocido 3 amigos"); objeto1.crecer(2); objeto1.conseguirAmigos(3); objeto1.imprimirDatosClase(); // Escribimos el objeto en archivo.txt System.out.println("Escribimos el objeto en archivo.txt"); escritor.writeObject(objeto1); // Transcurridos 5 anos el objeto ha crecido // Lo hacemos crecer 5 anos y lo imprimimos. // Tambien haremos que tenga 6 amigos System.out.println("Transcurridos 5 anos el objeto ha crecido"); System.out.println("y ha conocido 6 amigos"); objeto1.crecer(5); objeto1.conseguirAmigos(6); objeto1.imprimirDatosClase(); // Recuperamos el objeto System.out.println("Recuperamos el objeto"); objeto1 = (ClaseSerializable)lector.readObject(); // Imprimimos objeto recuperado System.out.println("Imprimimos objeto recuperado"); objeto1.imprimirDatosClase(); } catch(Exception e){ System.out.println("Errores en algo"); } } public static void main(String args[]) { MyApp1 f = new MyApp1(); } } Podemos encontrar que los resultados obtenidos fueron los siguientes: Datos iniciales del objeto edad = 0 nombre = Hugo numeroAmigos = 0 Transcurridos dos anos el objeto ha crecido y ha conocido 3 amigos edad = 2 nombre = Hugo numeroAmigos = 3 Escribimos el objeto en archivo.txt Transcurridos 5 anos el objeto ha crecido y ha conocido 6 amigos edad = 5 nombre = Hugo numeroAmigos = 6 Recuperamos el objeto Imprimimos objeto recuperado edad = 2 nombre = Hugo numeroAmigos = 0 Exit code: 0 No Errors En donde es claro que a pesar que el objeto “objeto1” se guardo cuando tenía los siguientes valores: edad = 2 nombre = Hugo numeroAmigos = 3 También es cierto que al deserializarse se obtienen los siguientes datos: edad = 2 nombre = Hugo numeroAmigos = 0 Lo que indica que el atributo “numeroAmigos” no fue almacenado en el momento de la serialización 24.4. LA SERIALIZACION Y EL DIAGRAMA DE ESTADOS El diagrama de estados en UML intenta modelar los diversos estados por los que pasa un objeto en el tiempo. De otra parte los estados tienen directa relación con el contenido de los atributos de un objeto, es decir que podemos pensar que un objeto cambia de estado cuando algunos de sus atributos han cambiado de valor. De otra parte es interesante observar que la serialización intenta almacenar el estado de un objeto en un momento determinado y que la deserialización intenta retroceder en el tiempo a un objeto restableciendo los valores que sus atributos no “transient” tenían en un determinado momento. Es interesante observar que cuando el objeto “objeto1” tenía los valores: edad = 0 nombre = Hugo numeroAmigos = 0 Se podría modelar esta situación con el diagrama UML: PRENATAL Pero también es posible que cuando el objeto “objeto1” cambie sus valores a los siguientes: edad = 2 nombre = Hugo numeroAmigos = 3 Se podría modelar este nuevo estado de la siguiente manera: BEBE Y la transición de un estado al otro se podría modelar de la siguiente forma: PRENATAL BEBE En donde el paso de un estado a otro depende no del “numero de amigos” que tenga el objeto, sino de la edad del objeto. Tambien podríamos pensar en modelar la situación que el objeto “objeto1” tenga los siguientes datos: edad = 5 nombre = Hugo numeroAmigos = 6 Mediante el empleo de la siguiente notación: NINO Con lo cual la alteración de estos atributos del objeto “objeto1” hechas hasta el momento podrían modelarse de la siguiente manera: PRENATAL BEBE NINO Y nos restaría modelar la situación en la que se puede pasar al estado anterior, o sea del estado de “NINO” al estado de “BEBE” usando la descerializacion y modelándolo tal como se muestra a continuación: PRENATAL BEBE NINO Finalmente si el estado inicial es ser “PRENATAL” y el máximo estado es ser “NINO” teniendo en cuenta que utópicamente solamente se pueda morir cuando se sea “NINO”, podríamos modelar esta situación tal como se muestra a continuación: PRENATAL BEBE NINO Obviamente el anterior diagrama no es acorde con la realidad debido a que un “PRENATAL” se puede morir, al igual que un “BEBE” o un “NINO”. Con lo cual en la vida real tenemos una situación como la siguiente: PRENATAL BEBE NINO Aunque para el caso del programa que ya hicimos y que mostramos anteriormente tan solo podemos finalizar si somos “NINO”. 24.5. TALLER PROPUESTO SOBRE SERIALIZACION Con el animo de lograr que los conceptos de serialización queden bien comprendidos por parte del amigo lector / estudiante, a continuación se muestra un ejercicio propuesto sobre serialización en el que el estudiante debe explicar por que el siguiente programa conformado por los tres archivos “ClaseSerializable.java”, “InterfazSerializable” y “MyApp.java” produce los resultados aquí expuestos. Los tres archivos del programa son: Archivo InterfazSerializable.java import java.io.*; public interface InterfazSerializable extends Serializable{ } Archivo ClaseSerializable.java public class ClaseSerializable implements InterfazSerializable{ public int edad; public String nombre; public transient int numeroAmigos; public ClaseSerializable(String nombrecin){ this.nombre = nombrecin; edad = 0; numeroAmigos = 0; } public void crecer(int valor){ edad = valor; } public void imprimirDatosClase(){ System.out.println("edad = "+edad); System.out.println("nombre = "+nombre); System.out.println("numeroAmigos = "+numeroAmigos); } public void conseguirAmigos(int numero){ this.numeroAmigos = numero; } } Y el archivo: Archivo MyApp.java import java.io.*; import java.awt.*; import java.awt.event.*; public class MyApp { ClaseSerializable ClaseSerializable ClaseSerializable ClaseSerializable public MyApp() { objeto1 = new objeto2 = new objeto3 = new objeto4 = new objeto1 objeto2 objeto3 objeto4 = = = = null; null; null; null; ClaseSerializable("Hugo"); ClaseSerializable("Paco"); ClaseSerializable("Luis"); ClaseSerializable("Mickey"); // Imprimimos los datos iniciales de los objetos System.out.println("Datos iniciales de objetos"); objeto1.imprimirDatosClase(); objeto2.imprimirDatosClase(); objeto3.imprimirDatosClase(); objeto4.imprimirDatosClase(); try{ // Creamos los flujos para leer y escribir en archivo.txt FileOutputStream flujoSalida = new FileOutputStream("archivo.txt"); FileInputStream flujoEntrada = new FileInputStream("archivo.txt"); ObjectOutputStream escritor = new ObjectOutputStream(flujoSalida); ObjectInputStream lector = new ObjectInputStream(flujoEntrada); // Escribimos los objetos en archivo.txt System.out.println("Escribimos los objetos en archivo.txt"); escritor.writeObject(objeto1); escritor.writeObject(objeto2); escritor.writeObject(objeto3); escritor.writeObject(objeto4); // Transcurridos dos anos los objetos han crecido System.out.println("Transcurridos dos anos los objetos han crecido"); objeto1.crecer(2); objeto2.crecer(2); objeto3.crecer(2); objeto4.crecer(2); // Imprimimos los nuevos datos de los objetos System.out.println("Imprimimos los nuevos datos de los objetos"); objeto1.imprimirDatosClase(); objeto2.imprimirDatosClase(); objeto3.imprimirDatosClase(); objeto4.imprimirDatosClase(); // Y uno de ellos el mas piloso ha conseguido 3 amigos System.out.println("Y uno de ellos el mas piloso ha conseguido 3 amigos"); objeto3.conseguirAmigos(3); // Imprimimos nuevamente datos de los objetos System.out.println("Imprimimos nuevamente datos de los objetos"); objeto1.imprimirDatosClase(); objeto2.imprimirDatosClase(); objeto3.imprimirDatosClase(); objeto4.imprimirDatosClase(); // Volvemos a serializar los objetos System.out.println("Volvemos a serializar los objetos"); escritor.writeObject(objeto1); escritor.writeObject(objeto2); escritor.writeObject(objeto3); escritor.writeObject(objeto4); // Recuperamos los objetos una vez System.out.println("Recuperamos los objetos una vez"); objeto1 = (ClaseSerializable)lector.readObject(); objeto2 = (ClaseSerializable)lector.readObject(); objeto3 = (ClaseSerializable)lector.readObject(); objeto4 = (ClaseSerializable)lector.readObject(); // Falta Imprimir objetos recuperados una vez System.out.println("Falta Imprimir objetos recuperados una vez"); objeto1.imprimirDatosClase(); objeto2.imprimirDatosClase(); objeto3.imprimirDatosClase(); objeto4.imprimirDatosClase(); // Recuperamos los objetos por segunda vez System.out.println("Recuperamos los objetos por segunda vez"); objeto1 = (ClaseSerializable)lector.readObject(); objeto2 = (ClaseSerializable)lector.readObject(); objeto3 = (ClaseSerializable)lector.readObject(); objeto4 = (ClaseSerializable)lector.readObject(); // Falta Imprimir objetos recuperados segunda vez System.out.println("Falta Imprimir objetos recuperados segunda vez"); objeto1.imprimirDatosClase(); objeto2.imprimirDatosClase(); objeto3.imprimirDatosClase(); objeto4.imprimirDatosClase(); // Recuperamos el objeto 3 System.out.println("Recuperamos el objeto 3"); objeto1 = (ClaseSerializable)lector.readObject(); objeto2 = (ClaseSerializable)lector.readObject(); objeto3 = (ClaseSerializable)lector.readObject(); objeto4 = (ClaseSerializable)lector.readObject(); // Falta Imprimir objeto3 recuperado System.out.println("Falta Imprimir objeto3 recuperado"); objeto3.imprimirDatosClase(); } catch(Exception e){ System.out.println("Errores en algo"); } } public static void main(String args[]) { MyApp f = new MyApp(); } } Los cuales producen el resultado siguiente: Datos iniciales de objetos edad = 0 nombre = Hugo numeroAmigos = 0 edad = 0 nombre = Paco numeroAmigos = 0 edad = 0 nombre = Luis numeroAmigos = 0 edad = 0 nombre = Mickey numeroAmigos = 0 Escribimos los objetos en archivo.txt Transcurridos dos anos los objetos han crecido Imprimimos los nuevos datos de los objetos edad = 2 nombre = Hugo numeroAmigos = 0 edad = 2 nombre = Paco numeroAmigos = 0 edad = 2 nombre = Luis numeroAmigos = 0 edad = 2 nombre = Mickey numeroAmigos = 0 Y uno de ellos el mas piloso ha conseguido 3 amigos Imprimimos nuevamente datos de los objetos edad = 2 nombre = Hugo numeroAmigos = 0 edad = 2 nombre = Paco numeroAmigos = 0 edad = 2 nombre = Luis numeroAmigos = 3 edad = 2 nombre = Mickey numeroAmigos = 0 Volvemos a serializar los objetos Recuperamos los objetos una vez Falta Imprimir objetos recuperados una vez edad = 0 nombre = Hugo numeroAmigos = 0 edad = 0 nombre = Paco numeroAmigos = 0 edad = 0 nombre = Luis numeroAmigos = 0 edad = 0 nombre = Mickey numeroAmigos = 0 Recuperamos los objetos por segunda vez Falta Imprimir objetos recuperados segunda vez edad = 0 nombre = Hugo numeroAmigos = 0 edad = 0 nombre = Paco numeroAmigos = 0 edad = 0 nombre = Luis numeroAmigos = 0 edad = 0 nombre = Mickey numeroAmigos = 0 Recuperamos el objeto 3 Errores en algo Exit code: 0 No Errors Y el amigo lector / estudiante debe dar una explicación racional y cierta sobre la razón por la cual se producen los resultados anteriores. 25. EJERCICIOS QUE TIENEN DIAGRAMAS DE SECUENCIA 25.1. MODELAMIENTO DE DETENCION SINCRONICA DE MULTIPLES HILOS CON UN EJEMPLO. Supongamos que tenemos un Zoológico que tiene Burros, perros y como mínimo un Domador. Se requiere que el Zoológico no solo use los Burros o los Perros, sino que los tenga, debido a que si no los tiene pues no seria un Zoológico. (Bueno, esto es para el ejercicio, porque los zoológicos por lo general tienen panteras, leones y otros animales, pero es simplemente para hacer el ejercicio mas sencillo). Según lo establecido anteriormente podemos decir que las relaciones anteriormente citadas se pueden expresar mediante el siguiente diagrama: <<include>> Zoologico Burro <<include>> <<include>> Perro Domador Ahora supongamos que el Zoológico ha comprado dos burros llamados “higor” y “corcelin”, como también ha comprado dos perros llamados “doki” y “cuchufleto”. Con lo cual nuestro diagrama de clases, podría eventualmente tener algunos objetos tal como se muestra a continuación: <<include>> Zoologico Burro Burro: higor <<include>> Burro: corcelin Perro <<include>> Perro: doki Domador Perro: cuchufleto Observe amigo lector / estudiante que el símbolo: Perro Perro: cuchufleto No solamente se usa para denotar que una clase dependa de otra, sino que también se usa para denotar relaciones de instanciación entre clases y los objetos que implementan estas clases. En otras palabras vemos que esto es una relación de instanciación. Siguiendo con nuestro ejemplo supongamos que el Zoológico contrata a un domador llamado “pepito” para que haga el trabajo de adiestrar a estos animalitos, con lo cual nuestro diagrama tomaría la siguiente forma: <<include>> Zoologico Burro Burro: higor <<include>> Burro: corcelin <<include>> Perro Perro: doki Domador Domador: pepito Perro: cuchufleto En términos de código, las relaciones anteriores se crean cuando se crean los objetos, tal como lo muestra el siguiente código fuente: Burro higor = new Burro("higor"); Burro corcelin = new Burro("corcelin"); Perro doki = new Perro("doki"); Perro cuchufleto = new Perro("cuchufleto"); Domador pepito = new Domador(); Dado que los animales burros y los perros se comportan abstractamente de acuerdo al concepto de animal, es bueno crear una interfaz que obligue a los animales a implementar su método “dialogar ()”. Con la creación de esta interfaz, tenemos que nuestro nuevo diagrama de clases toma la forma: Con lo cual queda bien claro que los burros y los perros implementan los contratos especificados en la interfaz “Animal”. A nivel de código podríamos crear la interfaz como se muestra a continuación: public interface Animal { public void dialogar(); } // Cierra interface Animal La clase “Perro” que implementa la interfaz seria similar a la siguiente: public class Perro implements Animal{ String nombrecin =""; boolean estadoLadro = true; public void dialogar(){ System.out.println("ladro bastante"); } // Cierra void dialogar() public Perro(String nombre){ nombrecin = nombre; } // Cierra public Perro() public String getNombre(){ return nombrecin; } } // Cierra class Perro Y la clase “Burro” que implementa la interfaz tendría un código similar al siguiente: public class Burro implements Animal{ String nombrecin =""; boolean estadoRebusno = true; public void dialogar(){ System.out.println("Rebusno bastante"); } // Cierra void dialogar() public Burro(String nombre){ nombrecin = nombre; } // Cierra public Burro() public String getNombre(){ return nombrecin; } } // Cierra class Burro Con lo cual el diagrama que estamos haciendo tomaría una forma similar a la siguiente: De otra parte el “zoológico” tiene dos grandes actividades que son las actividades previas a la función y las actividades que realiza cuando la función esta presentándose. Por esta razón es necesario agregar a la clase “zoológico” dos métodos que son: Las actividades previas tienen que ver con adiestrar los animales por parte del “Domador”, en este caso por parte de “pepito”, con lo cual a nivel de código tendríamos un código similar al siguiente: public void realizarActividadesPrevias(){ pepito.adiestrar(higor); pepito.adiestrar(corcelin); pepito.adiestrar(doki); pepito.adiestrar(cuchufleto); } // Cierra void realizarActividadesPrevias() En este caso el método adiestrar() del “domador” es un método que se encuentra dos veces implementado debido a que permite recibir dos tipos de objetos y de acuerdo a cada uno de ellos sigue el proceso de adiestramiento, puesto que no es lo mismo adiestrar un perro que un burro. De otra parte tenemos que el “domador” es el único que conoce cuantos animales tiene a su cargo, con lo cual el tendrá un vector que permita almacenar los burros y los perros y la implementación de sus métodos adiestrar(), seria similar a la siguiente: public void adiestrar(Burro animalin){ ThreadBurros hiloBurros = new ThreadBurros(animalin, grupoBurros,animalin.getNombre()); vectorBurros.add(hiloBurros); } // Cierra void adiestrar(Burro) public void adiestrar(Perro animalin){ ThreadPerros hiloPerros = new ThreadPerros(animalin, grupoPerros,animalin.getNombre()); vectorPerros.add(hiloPerros); } // Cierra void adiestrar(Perro) Observemos este proceso de sincronización. Vemos que cuando se adiestran a los animales se tienen grupos para cada animal. Veamos la implementación pues de cada uno de estos “ThreadGroup”: ThreadBurros.java public class ThreadBurros extends Thread{ Burro objetoBurro1; public ThreadBurros(Burro objetoBurro, ThreadGroup grupo, String cadena){ super(grupo, cadena); objetoBurro1 = objetoBurro; } // Cierra constructor ThreadBurros public void run(){ while(true){ try{ this.objetoBurro1.dialogar(); Thread.sleep(1000); } // Cierra try catch(Exception e){ System.out.println("Errores rebusnando"); break; // objetoBurro1.estadoRebusnado(false); } // Cierra catch(); } // Cierra while(true) } // Cierra public void run() } // Cierra public class ThreadBurros En donde simplemente se esta diciendo que un burro cuando comienza a dialogar(), lo hace cada Segundo y si en algun momento algun proceso extrano o ajeno no permite la ejecucion, automaticamente se sale del ciclo para que nunca vuelva ejecutarse el hilo. La implementación para el ThreadPerros es similar a la anterior y se muestra a continuación: public class ThreadPerros extends Thread{ Perro objetoPerro1; public ThreadPerros(Perro objetoPerro, ThreadGroup grupo, String cadena){ super(grupo, cadena); objetoPerro1 = objetoPerro; } // Cierra constructor ThreadPerros public void run(){ while(true){ try{ this.objetoPerro1.dialogar(); Thread.sleep(1000); } // Cierra try catch(Exception e){ System.out.println("Errores ladrando"); break; } // Cierra catch(); } // Cierra while(true) } // Cierra public void run() } // Cierra public class ThreadPerros Con todo lo dicho hasta el momento, tenemos que nuestro diagrama tiene una forma similar a la siguiente: Cuando se pongan a hablar los perros, se obtienen los hilos asociados a cada animal y se comienza la ejecución del hilo, tal como lo muestran las funciones: ponerHablarBurros() ponerHablarPerros() Las cuales se detallan una a una mas adelante. La función “ponerHablarBurro”, por ejemplo contiene el siguiente código: public void ponerHablarBurros(){ int cantidad = vectorBurros.size(); System.out.println("Cantidad burros = "+cantidad); int contador = 0; while(contador<cantidad){ ThreadBurros grupoBurrosHilos (ThreadBurros)vectorBurros.elementAt(contador); try{ grupoBurrosHilos.start(); } catch(Exception e){ System.out.println("Burros no pueden rebusnar"); }// Cierra catch contador++; } // Cierra while } // Cierra void ponerHablarBurros() = Es tan complicado hacer este método, que es bueno diseñar un diagrama que permita modelar la complejidad de dicho método. Para lograr esto, a continuación se muestra el diagrama de actividad que modela y explica el funcionamiento de dicho método: v ectorBurros : Vector obj Sistema : Sistema grupoBurros : ThreadBurros <<<<size>>>> obtenerTamano <<<<println>>>> ImprimirTamano <<<<Max 2>>>> While( contador<2 ) <<<<elementAt>>>> ...>> obtenerElemento <<<<Casting>>>> Conversion While Exception? SI_Exception( e ) <<<<println>>>> imprimirError <<<<start>>>> ComenzarEjecu cion NO_Exception( e ) Obviamente el diagrama de actividad para el método “ponerHablarPerros”, es similar al anterior, pero antes de mostrarlo primero veamos el código fuente de dicho método: public void ponerHablarPerros(){ int cantidad = vectorPerros.size(); System.out.println("Cantidad perros = "+cantidad); int contador = 0; while(contador<cantidad){ ThreadPerros grupoPerrosHilos = (ThreadPerros)vectorPerros.elementAt(contador); try{ grupoPerrosHilos.start(); } catch(Exception e){ System.out.println("Perros no pueden ladrar"); }// Cierra catch contador++; } // Cierra while } // Cierra void ponerHablarPerros() Ahora el diagrama de actividad asociado a dicho método: v ectorPerros : Vector obj Sistema : Sistema grupoPerros : ThreadPerros <<<<size>>>> obtenerTamano <<<<println>>>> ImprimirTamano <<<<Max 2>>>> While( contador<2 ) <<<<elementAt>>>> ...>> obtenerElemento <<<<Casting>>>> Conversion While Exception? SI_Exception( e ) <<<<println>>>> imprimirError <<<<start>>>> ComenzarEjecu cion NO_Exception( e ) La detención de los procesos simultáneos se hace mediante los siguientes métodos: public void callarBurros(){ try{ System.out.println("Estoy intentando interrumpir"); grupoBurros.interrupt(); System.out.println("PUDE interrumpir a burros"); } catch(Exception e){ System.out.println("No pude callar a Burros"); } // Cierra catch } // Cierra void callarBurros El cual detiene la ejecución del método “dialogar”, asociado a cada “Burro”, Y para el caso de detener los hilos asociados a los “Perros”, tenemos el siguiente código: public void callarPerros(){ try{ System.out.println("Estoy intentando interrumpir"); grupoPerros.interrupt(); System.out.println("PUDE interrumpir a perros"); } catch(Exception e){ System.out.println("No pude callar a Perros"); } // Cierra catch } // Cierra callarPeros() Observe finalmente que la invocación del método “interrupt()” se encarga de detener los hilos asociados a este ThreadGroup. En conclusión todos los hilos que se encuentran en este grupo de hilos, son automáticamente detenidos con la invocación de este método. 25.2. IMPLEMENTACION DE DETENCION SINCRONICA DE MULTIPLES HILOS CON UN EJEMPLO. Basados en el ejercicio de la anterior sección, a continuación mostramos el código fuente en java de cada uno de los archivos que conformarían la solución de software del ejercicio en mención. Archivo: Anima.java public interface Animal { public void dialogar(); } // Cierra interface Animal Archivo: Burro.java public class Burro implements Animal{ String nombrecin =""; boolean estadoRebusno = true; public void dialogar(){ System.out.println("Rebusno bastante"); } // Cierra void dialogar() public Burro(String nombre){ nombrecin = nombre; } // Cierra public Burro() public String getNombre(){ return nombrecin; } } // Cierra class Burro Archivo Domador.java import java.util.*; public class Domador { ThreadGroup grupoPerros = new ThreadGroup("perrillos"); ThreadGroup grupoBurros = new ThreadGroup("burrillos"); Vector vectorBurros = new Vector(); Vector vectorPerros = new Vector(); public void callarAnimales(){ callarBurros(); callarPerros(); } // Cierra void callarAnimales() public void adiestrar(Burro animalin){ ThreadBurros hiloBurros = new ThreadBurros(animalin, grupoBurros,animalin.getNombre()); vectorBurros.add(hiloBurros); } // Cierra void adiestrar(Burro) public void adiestrar(Perro animalin){ ThreadPerros hiloPerros = new ThreadPerros(animalin, grupoPerros,animalin.getNombre()); vectorPerros.add(hiloPerros); } // Cierra void adiestrar(Perro) public void ponerHablarBurros(){ int cantidad = vectorBurros.size(); System.out.println("Cantidad burros = "+cantidad); int contador = 0; while(contador<cantidad){ ThreadBurros grupoBurrosHilos = (ThreadBurros)vectorBurros.elementAt(contador); try{ // Thread.sleep(500); grupoBurrosHilos.start(); } catch(Exception e){ System.out.println("Burros no pueden rebusnar"); }// Cierra catch contador++; } // Cierra while } // Cierra void ponerHablarBurros() public void ponerHablarPerros(){ int cantidad = vectorPerros.size(); System.out.println("Cantidad perros = "+cantidad); int contador = 0; while(contador<cantidad){ ThreadPerros grupoPerrosHilos = (ThreadPerros)vectorPerros.elementAt(contador); try{ // Thread.sleep(500); grupoPerrosHilos.start(); } catch(Exception e){ System.out.println("Perros no pueden ladrar"); }// Cierra catch contador++; } // Cierra while } // Cierra void ponerHablarPerros() public void callarBurros(){ try{ System.out.println("Estoy intentando interrumpir"); grupoBurros.interrupt(); System.out.println("PUDE interrumpir a burros"); } catch(Exception e){ System.out.println("No pude callar a Burros"); } // Cierra catch } // Cierra void callarBurros public void callarPerros(){ try{ System.out.println("Estoy intentando interrumpir"); grupoPerros.interrupt(); System.out.println("PUDE interrumpir a perros"); } catch(Exception e){ System.out.println("No pude callar a Perros"); } // Cierra catch } // Cierra callarPeros() } // Cierra class Domador Archivo Perro.java public class Perro implements Animal{ String nombrecin =""; boolean estadoLadro = true; public void dialogar(){ System.out.println("ladro bastante"); } // Cierra void dialogar() public Perro(String nombre){ nombrecin = nombre; } // Cierra public Perro() public String getNombre(){ return nombrecin; } } // Cierra class Perro Archivo ThreadBurros.java public class ThreadBurros extends Thread{ Burro objetoBurro1; public ThreadBurros(Burro objetoBurro, ThreadGroup grupo, String cadena){ super(grupo, cadena); objetoBurro1 = objetoBurro; } // Cierra constructor ThreadBurros public void run(){ while(true){ try{ this.objetoBurro1.dialogar(); Thread.sleep(1000); } // Cierra try catch(Exception e){ System.out.println("Errores rebusnando"); break; // objetoBurro1.estadoRebusnado(false); } // Cierra catch(); } // Cierra while(true) } // Cierra public void run() } // Cierra public class ThreadBurros Archivo ThreadPerros.java public class ThreadPerros extends Thread{ Perro objetoPerro1; public ThreadPerros(Perro objetoPerro, ThreadGroup grupo, String cadena){ super(grupo, cadena); objetoPerro1 = objetoPerro; } // Cierra constructor ThreadPerros public void run(){ while(true){ try{ this.objetoPerro1.dialogar(); Thread.sleep(1000); } // Cierra try catch(Exception e){ System.out.println("Errores ladrando"); break; } // Cierra catch(); } // Cierra while(true) } // Cierra public void run() } // Cierra public class ThreadPerros Archivo Zoologico.java public class Zoologico { Burro higor = new Burro("higor"); Burro corcelin = new Burro("corcelin"); Perro doki = new Perro("doki"); Perro cuchufleto = new Perro("cuchufleto"); Domador pepito = new Domador(); public void realizarActividadesPrevias(){ pepito.adiestrar(higor); pepito.adiestrar(corcelin); pepito.adiestrar(doki); pepito.adiestrar(cuchufleto); } // Cierra void realizarActividadesPrevias() public void mostrarFuncion(){ pepito.ponerHablarBurros(); pepito.ponerHablarPerros(); try{ Thread.sleep(7000); pepito.callarAnimales(); } catch(Exception e){ System.out.println("Errores callando burros o perros"); } } // Cierra mostrarFuncion() public static void main(String[] args) { Zoologico programa = new Zoologico(); programa.realizarActividadesPrevias(); programa.mostrarFuncion(); } // Cierra statico void main() } // Cierra class Zoologico 26. INTRODUCCION A LOS PATRONES DE SOFTWARE Una primera clasificación de los patrones es de acuerdo con las siguientes funcionalidades: Funcionalidad de creación Funcionalidad estructural Funcionalidad de comportamiento 26.1. PATRONES CON FUNCIONALIDAD DE CREACIÓN No siempre la creación de objetos es sencilla, sobre todo cuando el sistema tiene muchos objetos. Es bueno crear un mecanismo lógico que permita abstraer toda la complejidad que existe en un sistema sofisticado para la creación de mencionados objetos 26.2. PATRONES CON FUNCIONALIDAD ESTRUCTURAL 26.3. PATRONES CON FUNCIONALIDAD DE COMPORTAMIENTO 27. EXPLICACION DETALLADA DE LOS PATRONES 27.1. EJEMPLO PRÁCTICO DE APLICACIÓN DE FACTORY Lo importante al aplicar el patrón “Factory” es que existan varias clases hijas(i) que hereden de una gran clase “padre”, de tal suerte que por medio de otra clase “Factoria” se pueda invocar un método de la misma con el ánimo que ésta sea capaz de entregar un objeto específico hijo(i) que no siempre será el mismo, pero que lo único cierto es que siempre va a ser un objeto de una clase que a su vez hereda de la gran clase “padre”. En el caso particular que nos proponemos realizar tenemos la siguiente situación: “Se requiere hacer una clase que sea capaz de premiar a una carrera de la Universidad, dándole un cupo adicional a un estudiante para que ingrese a un proyecto curricular específico. El proyecto curricular específico que gana la premiación se elige a la zar. Lo importante es que el programa sea capaz de crear verdaderamente el estudiante y que no sea fijo que se cree dicho estudiante.” El programa propuesto anteriormente se puede resolver Ahora bien, para lograr una mayor comprensión del patrón, a continuación se muestra el programa completo que implementa mencionado patrón y que trabaja las clases mostradas en el diagrama anterior: import java.awt.*; import java.awt.event.*; public class MyApp extends Frame { public class Estudiante{ protected int cod_carrera; public int dev_Cod_carrera(){ return cod_carrera; } } public class Est_sist_datos extends Estudiante{ public Est_sist_datos(){ cod_carrera=1; System.out.println("Se ha creado un estudiante"); System.out.println("tipo Est_sist_datos"); } } public class Est_ing_civil extends Estudiante{ public Est_ing_civil(){ cod_carrera=2; System.out.println("Se ha creado un estudiante"); System.out.println("tipo Est_ing_civil"); } } public class Est_electronica extends Estudiante{ public Est_electronica(){ cod_carrera=3; System.out.println("Se ha creado un estudiante"); System.out.println("tipo Est_electronica"); } } public class Est_literatura extends Estudiante{ public Est_literatura(){ cod_carrera=4; System.out.println("Se ha creado un estudiante"); System.out.println("tipo Est_literatura"); } } public class Est_musica extends Estudiante{ public Est_musica(){ cod_carrera=5; System.out.println("Se ha creado un estudiante"); System.out.println("tipo Est_musica"); } } public class Est_preescolar extends Estudiante{ public Est_preescolar(){ cod_carrera=6; System.out.println("Se ha creado un estudiante"); System.out.println("tipo Est_preescolar"); } } public class Premiacion{ int sorteo; public Premiacion(){ sorteo = (int)(Math.random()*6); } public Estudiante dev_NuevoCupo(){ switch(sorteo){ case 0: return new Est_sist_datos(); case 1: return new Est_ing_civil(); case 2: return new Est_electronica(); case 3: return new Est_literatura(); case 4: return new Est_musica(); default : return new Est_preescolar(); } } // Cierra public Estudiante dev_NuevoCupo() } public MyApp() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); Premiacion premiacion1 = new Premiacion(); Estudiante estudiante1 = premiacion1.dev_NuevoCupo(); int carrera = estudiante1.dev_Cod_carrera(); System.out.println("Se ha creado un nuevo"); System.out.println("cupo para un estudiante que"); System.out.println("pertenece a la carrera con"); System.out.println("codigo = "+carrera); } public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(100,100); f.show(); } } Los resultados del anterior programa son similares a los siguientes: Se ha creado un estudiante tipo Est_ing_civil Se ha creado un nuevo cupo para un estudiante que pertenece a la carrera con codigo = 2 Lo cual comprueba que verdaderamente se crea el cupo para un estudiante de ingeniería civil. Obviamente la ejecución del anterior programa generaría resultados diferentes cada vez que se ejecute, por ejemplo cuando el autor ejecutó por segunda vez el anterior programa, se tuvieron los resultados siguientes: Se ha creado un estudiante tipo Est_electronica Se ha creado un nuevo cupo para un estudiante que pertenece a la carrera con codigo = 3 Normalmente las clases que heredan las clases “Factory” heredan un comportamiento común de una clase abstracta, pero implementan a su manera los métodos abstractos. 27.2. EJEMPLO MAS ELABORADO USANDO FACTORY El patrón Factory se presta para solucionar el siguiente problema: Se tienen diversos tipos de “Estudiantes”, realmente se tienen “Estudiantes Excelentes”, “Estudiantes Buenos” y “Estudiantes Malos” en donde todos ellos son capaces de “presentar Evaluaciones” y posteriormente “entregarlas”. Al momento de presentar la evaluación pueden pasar cosas inesperadas, es decir un “estudiante bueno” puede presentar y entregar evaluaciones “Excelentes”, “Buenas” o “Malas”, esto debido a que las evaluaciones no solo dependen de los conocimientos, sino de la suerte que se tenga al escoger las respuestas o del estado anímico del estudiante en el momento de presentar esta evaluación, por eso a nivel de software podemos pensar que la presentación de la evaluación es algo aleatorio. De otra parte existe la entidad “Universidad” y concretamente una instancia de una Universidad llamada “Universidad Distrital” en la cual se matriculan estudiantes, pero como todo proceso de matricula, es posible que lleguen estudiantes Malos, pero con notas buenas e ICFES bueno, y por esta razón sean recibidos en la Institución, por eso podemos afirmar que este tipo de cosas para el caso del ejercicio que proponemos se puede tratar como un proceso de admisión aleatorio. El sistema debe brindar la posibilidad de imprimir un listado de los “estudiantes Matriculados“. Finalmente la Universidad hace un proceso al finalizar cada semestre en el que entrega menciones a los mejores estudiantes, en nuestro caso particular entregaremos menciones al estudiante que sea un estudiante Excelente por su trayectoria sin importar como le halla ido en el ultimo parcial. Para nuestro caso nos bastara con que el estudiante sea del tipo “Estudiante Excelente” para que le entregue la mención. Obviamente el ejercicio anterior es un ejercicio un poco forzado ya que las Universidades de pronto no funcionen así, pero es simplemente para explicar como el uso del patron Factory se puede hacer no solamente en una clase, sino que al ser implementado en varias clases Factory ayuda a disminuir la dificultad a nivel de programación para manejar la creación de instancias de varias clases que en ultimas heredan funcionalidades de una superclase. Una solución a nivel de programación con el lenguaje Java propuesta es la siguiente: import java.awt.*; import java.awt.event.*; import java.util.*; public class MyApp extends Frame { public abstract class Parcial{ public String TipoParcial; public abstract String entregarTipoParcial(); } // Cierra class Parcial public class ParcialBueno extends Parcial{ public String entregarTipoParcial(){ return TipoParcial; } public ParcialBueno(){ TipoParcial = "BUENO"; } } // Cierra class ParcialBueno public class ParcialMalo extends Parcial{ public String entregarTipoParcial(){ return TipoParcial; } public ParcialMalo(){ TipoParcial = "MALO"; } } // Cierra class ParcialMalo public class ParcialExcelente extends Parcial{ public String entregarTipoParcial(){ return TipoParcial; } public ParcialExcelente(){ TipoParcial = "EXCELENTE"; } } // Cierra class ParcialExcelente public abstract class Estudiante{ int TipoExamen; public void presentarEvaluacion(){ TipoExamen = (int)(Math.random()*6); } public Parcial entregarEvaluacion(){ switch(TipoExamen){ case 2: return new ParcialExcelente(); case 1: return new ParcialBueno(); default: return new ParcialMalo(); } // Cierra switch } // Cierra entregarEvaluacion() } // Cieraa class Estudiante public class EstudianteExcelente extends Estudiante{ } public class EstudianteBueno extends Estudiante{ } public class EstudianteMalo extends Estudiante{ } public class Universidad{ Vector Matriculados = new Vector(); public void matricularEstudiantes(){ for(int i=0;i<10;i++){ int TipoEst = (int)(Math.random()*4); switch(TipoEst){ case 2 : Matriculados.addElement(new EstudianteExcelente()); case 1 : Matriculados.addElement(new EstudianteBueno()); default : Matriculados.addElement(new EstudianteMalo()); } } // Cierra for } // Cierra void matricular public void imprimirEstudiantesMatriculados(){ System.out.println(Matriculados.toString()); } public void entregarMencion(){ for(int i=0;i<10;i++){ Estudiante estu = (Estudiante)Matriculados.elementAt(i); if(estu instanceof EstudianteExcelente){ System.out.println("entrega mencion a estudiante"); } // Cierra if } // Cierra for } // Cierra void entregarMencion } // Cierra class Universidad public MyApp() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); Universidad UDistrital = new Universidad(); UDistrital.matricularEstudiantes(); UDistrital.imprimirEstudiantesMatriculados(); UDistrital.entregarMencion(); } public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(100,100); f.show(); } } Obsérvese que en la medida de lo posible es mejor procurar que la clase “Estudiante” sea una clase abstracta, que describa en lo posible en forma general las funcionalidades, pero que se implementen de diferente manera en las clases que hereden de dicha clase. 28. PATRON DE CREACION SINGLETON 28.1. PARTE TEORICA DEL PATRON SINGLETON El patrón singleton lo que busca es poder crear una y como máximo una instancia de un objeto. Esto puede ser útil cuando de usar recursos compartidos se trate. Por ejemplo en el uso de la impresora podemos decir que una vez esta siendo usada por una aplicación no se debe permitir que otro usuario corte el trabajo del primero y comience a imprimir su trabajo. Para garantizar el éxito del patrón singleton hacemos uso de una variable estática al interior de la clase que queremos no tenga mas de una instancia. En nuestro caso queremos que la clase Impresora no tenga mas de una instancia y lo que se hace es preguntar por esta variable estática en un método cualquiera, casi siempre le llaman “getInstance()”, pero puede llamarse con cualquier nombre, lo importante es que en este método si la variable es nula se permite la creación del objeto y se le asigna un valor a dicha variable, pero si no lo es quiere decir que la variable no es nula y por lo tanto ya existe una instancia de esta clase, en nuestro caso una instancia de la clase “Impresora”, con lo cual el método retorna nulo y esto hace que no se pueda crear otra instancia. A nivel de UML podemos decir que el diagrama de clases para el problema planteado es como sigue a continuación: En el ejercicio que nos proponemos desarrollar en la siguiente sección queremos usar la anterior clase desde un programa llamado “MyApp” y esto en términos de UML seria como se muestra a continuación: Con lo anterior estamos diciendo con el rombo en la flecha que se trata de una agregación y esto quiere decir que el programa “MyApp” puede existir si existen o no existen objetos tipo “Impresora”. Se le coloca una relación unidireccional debido a que no es posible que una impresora contenga objetos de tipo “MyApp”. Y para especificar que tenemos o que estamos usando el patrón singleton, a continuación le colocamos una multiplicidad a la relación de asociación tal como se muestra a continuación: 28.2. PARTE PRACTICA DEL PATRON SINGLETON El planteamiento del problema de la sección anterior se puede especificar en código de la forma como se muestra a continuación: Archivo MyApp.java import java.awt.*; import java.awt.event.*; public class MyApp { public MyApp() { try{ Impresora epson1=null; for(int i=0;i<10;i++){ epson1 = Impresora.getInstance("trabajo "+i); if(epson1!=null){ System.out.println("epson1 se pudo crear"); } else{ System.out.println("epson1 no se pudo crear"); } } // Cierra for externo System.out.println(epson1.trabajo); } // Cierra try catch(Exception e){ } } // Cierra MyApp public static void main(String args[]) { MyApp f = new MyApp(); } } Archivo Impresora.java public class Impresora{ static String trabajo = null; public Impresora(String traba){ } public static Impresora getInstance(String trabajo1){ if(trabajo == null){ trabajo = trabajo1; return new Impresora(trabajo1); } else{ return null; } } // Cierra getInstance } // Cierra class PrimerAmor 28.3. OBSERVACIONES AL EJERCICIO DE SINGLETON Observe amigo lector / estudiante que el código de la sección anterior exige que siempre se cree el objeto usando el método “getInstance”, es decir ejecutando sentencias de la forma: epson1 = Impresora.getInstance("trabajo "+i); En otras palabras estamos diciendo que aunque a nivel de programación se pueden crear los objetos con instrucciones como la siguiente: Impresora impresora1 = new Impresora("Trabajin1"); Si usted quiere trabajar con el patrón singleton debe usar tan solo el método “getInstance()” para la creación de objetos porque si no se corre el riesgo que se este intentando crear un objeto que no sea el primero y el constructor no realizara este tipo de comprobaciones. Otra de las cosas a tener en cuenta con el uso del patrón singleton es que la asignación de un valor para la variable estática usada como punto de referencia para controlar si ya se han creado instancias puede hacerse no necesariamente desde el método getInstance()”, es decir que para el ejercicio que venimos realizando podemos hacer la asignación desde el mismo constructor de la clase, tal como se muestra a continuación: 29. PATRON ITERATOR 29.1. DESCRIPCION Este patrón es útil cuando se tiene una colección y se quiere acceder a dicha colección de una manera independiente de dicha colección. 29.2. APLICABILIDAD Imaginémonos que tenemos una estructura de almacenamiento y que no sabemos si se trata de una lista, de un árbol o de cualquier otro TAD (tipo abstracto de dato), queremos que este almacenamiento sea independiente de las personas que usan esta estructura. En pocas palabras queremos que para los usuarios de la estructura mostrar los elementos de la misma sea transparente del tipo de colección. Esto obviamente da una escalabilidad al sistema, debido a que permitiría cambiar el tipo de almacenamiento y seguir manteniendo unas mismas interfaces comunes que hagan que sea transparente cualquier cambio en la forma de la estructura de almacenamiento para los usuarios que quieren mostrar los datos contenidos en ella. Desde el punto de vista del modelo MVC (Modelo Vista Controlador) decimos que los desarrolladores que manipulen la vista para mostrar datos de una colección no les debería importar los detalles de cómo el modelo manipula internamente sus estructuras. En este caso el modelo seria la colección y el iterador tendría estrecha relación con el controlador debido a que de una manera u otra captura el evento del usuario de la vista de querer mostrar los datos de una colección y ejecuta la acción de buscar los datos en la colección y pasárselos a la vista. La vista de una u otra manera estaría dada por los métodos expuestos en la interfaz del iterador que indicaría a la vista el prototipo de los métodos que puede usar la vista para acceder a la colección. En términos del modelo vista controlador tendríamos el siguiente diagrama: MODELO interfaz coleccionGenerica Class Nodo Interface Estructura Class ColeccionLista Class Lista Class ColeccionVectores Class Array En donde podemos ver una primera aproximación a nivel de dominio y específicamente en la parte concerniente al almacenamiento de nuestras estructuras para lograr que sea acoplable con el patrón iterador. Estamos pues indicando en el anterior diagrama de dominio que existe una colección genérica que le indica al sistema los métodos que van a ser expuestos por el modelo de aplicación para el acceso a las colecciones. Obviamente dicha colección debe ser implementada por las colecciones especificas, en este caso “ColeccionLista” y “ColeccionVector”. De otra parte las colecciones especificas usan unas estructuras de almacenamiento propias de dicha colección, por ejemplo una “ColeccionLista” usa una estructura de almacenamiento denominada “Lista” y la “ColeccionVectores” usa una estructura de almacenamiento denominada “Array”. Tengamos presente que se le ha colocado el nombre de “Array” a esta ultima para no interferir a la hora de la implementación con clases propias de Java como las clases “Vector”. Antes de terminar con la explicación de la parte del modelo es importante notar que se pueden dar estructuras de almacenamiento compuestas por otras y esto se deja claro en la estructura de almacenamiento “Lista” que esta compuesta por otra estructura de almacenamiento denominada “Nodo”. Lo que si es bueno notar en el anterior diagrama es que para darle mayor escalabilidad al modelo se ha creado una Interface común a cualquier tipo de estructura y sus estereotipos se tipifican en la Interface llamada “Estructura”. CONTROLADOR Class IteradorLista Class IteradorVectores Interface Iterator En el anterior diagrama queda bien claro que los iteradotes ejecutan acciones y de una manera u otra capturan el evento del usuario de querer mostrar o manipular los datos almacenados en las diversas colecciones. Por esta razón el controlador debe preferiblemente tener una interfaz común para que el manejo de las acciones a realizar sobre la colección sea uniforme para los elementos que lo invoquen desde la vista. Esto se logra en nuestro ejercicio concreto creando una Interface denominada “Iterator” que contiene tan solo el estereotipo de los métodos que pueden ser usados para la manipulación de las colecciones y que será implementado por los iteradotes concretos que a su vez manipularan las colecciones especificas. Es importante tener en cuenta que el controlador en nuestro ejercicio particular esta conectado con las diversas colecciones del modelo de la forma como muestra el siguiente diagrama: MODELO CONTROLADOR Class ColeccionLista Class IteradorLista Class ColeccionVectores Class IteradorVectores Interface iterador En donde es importante notar que esta comunicación es fluida debido a la Interface expuesta por el controlador que en nuestro caso es la Interface “Iterador”. Tengamos en cuenta que esta es la inteface expuesta por el controlador al modelo y visible también a la vista, con lo cual se vuelve la Interface centro de nuestro ejercicio y es tal vez esta situación la que hace que el patrón se llame “Iterator”. Esta situación se expone en la siguiente figura: MODELO CONTROLA DOR Clase1 VISTA Clase1 Clase2 Clase2 interface Iterator Clase3 Clase3 ClaseN ClaseM Ahora estamos en disposición de crear la vista de nuestra aplicación y para ello es bueno notar que el uso de interfaces es una aplicación hace que los estereotipos de unas clases sean conocidos por clases de otra vista. En nuestro caso particular tenemos que la interface “ColeccionGenerica” es conocida no solo por el controlador sino también por la vista, con lo cual diremos que es la forma como la vista sabe de la existencia de colecciones a querer manipular por medio del controlador pero se logra la completa abstracción de la forma como están implementadas dichas colecciones. En el ejemplo que estamos haciendo de manipulación de colecciones tipo “Lista” y tipo “Array” creamos una clase llamada “MyApp” que actúa como la vista de nuestro sistema y que usa las colecciones de acuerdo a la abstracción que tiene de dichas colecciones por medio de la interface ColeccionGenerica. La situación anterior se pude ver claramente en el siguiente diagrama: MODELO CONTROLADOR VISTA 1 ColeccionGenerica MyApp Iterador 2 mostrarElementos() 3 En donde es claro que desde el punto de la vista se conoce de la existencia de colecciones, pero no interesa mucho el tipo de colecciones, puesto que son tratadas como colecciones genéricas, y haciendo uso de su naturaleza, se les solicita a dichas colecciones que devuelven un objeto tipo “iterador”, al cual posteriormente se le solicitara que muestre los elementos de la colección sin importar que tipo de iterador concreto es el que nos ha devuelto la colección y de cómo hace el iterador mencionado para manipular la colección. 29.3. IMPLEMENTACION DE LA SOLUCION Queremos crear colecciones que sean capaces de devolver una referencia al iterador que las manipula. Esto lo hacemos inicialmente creando una interface como la siguiente: ColeccionGenerica.java public interface ColeccionGenerica { Iterador creaIterador(); } La anterior interface será entonces implementada por las colecciones concretas de nuestra aplicación. En nuestro caso será implementada por la clase “ColeccionLista” y “ColeccionVectores”, tal como se muestra en el siguiente código: ColeccionLista.java import java.util.Vector; public class ColeccionLista implements ColeccionGenerica { public Lista estructuraAlmacenamiento = new Lista(); public Iterador creaIterador() { return new IteradorLista( this ); } } La colección “ColeccionVectores” implementa también la interface tal como lo muestra el siguiente código: ColeccionVectores.java public class ColeccionVectores implements ColeccionGenerica { public Array estructuraAlmacenamiento = new Array(); public Iterador creaIterador() { return new IteradorVectores( this ); } } En donde es bueno que el amigo lector / estudiante observe que cada colección concreta tiene una estructura de almacenamiento concreta. La estructura de almacenamiento “Array” tiene el siguiente código: Array.java import java.util.Vector; public class Array implements Estructura{ public Vector objetoVector = new Vector(); public Array(){ } // Cierra Array public int tamano(){ return objetoVector.size(); } public Object elemento(int indice){ return objetoVector.elementAt(indice); } // Cierra elemento(int ) public Object primero(){ return objetoVector.firstElement(); } public boolean esVacio(){ return objetoVector.isEmpty(); } } La clase anterior contiene un método “tamano()” que devuelve un entero que corresponde con el numero de elementos almacenados en la estructura, en nuestro caso dado que la estructura se implementa como “Vector” es posible usar el método “size()” de la clase “java.util.Vector” que permite devolver el tamaño del vector. De otra parte si le colocamos un auto numérico a cada uno de los elementos almacenados en el vector podemos pensar en un método que basado en una posición indicada por un índice devuelve el elemento cuyo auto numérico corresponda con dicho índice. Esto afortunadamente y para facilidad de nuestro ejercicio lo hace el método “elementAt(int)” de la clase “java.util.Vector” y es usado en el método “elemento(int)”. De otra parte el método “esVacio()” devuelve un valor tipo “boolean” que será “true” cuando el vector esta vació o “false” cuando no lo este. En el anterior código se puede observar que para mayor facilidad y rapidez en el desarrollo se hizo uso de la clase “Vector” del paquete java”.util” de java. Observamos pues que la clase “Array” tiene métodos que devuelven objetos y esto se hace particularmente para lograr que el uso de un objeto de tipo “Array” sea lo mas genérico posible y no solo esto, sino para lograr que sea factible que la clase “Array” implemente los métodos de una interface común a todas las demás estructuras de almacenamientos posibles. En nuestro caso particular la interface que contiene el estereotipo de dichos métodos es la interface “Estructura” cuyo código es el siguiente: Estructura.java public interface Estructura{ public int tamano(); public Object elemento(int indice); public Object primero(); boolean esVacio(); } // Cierra interface Estructura Otra clase para nuestro ejercicio que implementa la anterior interface “Estructura” es la clase “Lista”, cuyo código es el siguiente: Lista .java public class Lista implements Estructura{ Nodo primero = null; Nodo ultimo = null; Nodo actual = null; public Lista(){ primero = null; ultimo = null; } public int tamano(){ int tamano = 0; Nodo correr = primero; while(correr!=null){ tamano = tamano +1; correr = correr.siguiente; } return tamano; } // Cierra int tamano() public Object elemento(int indice){ Nodo correr = primero; if(indice<tamano()){ int contador = 0; while(correr!=null){ if(indice==contador){ break; } contador = contador +1; correr = correr.siguiente; } // Cierra while } // Cierra if externo return correr; } // Cierra Object elemento() public Object primero(){ return primero; } // Cierra Objecto primero() public boolean esVacio(){ if(primero==null){ return true; } else{ return false; } } // Cierra boolean esVacio() } // Cierra Lista Dado que la anterior clase es larga, merece una explicación detallada sobre algunos de sus métodos mas importantes. La lista se crea a partir de un Nodo llamado Nodo “primero”. Si este nodo es nulo, la lista es vacía y el método “esVacio()” devuelve un valor “true” en caso que la lista este vacía y un valor “false” en caso que por lo menos el nodo “primero” tenga una referencia no nula. Es de notar que en el ejercicio que estamos desarrollando no estamos implementando el método que adiciona elementos a la lista, dado que pretendemos mostrar como usar el patrón “iterator” para mostrar elementos no para insertarlos en forma secuencial a como van llegando, porque de implementar esta funcionalidad el código que nos saldría para explicar el ejercicio seria demasiado grande para lo que estamos explicando. También tenemos un método llamado “primero()” que devuelve el primer objeto de la lista. Es de notar nuevamente que los métodos de la clase “Lista” que devuelven valores devuelven valores voléanos o referencias a objetos tipo “Object”, esto para lograr que sean lo mas genéricas posibles. De otra parte tenemos otro método llamado “elemento(int)” que recibe un valor entero y devuelve el objeto de la lista que corresponde con la posición que ocupa mencionado elemento y que debe ser igual al valor pasado como parámetro al método. Finalmente tenemos el método “tamano()” que devuelve un valor entero que indica cuantos elementos hay en la Lista. La Lista que hicimos en el anterior código debe ser manipulada por una colección especifica en este caso es manipulada por la colección “ColeccionLista” No olvidar que en este caso tenemos una situación en la que la estructura de almacenamiento es compuesta, es decir esta conformada por otras clases, en este caso una “Lista” esta conformada por objetos tipo “Nodo” que en nuestro caso particular almacenan valores tipo “String” y tienen una estructura que permite su relación de unos con otros por medio de una variable al interior de la clase Nodo llamada “siguiente”. La clase en mención tiene pues el siguiente código: Nodo.java public class Nodo{ String valor = null; Nodo siguiente = null; public Nodo(){ } public String getValor(){ return valor; } public void setValor(String valor){ this.valor = valor; } } // Cierra class Nodo La clase “ColeccionLista”, tiene el siguiente código: ColeccionLista.java import java.util.Vector; public class ColeccionLista implements ColeccionGenerica { public Lista estructuraAlmacenamiento = new Lista(); public Iterador creaIterador() { return new IteradorLista( this ); } } En este punto es bueno que el amigo lector / estudiante observe que las dos colecciones que estamos trabajando tienen un método llamado “creaIterador()” que devuelve una referencia al iterador concreto que manipula dicha colección, pero para los que lo reciben es un objeto de tipo “Iterador”, mas no se sabe específicamente que tipo de iterador es. Esto se hace con el animo de lograr total transparencia en el uso de dicho iterador por parte de los usuarios del mismo. Recordad que esto se puede hacer debido a que como ambos iteradores implementan la interface “Iterador”, se puede hacer casting hacia arriba en el árbol de herencia. La interface “Iterador” contiene el prototipo de los metodos que pueden ser invocados por los iteradotes concretos. Los metodos que pueden ser invocados son los metodos “mostrarElementos()” que muestra los elementos de la colección, el metodo “primero()” que devuelve una referencia al primer elemento de la colección, el metodo “ingresarElemento()” que aunque no es implementado en toda su expresión en los iteradotes concretos, indica al amigo lector / donde se puede implementar dicho metodo y finalmente el metodo “siguiente()” que devuelve o mas bien deberia devolver una referencia a un objeto que corresponde con el siguiente elemento de la colección, partiendo desde el ultimo elemento que se quizo devolver. Es de notar que estos metodo no han sido implementados en su totalidad en este ejercicio, pero para darle la minima funcionalidad a este ejercicio el metodo “mostrarElementos()” si fue implementado en su totalidad. Iterador.java public interface Iterador { Object primero() throws IndexOutOfBoundsException; void mostrarElementos() throws IndexOutOfBoundsException; void ingresarElemento() throws IndexOutOfBoundsException; Object siguiente() throws IndexOutOfBoundsException; // Object actualItem() throws IndexOutOfBoundsException; } Obviamente a bajo nivel los iteradores hacen cosas distintas aunque en forma lógica hacen lo mismo, la forma como lo hacen es distinta de si se esta manipulando una lista o de si se esta manipulando un Array, por esto a continuación se muestran cada una de las dos implementaciones tanto del “IteradorLista” como del “IteradorVectores”. Veamos primero el “IteradorLista”: IteradorLista.java public class IteradorLista implements Iterador { private ColeccionLista coleccion; private int indice = 0; public IteradorLista( ColeccionLista coleccion ) { this.coleccion = coleccion; } // Cierra constructor IteradorVectores public void mostrarElementos() throws IndexOutOfBoundsException { if( !coleccion.estructuraAlmacenamiento.esVacio() ) { int tamano = 0; tamano = coleccion.estructuraAlmacenamiento.tamano(); for(int i=0;i<tamano;i++){ Object objeto = coleccion.estructuraAlmacenamiento.elemento(i); System.out.println(objeto.toString()); } // Cierra for externo } else { System.out.println("No hay elementos en ColeccionLista"); return; } } // Cierra mostrarElementos() public void ingresarElemento() throws IndexOutOfBoundsException { } // Cierra ingresarElemento() public Object primero() throws IndexOutOfBoundsException { Object object = null; if( coleccion.estructuraAlmacenamiento!=null ) { indice = 0; object = coleccion.estructuraAlmacenamiento.primero(); } else { throw new IndexOutOfBoundsException(); } return object; } public Object siguiente() throws IndexOutOfBoundsException { Object object = null; if( indice + 1 < coleccion.estructuraAlmacenamiento.tamano() ) { indice = indice + 1; object = coleccion.estructuraAlmacenamiento.elemento(indice); } else { throw new IndexOutOfBoundsException(); } return object; } public Object actualItem() throws IndexOutOfBoundsException { Object object = null; if( indice < coleccion.estructuraAlmacenamiento.tamano() ) { object = coleccion.estructuraAlmacenamiento.elemento( indice ); } else { throw new IndexOutOfBoundsException(); } return object; } } Algo importante en la clase anterior es el constructor, ya que si no fuera por este no se le podría indicar al “IteradorLista” que manipule una colección concreta de tipo “ColeccionLista”. Observe también que los métodos del “IteradorLista” son capaces de lanzar excepciones tanto cuando se muestran los elementos de la colección concreta. No esta de más recalcar que el método “ingresarElemento()” no se ha implementado para hacer este ejercicio lo mas corto posible y tan solo mostrar como se usaría el patrón “Iterator” para mostrar elementos de una colección, pero obviamente se supone que para darle toda la funcionalidad al actual ejercicio, el amigo lector / estudiante debe implementar el método de “ingresarElemento()”. También se implementaron otros como el método “primero()” que devuelve una referencia tipo “Object” que corresponde con el primer elemento ingresado a la lista. La verdad los otros métodos se colocan a manera de ejercicio, pero no se usan, simplemente se colocan para que el lector / estudiante tenga una visión de cómo implementar en su totalidad del patrón “Iterator” en un ejercicio real. Ahora veamos el “IteradorVectores”: IteradorVectores.java public class IteradorVectores implements Iterador { private ColeccionVectores coleccion; private int indice = 0; public IteradorVectores( ColeccionVectores coleccion ) { this.coleccion = coleccion; } // Cierra constructor IteradorVectores public void mostrarElementos() throws IndexOutOfBoundsException { if( !coleccion.estructuraAlmacenamiento.esVacio() ) { int tamano = 0; tamano = coleccion.estructuraAlmacenamiento.tamano(); for(int i=0;i<tamano;i++){ Object objeto = coleccion.estructuraAlmacenamiento.elemento(i); System.out.println(objeto.toString()); } // Cierra for externo } else { System.out.println("No hay elementos en ColeccionVectores"); return; } } // Cierra mostrarElementos() public void ingresarElemento() throws IndexOutOfBoundsException { } // Cierra ingresarElemento() public Object primero() throws IndexOutOfBoundsException { Object object = null; if( !coleccion.estructuraAlmacenamiento.esVacio() ) { indice = 0; object = coleccion.estructuraAlmacenamiento.primero(); } else { throw new IndexOutOfBoundsException(); } return object; } public Object siguiente() throws IndexOutOfBoundsException { Object object = null; if( indice + 1 < coleccion.estructuraAlmacenamiento.tamano() ) { indice = indice + 1; object = coleccion.estructuraAlmacenamiento.elemento(indice); } else { throw new IndexOutOfBoundsException(); } return object; } public Object actualItem() throws IndexOutOfBoundsException { Object object = null; if( indice < coleccion.estructuraAlmacenamiento.tamano() ) { object = coleccion.estructuraAlmacenamiento.elemento( indice ); } else { throw new IndexOutOfBoundsException(); } return object; } } Al igual que la clase “IteradorLista” la clase anterior, es decir la clase “IteradorVector” tiene implementados muchos métodos que no son usados específicamente en este ejercicio, sino mas bien para indicarle al lector / estudiante donde debería implementar los métodos que manipulan las colecciones concretas. Lo importante en la clase anterior es tener en cuenta que el método “mostrarElementos()” debe estar mínimamente implementado en este ejercicio para darle una mínima funcionalidad al ejercicio que estamos haciendo. De otra parte observe que el método “mostrarElemjentos()” es capaz de lanzar excepciones, cosa muy importante para lograr que el iterador informe que tipo de error se ha presentado al manipular la colección concreta. Adicional a todo lo dicho hasta el momento es bueno que se compare los códigos fuentes de los métodos “mostrarElementos()” tanto de la clase “IteradorLista” como de la clase “IteradorVectores”, con lo cual obtenemos que el código del método “mostrarElementos()” de la clase “IteradorVectores” es el siguiente: Método “mostrarElementos()” de la clase “IteradorVectores” public void mostrarElementos() throws IndexOutOfBoundsException { if( !coleccion.estructuraAlmacenamiento.esVacio() ) { int tamano = 0; tamano = coleccion.estructuraAlmacenamiento.tamano(); for(int i=0;i<tamano;i++){ Object objeto = coleccion.estructuraAlmacenamiento.elemento(i); System.out.println(objeto.toString()); } // Cierra for externo } else { System.out.println("No hay elementos en ColeccionVectores"); return; } } // Cierra mostrarElementos() Y al compararlo con el método “mostrarElementos()” de la clase “IteradorLista”: Método “mostrarElementos()” de la clase “IteradorLista” public void mostrarElementos() throws IndexOutOfBoundsException { if( !coleccion.estructuraAlmacenamiento.esVacio() ) { int tamano = 0; tamano = coleccion.estructuraAlmacenamiento.tamano(); for(int i=0;i<tamano;i++){ Object objeto = coleccion.estructuraAlmacenamiento.elemento(i); System.out.println(objeto.toString()); } // Cierra for externo } else { System.out.println("No hay elementos en ColeccionLista"); return; } } // Cierra mostrarElementos() Vemos que es exactamente igual, con lo cual diremos que un beneficio del uso de una interface para la estructura de almacenamiento nos puede llevar a que se pueda incluso pensar en la creación de iteradores independientes funcionalmente hablando de la colección que se manipule. Y en otras palabras esto se comprende cuando nos damos cuenta que en el método “mostrarElementos()” para las dos colecciones el código no es dependiente de la colección manipulada. Finalmente diremos que teniendo los iteradores y las colecciones listas, lo único que hace falta es la creación de una vista que invoque la manipulación de la lista por medio de los iteradores y esto se puede hacer mediante un programa sencillo como el siguiente: MyApp.java public class MyApp { public static void main( String arg[] ) { try { ColeccionGenerica coleccioncilla1 = new ColeccionVectores(); Iterador objetoiterador1 = coleccioncilla1.creaIterador(); objetoiterador1.mostrarElementos(); ColeccionGenerica coleccioncilla2 = new ColeccionLista(); Iterador objetoiterador2 = coleccioncilla2.creaIterador(); objetoiterador2.mostrarElementos(); } catch( Exception e ) { e.printStackTrace(); } } } 29.4. OBSERVACIONES GENERALES AL EJERCICIO DESARROLLADO Mas que observaciones, son puntos que es bueno tener en cuenta para comprender el funcionamiento del ejercicio propuesto y su desarrollo acorde con el patrón “iterator”. Es bueno observar que los métodos en los que ColeccionVectores crea un IteradorVectores son métodos obligatorios por cuanto ColeccionVectores implementa ColeccionGenerica y si no puede implementar el método "creaIterador()" entonces no puede crearse el objeto. Lo cual hace que exista una fuerte cohesión entre estas dos clases. Es bueno observar que la cohesión en nuestro ejercicio es fuerte entre las colecciones y los iteradotes, debido a que "ColeccionVectores" no puede implementar "creaIterador()" si no se puede crear "IteradorVectores", pero al mismo tiempo un objeto de tipo "IteradorVectores" no puede crearse si no existe un objeto tipo "ColeccionVectores". Este tipo de cohesión en este caso es bien importante, debido a que se obliga que los dos existan. También es importante que se note que la cohesión no se puede hacer en ambos lados a nivel de constructor porque si no quedaría una redundancia cíclica en la que "ColeccionVectores" no puede crearse si no existe un objeto tipo "IteradorVectores" y un objeto tipo "IteradorVectores" no podría crearse si no existiera un objeto tipo "ColeccionVectores". Estas cuestiones obviamente a nivel de código generarían un problema pero como hemos visto se pueden solucionar con el uso de interfaces en un lado y con la dependencia a nivel de constructor en el otro lado. Es bueno observar que la forma de manipular una colección es por medio de un objeto de tipo "Iterador". Esta clase garantiza que las operaciones que se realizaran para operar la colección serán uniformes para cualquier colección que implemente la interface "ColeccionGenerica". De otra parte es bueno observar que la "ColeccionGenerica" obliga a que cualquier colección tipo "ColeccionGenerica" pueda obtener un "Iterador" para su manipulación interna y lo puede conseguir invocando el método "creaIterador()". En nuestro ejercicio hemos extendido el patrón haciéndole algunas mejoras para ver que es posible adaptar un patrón según las necesidades de un momento dado. En nuestro caso hemos obligado que los objetos de tipo "ColeccionGenerica" sean del tipo que sean como en nuestro caso "ColeccionLista" y "ColeccionVectores" tienen una estructura de almacenamiento que puede manipularse con el iterador pero dicha estructura internamente es distinta dependiendo la colección concreta que estemos manipulando. Lo interesante del asunto es que en nuestro ejercicio hacemos que esta estructura interna para cualquier colección tendrá en forma lógica una misma interface que permitirá que sus métodos expuestos para su manipulación desde el iterador sean uniformes en forma independiente del tipo de estructura. Esto se logra mediante la creación de una nueva "interface" que entra en juego en nuestro ejercicio. Dicha interface la hemos denominado "Estructura" y nos ayuda a dar uniformidad al manipular las estructuras concretas para cada colección concreta. Para comprobar que el uso de esta interfaz ayuda bastante simplemente podemos observar el código usado para mostrar una colección tipo "ColeccionVectores", es decir el código mostrado en el la clase "IteradorVectores" y específicamente en el método "mostrarElementos()", vemos que dado que en forma lógica una lista es muy similar a un Array, entonces la manipulación lógica es similar, la única diferencia es a nivel físico que los vectores tienen espacios de memoria consecutivos en tanto que las listas no siempre. Pero esta diferencia es física y no conceptual, con lo cual la forma de mostrar ambas estructuras a nivel lógico usando un iterador debe ser similar y efectivamente son iguales. Es decir que haciendo el código para mostrar un vector, desde el "IteradorVector", podemos copiar este mismo código en la clase "IteradorLista", debido a que esto es lógicamente igual. El amigo lector / estudiante estará pensando que estamos haciendo código igual y copiándolo de un método a otro, lo cual indica que hay algo mal en el diseño y en la programación, pero la verdad lo único que se esta haciendo es mostrando que para el caso de nuestro ejercicio los iteradores conocen conceptualmente la forma como se debe manipular una estructura, con lo cual si las estructuras resultan ser en forma abstracta iguales su manipulación es idéntica, lo cual permitirá que se puedan crear incluso mas adelante iteradotes comunes para Colecciones que sean semánticamente idénticas. Esto da una escalabilidad al código y termina por mostrarnos que aunque el esfuerzo inicial para crear este tipo de estructuras en cuanto a su concepción, una vez se hallan creado su facilidad de reuso hace que se puedan implementar en diversas situaciones en forma inmediata. Si el amigo lector / estudiante, examina el código presentado anteriormente y lo compara con las APIS que ofrece el lenguaje de programación Java y algunos otros lenguajes para manipular Colecciones, podrá observar que si tenemos una forma de pensar usando patrones podemos estar en capacidad de crear APIS para un lenguaje que puedan ser manipulables. Otra conclusión es que ahora si se comprenden algunos patrones arquitectónicos es posible desarrollar APIS y si tenemos en cuenta que los FRAMEWORKS según Francisco Javier Martínez Juan(Quien hizo un proyecto final de carrera titulado Guía de construcción de software en java con patrones de diseño)que dice que un Framework son bibliotecas de clases preparadas para su reutilización que pueden a su vez utilizar componentes diremos que el uso de patrones puede ayudar a la construcción de frameworks. Recordemos que autores como el mencionado anteriormente también dice que un "Framework es una mini arquitectura que proporciona la arquitectura genérica y el comportamiento para una familia de abstracciones a lo largo de un contexto de metáforas". Con lo cual diremos que el anterior programa teniendo en cuenta que usa la metáfora del almacenamiento secuencial bien sea como lista o como Array y muestra un funcionamiento genérico para una familia de abstracciones como en este caso los arrays y las listas, diremos que este tipo de lógica se puede implementar en APIS que puedan ser usadas por aplicaciones especificas para dar funcionalidad concreta a un dominio de aplicación. 29.5. TALLER PROPUESTO SOBRE EL EJERCICIO. 1. Hacer el diagrama de secuencia del ejercicio. 2. Hacer el diagrama de colaboración del ejercicio. 3. Modificar el anterior ejercicio para lograr que existe un solo Iterador y no iteradores concretos para cada colección. 4. Implementar los métodos de inserción de elementos en las dos colecciones mostradas. 5. Implementar los métodos de ordenamiento de elementos en las dos colecciones mostradas. 6. Adicionar al ejercicio mostrado la clase Árbol y sus respectivos iteradores y colecciones siguiendo el mismo esquema mostrado en el actual ejercicio. 7. Hacer una comparación entre la explicación dada de este patrón con la explicación dada por otras fuentes sobre el mismo patrón. 8. Hacer el diagrama de clases del ejercicio desarrollado. 9. Implementar este patrón en otro lenguaje de programación distinto a Java. 30. PATRON ADAPTADOR El patrón adaptador convierte la interfaz de una clase dada en la interfaz que el cliente desea. Esta es una primera definición al patrón adaptador, pero a continuación se muestra una definición un poco mas técnica del patrón que nos ira acercando a la implementación del mencionado patrón. 30.1. DEFINICION DEL PATRON ADAPTADOR En algunas ocasiones se desea adaptar una clase “A” que tiene una interfaz que no nos sirve para una determinada situación, pero sin necesidad de tener que crear otra clase “B” que tenga la interfaz que necesitamos, puesto que la funcionalidad ya se tiene, lo que no se tiene es la interfaz apropiada. Esta situación se puede entender mediante situaciones practicas y esta es precisamente la pedagogía con que se intentara explicar el patrón en esta sección. 30.2. UN EJEMPLO QUE USA EL PATRON ADAPTADOR Todos tenemos una idea de las cosas que puede hacer un “Hombre” y sabemos que un hombre es capaz de imitar a un “PERRO”, es mas, podríamos pensar que un método común a muchos hombres es imitar a un “PERRO”, para lograr establecer esta generalidad a diversos hombres, nos valemos de una interfaz que en nuestro ejercicio llamaremos “InterfazOriginalHombre” que contendrá el siguiente código: Archivo InterfazOriginalHombre.java public interface InterfazOriginalHombre { public void imitarPerro(); } Un “Hombre” con capacidades normales debería estar en capacidad de implementar la anterior funcionalidad. Esta situación la podemos desarrollar con la siguiente clase: Archivo Hombre.java public class Hombre implements InterfazOriginalHombre{ public void imitarPerro(){ System.out.println("GUAU GUAU"); } } // Cierra public class Hombre Resulta que hay una fiesta de disfraces, pero a esta fiesta no pueden asistir hombres común y corrientes, ni tampoco mascotas como perros, lo que si pueden asistir son hombres disfrazados de perros. Para nuestro ejercicio un hombre disfrazado de perro no requiere que se cree la clase “Perro”, por cuanto no se pueden llevar a la fiesta “Perros”. Todo lo que tenemos que saber sobre los perros es que si invocan el método “ladrar()”, suenan idéntico a como suena un hombre cuando invoca el método “imitarPerro()”. Por esta razón podemos decir que hay un modo de comportamiento que es aceptado en la fiesta y este modo de comportamiento lo podemos especificar mediante la interfaz especifica de la fiesta, que se muestra a nivel de programación a continuación: Archivo InterfazEspecificaFiesta.java public interface InterfazEspecificaFiesta { void ladrar(); } El anterior modo de comportamiento lo deben implementar los hombres disfrazados de perro que van a la fiesta, pero que al fin y al cabo siguen siendo hombres y por tanto extienden la funcionalidad de cualquier hombre. Por ello, podemos pensar en crear una clase llamada “HombreDisfrazadoPerro” que extienda de “Hombre” y que implemente la “InterfazEspecificaFiesta”, tal como se muestra a continuación: Archivo HombreDisfrazadoPerro.java public class HombreDisfrazadoPerro extends Hombre implements InterfazEspecificaFiesta { public void ladrar() { imitarPerro(); } } // Cierra class HombreDisfrazadoPerro Realmente esta clase es la parte mas importante del patrón “ADAPTADOR”, por cuanto va a permitir que una clase implemente una nueva interfaz y extendiendo de otra clase con otra interfaz. Pero en fin, para probar que las clases anteriores funcionan se hace necesario crear una clase que use la clase “HombreDisfrazadoPerro” y es precisamente esta clase, la que se muestra a continuación: Archivo Cliente.java public class Cliente { public static void main( String arg[] ) { try{ HombreDisfrazadoPerro perritoDeFiesta = new HombreDisfrazadoPerro(); perritoDeFiesta.ladrar(); } catch( Exception e ){ e.printStackTrace(); } // Cierra try } // Cierra static void main() } // Cierra class Cliente Al ejecutar todo el programa que hasta ahora se ha elaborado, obtenemos unos resultados similares a los siguientes: GUAU GUAU Exit code: 0 No Errors Y ahora haciendo lo de lo cangrejos que caminan hacia atrás, veamos mediante un diagrama de clases la solución arquitectónica que se formulo para resolver el problema del hombre que debe adaptarse al comportamiento de un perro sin volverse perro, pero sin dejar de ser hombre. <<Interface>> InterfazOriginalHombre <<Interface>> InterfazEspecificaFiesta Cliente Hombre HombreDisfrazadoPerro En el código del ejemplo anterior se vio que la clase “Cliente”, usaba objetos de tipo “HombreDisfrazadoPerro” con la interfaz conocida para dicho cliente “InterfazEspecificaFiesta”, de otra parte “HombreDisfrazadoPerro” es un tipo de hombre y el “Hombre” desde antes de adaptarlo a hombre disfrazado ya implementaba la interfaz “InterfazOriginalHombre”. Es bueno tener en cuenta que un hombre sigue teniendo las dos conductas, la conducta con la interfaz “InterfazOriginalHombre” y la conducta dada por la interfaz “InterfazEspecificaFiesta”, lo que pasa es que el cliente tan solo conoce la interfaz llamada “InterfazEspecificaFiesta”. Un buen ejercicio para verificar que el “Hombre” en su connotación de disfrazado de Perro, podría eventualmente actuar como un “Hombre”, es porque ante el cliente también se deja disponible la interfaz original que tiene un hombre, pero como la interfaz conocida en nuestro caso al interior de la fiesta es la interfaz de un hombre disfrazado de perro, tendremos visible el método “ladrar()”, pero vuelvo y repito que los dos métodos están disponibles para los usuarios, lo que pasa es que si alguien no los conoce pues no van a solicitar este comportamiento. Para no ser tan teóricos a continuación mostramos una variación a la ultima clase, o sea a la clase “Cliente” Archivo Cliente.java public class Cliente { public static void main( String arg[] ) { try{ HombreDisfrazadoPerro perritoDeFiesta = new HombreDisfrazadoPerro(); perritoDeFiesta.ladrar(); perritoDeFiesta.imitarPerro(); } catch( Exception e ){ e.printStackTrace(); } // Cierra try } // Cierra static void main() } // Cierra class Cliente En la cual vemos que al ejecutar el anterior programa obtenemos unos resultados similares a los siguientes: GUAU GUAU GUAU GUAU Exit code: 0 No Errors 30.3. ESTRUCTURA GENERAL DEL PATRON ADAPTADOR El ejercicio mostrado en esta unidad, no es mas que una solución adaptada de un patrón general llamado el patrón adaptador, cuyo diagrama de clases es el que se muestra a continuación: Client Adaptee Target Adapter Se ha colocado los nombre originales en ingles para que se encuentre la relación entre la explicación dada mediante el ejercicio de esta unidad y el modelo de clases mostrado en la literatura clásica sobre patrones de software. En nuestro caso podíamos decir que al comparar el diagrama anterior con el diagrama de clases de nuestro ejemplo, tenemos la siguiente relación: CLASE CLASICA Target Adapter Adaptee Client LITERATURA CLASE DE NUESTRA EXPLICACION SOLUCION InterfazEspecificarFiesta Define la interfaz que es visible para el cliente. HombreDisfrazadoPerro Adapta la interfaz del objeto adaptado que en este caso es “Hombre” a la definida por el Target. InterfazOriginalHombre Hace referencia a la Hombre interfaz y al objeto que se van a adaptar. En el caso de nuestro ejercicio se hizo una separación de la clase y la interfaz a la que el implementase. Cliente Es el que manipula el objeto adaptado 30.4. OTRAS APLICACIONES DEL PATRON ADAPTADOR Es posible que se pretenda aplicar el patrón adaptador con una variante y es haciendo que no solamente se pueda adaptar una clase, sino todas sus subclases mediante la adaptación de la interfaz de su clase padre que tiene en común. Esta aplicación es usando el patrón adaptador y se deja la implementación de este caso al amigo lector / estudiante. Otra aplicación del patrón adaptador es cuando se tienen clases “A”, “B”, “C” y “D” que tienen una interfaz “original” y se pretende crear una clase colaboradora de todas ellas pero que tiene una interfaz incompatible con todas ellas. La implementación para esta situación también se deja a cargo del amigo lector / estudiante, pero teniendo presente que se usa la misma lógica mostrada en el diagrama de clases para el patrón adaptador. 31. PAQUETES Y DIAGRAMA DE PAQUETES Existen dos tipos de paquetes tal como lo muestra la siguiente figura: TIPOS DE PAQUETES Paquete del código fuente del sistema Paquete del binario del sistema Realmente los paquetes solucionan el problema de agrupar clases en un nivel mas alto, e incluso permiten agrupar paquetes en otros paquetes de nivel mas alto. Muchos autores relacionan pues el concepto de espacio de nombres con el concepto de paquetes en java y tienen toda la razón, por cuanto los espacios de nombres lo que hacen es permitir agrupar una serie de clases dentro de un espacio de nombres, de tal manera que si llegase a existir otra clase con el mismo nombre pero en distinto espacio de nombres, se podría usar la invocación completa de la clase anteponiendo a esta la ruta en la que se encuentra el paquete inmediatamente contenedor de esta clase en la cual se encuentra ubicada la misma, esto con el fin de lograr que coexistan dos clases con el mismo nombre dentro de una misma aplicación. De lo dicho anteriormente vemos que los paquetes a parte de ser un concepto de agrupación de clases y que permite recursivamente hacer agrupaciones de alto nivel en donde se incluyan incluso otros paquetes, solucionan el problema de los nombres repetidos de las clases y su uso. De otra parte los paquetes son uno de los mecanismos mas importantes que se tienen para descomponer un sistema grande en subsistemas más pequeños, cosa que es muy útil sobre todo en sistemas altamente grandes y complejos. Para comprender bien el tema de los paquetes y de los diagramas de paquetes se harán algunos ejercicios de creación de paquetes en java, se expondrán algunos conceptos que espero ayuden a que el amigo lector / estudiante comprenda el concepto de paquete y el funcionamiento de los diagramas de paquetes. 31.1. LOS JAR Y LOS PAQUETES En java existe el concepto de archivo “jar” que no es mas que un archivo que se puede ejecutar en una maquina virtual y que contiene los archivos binarios, fruto de la compilación de las clases. Para comprender este concepto supongamos una clase como la mostrada a continuación: Archivo MyApp.java import java.awt.*; import java.awt.event.*; public class MyApp extends Frame { public MyApp() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); } public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(100,100); f.setVisible(true); } } La cual básicamente consiste en una aplicación autónoma que muestra una pantalla cuadrada de 100 píxeles de alto por 100 de ancho con un botón de cerrar habilitado en la parte superior-izquierda que hará que se cierre la aplicación cuando el usuario haga clic sobre dicho botón de ventana. Al compilar el anterior programa se crean dos archivos, tal como muestra la siguiente grafica: Se crea una carpeta llamada “META-INF” preferiblemente en el mismo lugar donde están los archivos “.class” de tal forma que queda la siguiente estructura: Al interior de la carpeta “META-INF” se crea un archivo llamado “MANIFEST.MF”, el cual contendrá el siguiente código: Archivo MANIFEST.MF Manifest-Version: 1.0 Created-By: 1.6.0 (Sun Microsystems Inc.) Main-Class: MyApp En donde nos podemos dar cuenta que estamos indicando en este archivo cual es la clase que tiene el método “public static void main(String arg[])”. En nuestro caso de ejemplo la clase “MyApp” es la que contiene el archivo inicial de la aplicación(no hay de hecho mas que un archivo en nuestro ejemplo). Por ultimo creamos un archivo “MyApp.zip” y en el añadimos los archivos “MyApp$1.class”, “MyApp.class” y la carpeta “META-INF” (que contiene el archivo “MANIFEST.MF”). Recuerde que el archivo “MyApp.zip” se puede crear con un compresor que permita crear archivos en formato “.zip”. Hasta ahora la situación gráficamente es como se muestra a continuación: Ahora procedemos a renombrar el archivo “MyApp.zip” en donde tan solo le cambiamos la extensión y le colocamos el nombre “MyApp.jar”. A veces los sistemas operativos muestran que se va a cambiar la extensión del archivo con un mensaje similar al siguiente: El resultado de haber alterado la extensión se muestra a continuación: Lo interesante del asunto es que si hacemos clic derecho sobre el archivo señalado en la grafica anterior obtenemos un menú contextual similar al siguiente: Dado que los archivos “.jar” son ejecutables de java, podemos pensar en ejecutarlo con la maquina virtual instalada en la maquina que es precisamente lo que se intenta hacer en la grafica anterior. El resultado de la ejecución del anterior programa con la maquina virtual es similar al siguiente: A nivel de UML podemos graficar el paquete creado de la siguiente forma: MyApp Que indica que el paquete creado se llama “MyApp.jar”, pero es posible que queramos que en el modelamiento queden los nombres de los binarios que se encuentran en dicho paquete, cosa que se podría hacer mediante la siguiente notación UML: MyApp MyApp.class MyApp$1.class 31.2. PAQUETES ANIDADOS 32. FLUJO DE PRUEBAS Las pruebas de una aplicativo son uno de los insumos más importantes a la hora de decidir si se implementa el aplicativo o no. Realmente probar cada modulo de un programa se denomina hacer pruebas unitarias. 32.1. FUNCIONAMIENTO DE JUNIT En el caso de Junit se hacen pruebas por clase, es decir que a cada clase se le hace su prueba unitaria. Para cada clase creamos una clase de caso de prueba, lo cual gráficamente puede verse como se muestra en el siguiente diagrama: Casos de prueba para cada una de las clases Caso de prueba para Clase 1 Caso de prueba para Clase 2 Caso de prueba para Clase 3 Caso de prueba para Clase 4 Caso de prueba para Clase 1 Clase 1 Clase 2 Clase 3 Clase 4 Clase 1 Clases de la aplicación que deseamos hacerles las pruebas unitarias Los casos de prueba pueden agruparse según su funcionalidad en suites de prueba (test suite), lo cual gráficamente puede verse como se muestra a continuación: Suites de prueba según funcionalidad 1 Suites de prueba según funcionalidad 2 Suites de prueba según funcionalidad 3 Caso de prueba para Clase 1 Caso de prueba para Clase 3 Caso de prueba para Clase 3 Caso de prueba para Clase 2 Caso de prueba para Clase 7 Caso de prueba para Clase 7 Podemos seguir agrupando suites de prueba en suites de prueba con lo cual tenemos una estructura similar a la siguiente: Suites de prueba según funcionalidad A Suites de prueba según funcionalidad B Suites de prueba según funcionalidad 1 Suites de prueba según funcionalidad 2 Suites de prueba según funcionalidad 3 Caso de prueba para Clase 1 Caso de prueba para Clase 3 Caso de prueba para Clase 3 Caso de prueba para Clase 2 Caso de prueba para Clase 7 Caso de prueba para Clase 7 Con lo cual vemos que las suites de prueba se organizan en forma de árbol y cuando aplicamos una suite de pruebas ejecutamos las suites de pruebas que se encuentran dentro de esta suite de prueba. Obviamente esto permite acelerar el proceso de testeo de aplicaciones, debido a que permite aplicar todo un subárbol o un árbol a un conjunto de clases. 32.2. CONSTRUCCION DE LA CLASE QUE VAMOS A PROBAR Vamos a construir una clase denominada “Lista” que va a contener elementos de tipo Nodo, los cuales tienen la estructura determinada por la siguiente clase: Nodo.java public class Nodo{ Nodo siguiente; int valor; public Nodo(){ siguiente = null; } } // Cierra class Nodo Y ahora si la clase “Lista” propiamente dicha que contiene el siguiente código: Lista.java import java.awt.*; import java.awt.event.*; public class Lista{ Nodo cabeza = null; Nodo ultimo = null; public boolean buscarNodo(int valor){ boolean buscado = false; if(cabeza==null){ return buscado; } // Cierra if externo else{ Nodo correr = cabeza; while(correr!=null){ if(correr.valor==valor){ buscado = true; break; } correr = correr.siguiente; } // Cierra while } // Cierra else externo return buscado; } // Cierra boolean buscarNodo // Ingresa elementos a la lista sin importar // si los elementos ya se encuentran, tampoco // importa el orden, siempre lo dejara al // final de la lista el ultimo elemento // ingresado. public void ingresarNodo(int valor){ boolean encontrado = buscarNodo(valor); if(!encontrado){ Nodo nuevo = new Nodo(); nuevo.valor = valor; if(cabeza==null){ cabeza = nuevo; ultimo = nuevo; } else{ Nodo antes = cabeza; Nodo despues = cabeza; while(despues!=null){ if(despues.valor>valor){ break; } antes = despues; despues = despues.siguiente; } // Cierra while interno antes.siguiente = nuevo; nuevo.siguiente = despues; } // else interno } // Entra al if cuando no existe } // Cierra void ingresarNodo() public String getListado(){ Nodo correr = cabeza; String cadena = ""; while(correr!=null){ cadena = cadena + correr.valor; cadena = cadena + " "; correr = correr.siguiente; } // Cierra while return cadena; } // Cierra String imprimirLista() public Lista(Nodo nodin){ cabeza = nodin; Nodo corre = cabeza; while(corre!=null){ if(corre.siguiente==null){ ultimo = corre; } corre = corre.siguiente; } // Cierra while }// Cierra public MyApp() public boolean comparar(Lista objeto){ boolean retornar=true; if(objeto!=null){ Nodo correr1 = cabeza; Nodo correr2 = objeto.cabeza; // Nodo correr2 = objeto.cabeza.siguiente; while(correr1!=null){ if(correr1.valor!=correr2.valor){ retornar = false; } correr1 = correr1.siguiente; correr2 = correr2.siguiente; if(correr1==null && correr2!=null){ retornar = false; } if(correr1!=null && correr2==null){ retornar = false; } } // Cierra while if(correr2!=null){ retornar = false; } return retornar; } // Cierra if externo return false; } // Cierra boolean comparar } // Cierra class Lista Realmente el objetivo de la creación de la clase anterior es tener una clase que permita adicionar elementos a la lista, teniendo en cuenta que el comienzo de la lista esta referenciado por una variable llamada “cabeza”. La inserción de elementos en la lista se hace con el método “ingresarNodo(int)”. Dicho método verifica que no existan elementos en la lista mediante la invocación del método “boolean buscarNodo(int valor)”, el cual retorna “true” cuando existe en la lista un Nodo cuyo valor es igual al solicitado, el método retorna “false” en caso que no exista coincidencia alguna. La lista permite el ingreso de elementos en forma ordenada y ascendente según el valor contenido en la variable “valor” de cada Nodo. El amigo lector / estudiante se estará preguntando: ¿Por qué incluir mas métodos si solamente se va a probar el método “ingresarNodo(int)”?. La respuesta es bien sencilla: “Se requieren otros métodos para que Junit logre probar correctamente el método ingresarNodo(int) y también se requieren otros métodos para que en si el método funcione”. Detalladamente podemos decir que el método “String getListado()” se coloco como un ejercicio suelto porque ni es necesario para que funcione Junit, ni es necesario para que funcione la inserción. De otra parte el método “boolean buscarNodo(int valor)” es necesario para que funcione el método “ingresarNodo(int)”. El constructor de la clase “Lista” es necesario simplemente para garantizar que cuando se cree una lista, es porque existe por lo menos un primer elemento “cabeza” que se debe almacenar en mencionada lista. Finalmente decimos que la clase “Lista” tiene un método llamado “boolean comparar(Lista objeto)” y este método es necesario para que funcione Junit, debido a que es con la invocación de este método que vamos a comparar dos listas, una que se construye manualmente y otra que se construye invocando el método “ingresarNodo(int)” de la clase “Lista”. Esta ultima parte se explicara con detalle cuando se este explicando el testeo de la aplicación. 32.3. CONSTRUCCION DE CASO DE PRUEBA PARA CLASE LISTA Ha llegado el momento de crear nuestro caso de prueba para la clase que anteriormente denominábamos “Lista”, para ello comenzamos diciendo que debemos usar el paquete “framework” como se muestra a continuación: import junit.framework.*; También es importante mencionar que nuestra clase de prueba debe extender de la clase “TestCase” tal como se muestra a continuación: public class ListaTest extends TestCase{ } Otra cuestión importante de mencionar es que el constructor de la clase “ListaTest” debe recibir un “String” como parámetro, tal como se muestra a continuación: public ListaTest(String nombre){ super(nombre); } // Cierra constructor ListaTest() Ahora creamos un método llamado “testIngresarNodo()” con el que probaremos el método “ingresarNodo(int)” de la clase “Lista”. Veamos entonces detenidamente como es que funciona el método para el testeo. Creamos manualmente 5 nodos con el estereotipo “static”: final final final final final static static static static static Nodo Nodo Nodo Nodo Nodo nodo1Lista2 nodo2Lista2 nodo3Lista2 nodo4Lista2 nodo5Lista2 = = = = = new new new new new Nodo(); Nodo(); Nodo(); Nodo(); Nodo(); Les asignamos unos valores: nodo1Lista2.valor nodo2Lista2.valor nodo3Lista2.valor nodo4Lista2.valor nodo5Lista2.valor = = = = = 1; 5; 2; 3; 4; Los ingresamos a la lista usando el metodo “ingresarNodo(int)”: Lista listaPROBANO = new Lista(nodo1Lista2); listaPROBANO.ingresarNodo(nodo1Lista2.valor); listaPROBANO.ingresarNodo(nodo2Lista2.valor); listaPROBANO.ingresarNodo(nodo3Lista2.valor); listaPROBANO.ingresarNodo(nodo4Lista2.valor); listaPROBANO.ingresarNodo(nodo5Lista2.valor); Se supone que si el método funciona como debe funcionar correctamente la lista tendría los siguientes nodos: 1 2 3 4 5 listaPROBANO Recordemos que esto debería funcionar debido a que en teoria el metodo “ingresarNodo(int)” ingresa elementos siempre y cuando no existan y los va ingresando en forma ordenada ascendentemente. Ahora bien, vamos a proceder a realizar una lista que con seguridad sabemos que forma tiene, debido a que se ha hecho en forma manual: Lista listaBIEN = new Lista(nodo1Lista1); final final final final final static static static static static Nodo Nodo Nodo Nodo Nodo nodo1Lista1 nodo2Lista1 nodo3Lista1 nodo4Lista1 nodo5Lista1 = = = = = new new new new new Nodo(); Nodo(); Nodo(); Nodo(); Nodo(); Y la enlazamos manualmente tal como se muestra a continuación: nodo1Lista1.siguiente nodo2Lista1.siguiente nodo3Lista1.siguiente nodo4Lista1.siguiente = = = = nodo2Lista1; nodo3Lista1; nodo4Lista1; nodo5Lista1; Obviamente tenemos gráficamente una lista similar a la siguiente: 1 2 3 4 5 listaBIEN Las comparamos e informamos a Junit el resultado de dicha comparación invocando el método “assertTrue(boolean x)”. Junit se encargara automáticamente de verificar que el método funcione como queremos que funcione. Observemos también que con esta forma de hacer pruebas uno puede definir manualmente los objetos que producen los métodos que se van a probar y luego al ser comparados con los verdaderos objetos que retorna la ejecución de estos métodos podremos saber si realmente funcionan nuestros métodos como lo esperábamos. Veamos pues el código completo de nuestra clase de testeo: ListaTest.java import junit.framework.*; public class ListaTest extends TestCase{ final final final final final static static static static static Nodo Nodo Nodo Nodo Nodo nodo1Lista1 nodo2Lista1 nodo3Lista1 nodo4Lista1 nodo5Lista1 = = = = = new new new new new Nodo(); Nodo(); Nodo(); Nodo(); Nodo(); final final final final final static static static static static Nodo Nodo Nodo Nodo Nodo nodo1Lista2 nodo2Lista2 nodo3Lista2 nodo4Lista2 nodo5Lista2 = = = = = new new new new new Nodo(); Nodo(); Nodo(); Nodo(); Nodo(); public void testIngresarNodos(){ nodo1Lista1.siguiente nodo2Lista1.siguiente nodo3Lista1.siguiente nodo4Lista1.siguiente = = = = nodo1Lista1.valor nodo2Lista1.valor nodo3Lista1.valor nodo4Lista1.valor nodo5Lista1.valor = = = = = 1; 2; 3; 4; 5; nodo1Lista2.valor nodo2Lista2.valor nodo3Lista2.valor nodo4Lista2.valor nodo5Lista2.valor = = = = = 1; 5; 2; 3; 4; nodo2Lista1; nodo3Lista1; nodo4Lista1; nodo5Lista1; Lista listaBIEN = new Lista(nodo1Lista1); Lista listaPROBANO = new Lista(nodo1Lista2); listaPROBANO.ingresarNodo(nodo1Lista2.valor); listaPROBANO.ingresarNodo(nodo2Lista2.valor); listaPROBANO.ingresarNodo(nodo3Lista2.valor); listaPROBANO.ingresarNodo(nodo4Lista2.valor); listaPROBANO.ingresarNodo(nodo5Lista2.valor); assertTrue(listaBIEN.comparar(listaPROBANO)); } // Cierra void testIngresarNodos() public ListaTest(String nombre){ super(nombre); } // Cierra constructor ListaTest() } // Cierra class ListaTest 32.4. ELABORACION DEL PROGRAMA QUE EJECUTA LA PRUEBA Ya hemos creado la clase que vamos a probar, también hemos creado la clase que hace la prueba y nos vamos a disponer a realizar un programa principal que dispare la ejecución del framework junit, dicho programa es el siguiente: MyApp.java import java.awt.*; import java.awt.event.*; public class MyApp{ public static void main (String[] args) { String[] nombresTest = {ListaTest.class.getName()}; junit.swingui.TestRunner.main(nombresTest); } } // Cierra class MyApp El anterior programa lo que hace es ejecutar la herramienta “TestRunner” que usa a la clase “ListaTest” para probar la clase “Lista”. 32.5. EJECUCION DEL TESTRUNNER Al ejecutar el anterior programa tenemos un resultado similar al siguiente: En donde podemos escoger la ficha que muestra el árbol de pruebas, el cual nos presenta una interfaz similar a la siguiente: Observamos pues que para nuestro ejercicio el metodo “testIngresarNodos” responde satisfactorio en la ejecución de las pruebas. Para comprobar que esto realmente es cierto vamos a modificar la clase “Lista” y la dejaremos tal como se muestra a continuación: Lista.java import java.awt.*; import java.awt.event.*; public class Lista{ Nodo cabeza = null; Nodo ultimo = null; public boolean buscarNodo(int valor){ boolean buscado = false; if(cabeza==null){ return buscado; } // Cierra if externo else{ Nodo correr = cabeza; while(correr!=null){ if(correr.valor==valor){ buscado = true; break; } correr = correr.siguiente; } // Cierra while } // Cierra else externo return buscado; } // Cierra boolean buscarNodo // Ingresa elementos a la lista sin importar // si los elementos ya se encuentran, tampoco // importa el orden, siempre lo dejara al // final de la lista el ultimo elemento // ingresado. public void ingresarNodo(int valor){ boolean encontrado = buscarNodo(valor); if(!encontrado){ Nodo nuevo = new Nodo(); nuevo.valor = valor; if(cabeza==null){ cabeza = nuevo; ultimo = nuevo; } else{ Nodo antes = cabeza; Nodo despues = cabeza; while(despues!=null){ if(despues.valor>valor){ break; } // LO DEJAMOS EN COMENTARIO PARA // QUE ESTO INTENCIONALMENTE FUNCIONE // MAL Y PROVOQUE QUE EL JUNIT // INFORME DE UN ERROR POR AQUI. // antes = despues; despues = despues.siguiente; } // Cierra while interno antes.siguiente = nuevo; nuevo.siguiente = despues; } // else interno } // Entra al if cuando no existe } // Cierra void ingresarNodo() public String getListado(){ Nodo correr = cabeza; String cadena = ""; while(correr!=null){ cadena = cadena + correr.valor; cadena = cadena + " "; correr = correr.siguiente; } // Cierra while return cadena; } // Cierra String imprimirLista() public Lista(Nodo nodin){ cabeza = nodin; Nodo corre = cabeza; while(corre!=null){ if(corre.siguiente==null){ ultimo = corre; } corre = corre.siguiente; } // Cierra while }// Cierra public MyApp() public boolean comparar(Lista objeto){ boolean retornar=true; if(objeto!=null){ Nodo correr1 = cabeza; Nodo correr2 = objeto.cabeza; // Nodo correr2 = objeto.cabeza.siguiente; while(correr1!=null){ if(correr1.valor!=correr2.valor){ retornar = false; } correr1 = correr1.siguiente; correr2 = correr2.siguiente; if(correr1==null && correr2!=null){ retornar = false; } if(correr1!=null && correr2==null){ retornar = false; } } // Cierra while if(correr2!=null){ retornar = false; } return retornar; } // Cierra if externo return false; } // Cierra boolean comparar } // Cierra class Lista Al ejecutar el Junit con este error, tenemos un pantallaza similar al siguiente: Los otros errores que se muestran en la caja de abajo, se muestran a continuación: 33. SOBRE LA CALIDAD DEL SOFTWARE 33.1. MODELOS DE CALIDAD En la siguiente tabla se muestran los modelos mas conocidos sobre calidad: MODEL O CARACTERISTICAS VENTAJAS SPICE Se utiliza para la mejora de procesos y determinación de la capacidad. Incluye un proceso de medición. CMM Abarca todos los procesos relacionados con el desarrollo del software Nos dicen que debemos hacer Medio para evaluar que tan bien o mal esta la organización CMMI Abarca todos Combina la experiencia y conocimiento aportado por CMM, Trilliumy Bootstrapent re otros. Alinear las AREAS DE APLICACIÓ N NORMA S QUE APLICA N los procesos relacionados con el desarrollo del software Se deben usar como referencia para definir procesos en una organización y para autoevaluació n Evolución de CMM con el objetivo de facilitar la integración de varios modelos de forma simultánea. Incorpora un área de proceso dedicada a “Medición y Análisis”para dar soporte al resto de áreas de proceso. El estado de madurez se divide en 6 niveles (incompleto, ejecutado, gestionado, definido, cuantitativame actividades de análisis de la medición Establecer los objetivos de la medición. Especificar medidas. Especificar procedimient os de recogida y almacenamie nto. Especificar procedimient os de análisis. Proporcionarlos resultados de la medición. Recoger los datos de la medición. Analizar los datos de la medición Almacenar los datos y resultados Comunicar los resultados nte gestionado y optimizado). PSP Enfocado en individuos Enfocados a la ingeniería de productos de software Nos dice el cómo debemos hacer las cosas Se usa como guía para ejecutar proyectos Se basa en la mejora de los procesos, pero centrándose en el ingeniero de software. Se trata de un proceso software diseñado para mejorar las actividades y la productividad de los ingenieros. La calidad depende del trabajo de los ingenieros de software. Mejora la planeación del trabajo. Mejora técnicas de desarrollo. Proyectos cortos y de poca calidad. TSP Enfocados en equipos (incluye psp) Enfocados a la ingenieria del •Diseñado con el objetivo de facilitar alcanzar el nivel 5 CMM. Contribuye a software Proporciona los fundamentos necesarios para construir y guiar a un grupo de ingenieros software, que primero deben saber controlar su trabajo, y después saber trabajar en equipo. TICKLT la administració n eficiente de proyectos. Enfocados en reducir riesgos e incertidumbr e en un proyecto de software. Utiliza estrategias para lograr la certificación en productos software 33.2. MODELO SPICE Una norma que especifica el modelo SPICE es: Norma UNE 66-001-92 traducción de ISO 8402 33.3. NORMA ISO 9000-2000 ISO-9001 ISO9000-3 Es una norma internacional destinada a evaluar la capacidad de la organización para cumplir los requisitos del cliente, los reglamentarios y los propios de la organización. Ventajas Tiene un mecanismo de certificación bien establecido. Está disponible y es conocida. Desventajas No es específica para la industria de software. No es fácil de entender. No está definida como un conjunto de procesos. No es fácil de aplicar. 33.4. NORMA ISO 90003 Esta norma internacional proporciona una guía a las organizaciones para la aplicación de la ISO 9001:2000 para la adquisición, suministro, desarrollo, instalación y mantenimiento de SOFTWARE y servicios de soporte. - No cambia ni añade los requisitos de la ISO 9001:2000. - No está destinada para ser utilizada como criterio de evaluación en el registro/certificación del sistema de calidad. 33.5. NORMA ISO/IEC TR 15504 Define el modelo de referencia de procesos de software y de capacidades de procesos que constituyen la base para la evaluación de procesos de software. Se compone de 9 partes de las cuales la 2, 3 y 9 son normativas y las demás informativas. Ventajas Específico para el desarrollo y mantenimiento de software. Fácil de entender (24 procesos, 16 páginas). Definido como un conjunto de procesos. Orientado a mejorar los procesos para contribuir a los objetivos del negocio. Desventajas No es práctico ni fácil de aplicar. Tiene solamente lineamientos para un mecanismo de evaluación. Todavía no es norma internacional. Proporciona un marco de trabajo para la evaluación del proceso y establece los requisitos mínimos para realizar una evaluación que asegure la repetibilidad y consistencia de las valoraciones obtenidas El objetivo de la evaluación del proceso es conocer la capacidad de los procesos de una organización. Como resultado de una exitosa implementación de la evaluación de los procesos se determina la información que caracteriza los procesos evaluados y el punto hasta el cual los procesos realizan su propósito 33.6. ESTANDAR ISO 9126 El estándar ISO 9126 define 6 atributos de calidad del software que son la funcionalidad, la confiabilidad, la facilidad de uso, la eficiencia, la facilidad de mantenimiento y la portabilidad, a continuación se explican en detalle cada uno de ellos: Funcionalidad: El grado en el que un sistema satisfacen las necesidades que indican los siguientes subatributos: idoneidad, exactitud, interoperabilidad, cumplimiento y seguridad. Confiabilidad: La cantidad de tiempo en que el software esta disponible para usarlo según los siguientes atributos: madurez, tolerancia a fallas y facilidad de recuperación. Facilidad de uso: La facilidad con que se usa el software de acuerdo con los siguientes subatributos: facilidad de comprensión, facilidad de aprendizaje y operabilidad. Eficiencia: El grado en que el software emplea en forma optima los recursos del sistema, como lo indican los siguientes subatributos: comportamiento en el tiempo, comportamiento de los recursos. Facilidad de mantenimiento: La facilidad con que se repara el software de acuerdo con los siguientes subatributos, facilidad de análisis, facilidad de cambio, estabilidad y facilidad de prueba. Portabilidad: La facilidad con que se lleva un software de un entorno a otro según los siguientes atributos: adaptabilidad, facilidad para instalarse, cumplimiento, facilidad para reemplazarse. Y aunque los anteriores atributos no se pueden medir directamente son una base para realizar medidas indirectas. 33.7. MODELOS CMMI Los 6 niveles definidos en CMMI para medir la capacidad de los procesos son: 0. Incompleto: El proceso no se realiza, o no se consiguen sus objetivos. 1. Ejecutado: El proceso se ejecuta y se logra su objetivo. 2. Gestionado: Además de ejecutarse, el proceso se planifica, se revisa y se evalúa para comprobar que cumple los requisitos. 3. Definido: Además de ser un proceso gestionado se ajusta a la política de procesos que existe en la organización, alineada con las directivas de la empresa. 4. Cuantitativamente gestionado: Además de ser un proceso definido se controla utilizando técnicas cuantitativas. 5. Optimizado: Además de ser un proceso cuantitativamente gestionado, de forma sistemática se revisa y modifica o cambia para adaptarlo a los objetivos del negocio. Conocimientos incluidos y disponibles en CMMI Systems engineering (SE) Software engineering (SW) Integrated product and process development (IPPD) Supplier sourcing (SS) Su contenido integra y da relevo a la evolución de sus predecesores: CMM-SW (CMM for Software) SE-CMM (Systems Engineering Capability Maturity Model) IPD-CMM (Integrated Product Development) VENTAJAS REPRESENTACIÓN POR ETAPAS Su contenido integra y da relevo a la evolución de sus predecesores: CMM-SW (CMM for Software) SE-CMM (Systems Engineering Capability Maturity Model) IPD-CMM (Integrated Product Development) REPRESENTACION CONTINUA Su contenido integra y da relevo a la evolución de sus predecesores: CMM-SW (CMM for Software) SE-CMM (Systems Engineering Capability Maturity Model) IPD-CMM (Integrated Product Development) AREAS DE APLICACIÓN Área de proceso Categoría Nivel de madurez Análisis y resolución de problemas Soporte 5 Gestión de la configuración Soporte 2 Análisis y resolución de decisiones Soporte 3 Gestión integral de proyecto Gestión de proyectos 3 Gestión integral de proveedores Gestión de proyectos 3 Gestión de equipos Gestión de proyectos 3 Medición y análisis Soporte 2 Entorno organizativo para integración Soporte 3 Innovación y desarrollo Gestión de procesos 5 Definición de procesos Gestión de procesos 3 Procesos orientados a la organización Gestión de procesos 3 Rendimiento de los procesos de la org. Gestión de procesos 4 Formación Gestión de procesos 3 Integración de producto Ingeniería 3 Monitorización y control de proyecto Gestión de proyectos 2 Planificación de proyecto Gestión de proyectos 2 Gestión calidad procesos y productos Soporte 2 Gestión cuantitativa de proyectos Gestión de proyectos 4 Desarrollo de requisitos Ingeniería 3 Gestión de requisitos Ingeniería 2 Gestión de riesgos Gestión de proyectos 3 Gestión y acuerdo con proveedores Gestión de proyectos 2 Solución técnica Ingeniería 3 Validación Ingeniería 3 Verificación Ingeniería 3 33.8. TALLER PROPUESTO DE CALIDAD 1. Averiguar los factores de calidad de McCall. 2. Realizar un ejemplo de un programa sencillo y de forma creativa intentar medir la funcionalidad, la confiabilidad, la facilidad de uso, la eficiencia, la facilidad de mantenimiento y la portabilidad. 3. Investigar según el estándar ISO 9126 que significa: idoneidad, exactitud, interoperabilidad, cumplimiento y seguridad. 4. Investigar según el estándar ISO 9126 que significa: madurez, tolerancia a fallas y facilidad de recuperación. 5. Investigar según el estándar ISO 9126 que significa: facilidad de comprensión, facilidad de aprendizaje y operabilidad. 6. Investigar según el estándar ISO 9126 que significa: comportamiento en el tiempo, comportamiento de los recursos. 7. Investigar según el estándar ISO 9126 que significa: facilidad de análisis, facilidad de cambio, estabilidad y facilidad de prueba. 8. Investigar según el estándar ISO 9126 que significa: adaptabilidad, facilidad para instalarse, cumplimiento, facilidad para reemplazarse. Es posible que algunos términos no estén definidos en la norma, en cuyo caso debe realizarse una investigación en otras fuentes sobre dichos atributos con el fin de dar una definición completa del mencionado y para cada todos los atributos que no tengan su definición en la norma. 34. LOS SISTEMAS DE CONTROL DE VERSIONES El siguiente trabajo pretende mostrar los avances en cuanto a los sistemas de control de versiones que son día por día uno de los temas más apasionantes dentro del enorme campo de la Ingeniería de Software, también se pretende dar unas pautas sobre las características globales de los CVS, además de analizar con algo de detalle las perspectivas a futuro que se tienen para con los CVS. Es importante notar que el presente artículo trata en lo máximo de hacer algunas comparaciones entre los sistemas amparados bajo licencia GNU y algunos propietarios para mostrar algunas de las características que ofrecen ellos para implementar sistemas de control de versiones. 34.1. LOS CVS Y EL PROCESO DE DESARROLLO UNIFICADO El proceso unificado de desarrollo está compuesto por fases e iteraciones. Una fase es un intervalo de tiempo entres dos hitos importantes del proceso durante la cual se cumple un conjunto bien definido de objetivos, se completan artefactos y se toman las decisiones sobre si pasar a la siguiente fase. Las cuatro fases del proceso unificado son: Iteración Elaboración Construcción Transición Dentro de cada fase hay varias iteraciones que algunos denominan flujos de trabajo y que son: Modelo del negocio: Describe la estructura y la dinámica de la organización Requisitos: Describe el método basado en casos de uso para extraer los requisitos Análisis y Diseño: Describe las diferentes vistas arquitectónicas Pruebas: Describe los casos de pruebas, los procedimientos y métricas para evaluación de defectos. Gestión de Configuraciones: Controla los cambios y mantiene la integridad de los artefactos de un proyecto Gestión del Proyecto: Describe varias estrategias de trabajo en un proceso iterativo Entorno. Cubre la infraestructura necesaria para desarrollar un sistema Dentro del marco teórico plasmado anteriormente vemos que la gestión de configuraciones cobra una especial importancia en el desarrollo de sistemas y obviamente como casi todas las cosas han sido plasmadas primero en forma teórica por expertos del área y luego algunas personas han tratado de dar soluciones reales en el área. Pues bien, la gestión de configuraciones es un área tratada durante años por la Ingeniería de Software, pero en los últimos años se ha incrementado su interés tanto que surgieron teorías al respecto. La cuestión es que dentro de la gestión de configuraciones un punto bien importante a tratar es la gestión de versiones cosa que hasta hace unos años se trataba solamente en forma teórica, pero afortunadamente en estos últimos cinco años se ha visto favorecida debido al surgimiento de sistemas que permiten a los desarrolladores de sistemas gestionar las versiones e incluso ir más allá y gestionar las subversiones. Obviamente los sistemas actuales que permiten la gestión de configuraciones son sistemas que tienen algunas limitaciones, pero que así mismo también brindan algunas facilidades y éste es precisamente el objetivo de este artículo, poder dar una idea mundial del estado en el que se encuentran dichos sistemas y poder hacer algunas predicciones de los posibles caminos que pueden tomar estos sistemas basándonos en las cuestiones que les hace falta mejorar a los sistemas actuales. También se pretenden sacar algunas conclusiones sobre lo que son y lo que no son los sistemas de gestión de configuraciones. Se han realizado algunos trabajos sobre el tema, pero han sido desarrollados en su mayoría por personas que están inclinadas tecnológicamente a utilizar una u otra tecnología, por ejemplo Microsoft ha publicado algunos trabajos para hablar sobre la gestión de configuraciones y específicamente sobre la gestión del control de versiones en proyectos de desarrollo de sistemas, pero inmediatamente después comienza hablando sobre las herramientas que ofrece para apoyar dicha gestión, esto obviamente se hace debido a que están inclinados por la utilización de dichas herramientas. En otros casos algunos fervientes amantes del software amparado por GNU muestran a los sistemas CVS de código abierto como los mejores, pero la verdad es bueno tener el objetivismos para hacer análisis medios en los que no se subestime una u otra tecnología. En este sentido el presente artículo espera ser de valiosa ayuda para todo aquel que quiera comprender el estado actual de los sistemas de control de versiones. 34.2. LA GESTION DE CONFIGURACIONES Y LOS CVS El tema de la gestión de configuraciones y específicamente la gestión de control de versiones tiene un ingrediente tecnológico que puede tratarse más o menos de forma objetiva, pero también tiene un ingrediente social, por cuanto surge como una necesidad inicialmente plasmada por la Ingeniería de Software y en este sentido se tiene mucha subjetividad, debido a que la Ingeniería de Software tiene muchos paradigmas y metodologías y dependiendo de la que se utilice se ve el desarrollo de sistemas de una u otra forma. Este trabajo por tanto aunque intenta ser lo más objetivo no garantiza en un ciento por ciento que sea una fiel copia de lo que es la realidad en el tema de la gestión de versiones de sistemas, pero a pesar de serlo intenta ser lo más cercano a lo que realmente se está viendo en las organizaciones sobre el tema. 34.3. CONTENIDO DE LA UNIDAD En esta unidad se pretende abordar los siguientes objetivos: Dar varios puntos de vista sobre los que son los CVS (Sistemas de control de versiones) Indagar sobre los tipos de sistemas de control de versiones Analizar el papel que cumplen los CVS dentro de la Ingeniería de Software Indagar sobre los desarrollos más importantes actualmente hechos por empresas desarrolladores de sistemas para ayudar a implementar CVS Observar las características que deben tener los buenos CVS y hacer algunas precisiones sobre el futuro que tienen estos sistemas en el desarrollo de sistemas a largo y mediano plazo. Precisas algunas conclusiones que no se encuentren en textos algunos, sino que sean el resultado de analizar lo que son los CVS y de su estado actual. 34.4. CONCRETANDO LO QUE ES UN CVS Como hemos visto hasta el momento los CVS son de gran importancia en la actualidad y es un soporte valioso que tiene ahora la Ingeniería de Software para seguir fundamentando teorías que muestran a estos sistemas como sistemas estratégicos e importantes para cualquier empresa que desarrollo sistemas. Comenzaremos dando una definición de los que se entiende por CVS y luego haremos un estudio detallado de los tipos y características de CVS, para concluir con unas prospectivas hacia el futuro y con unas conclusiones sobre los CVS. Definición: CVS es básicamente un sistema de control de versiones [Ref 1,I] y actualmente podemos decir que es uno de los temas de gran interés para la Ingeniería de Software, debido básicamente a que si es manejado adecuadamente dicho control permitirá a los desarrolladores llevar un control estricto de sus versiones y poder volver con total seguridad a una de ellas cuando se presenten problemas posteriores en el desarrollo del sistema. La técnica más común para la implantación de un sistema de versiones es trabajar en directorios de trabajo y solo personas con permisos especiales pueden hacer envíos a dichos repositorios [Ref 2]. 34.5. TIPOS DE SISTEMAS DE CONTROL DE VERSIONES I No solamente un CSV es esto, sino que tiene otras cosas como poder sacar instantáneas de cualquier momento de la historia a parte de manejar unas tecnologías complejas que son descritas con más detalle en [Ref 1] Lo más común en grandes empresas desarrolladoras de sistemas es que se cuente con un servidor dedicado únicamente al manejo de las versiones y dicho servidor maneja el repositorio antes mencionado. La administración de mencionado servidor se debe hacer por personal altamente calificado y debe ser configurado de acuerdo con el tipo de servidor de versiones que se quiera implementar. Por ejemplo podemos hablar de servidores de versiones concurrentes y servidores de versiones no concurrentes[Ref 2] y sin importar el tipo de servidor de versiones que se quiera montar se pueden establecer diferentes tipos de usuarios con respecto al servidor de versiones. Es así como encontramos usuarios administradores, usuarios anónimos e invitados[Ref 2,II] Existen variedad de formas para implementar sistemas de control de versiones [Ref 3] [Ref 4] [Ref 5], entre los que tenemos: Sistema de control de versiones “clásico” Modelo “optimista” de control de modificaciones concurrentes Clientes disponibles para muchas plataformas Modelo cliente-servidor (no “desde el principio”) Gestión conjunta de grupos de ficheros Sistemas complementarios pueden soportar acceso vía web 34.6. LOS CVS Y LA INGENIERÍA DE SOFTWARE Para comprender el papel del control de versiones dentro de la Ingeniería de Software es bien importante comenzar por recordar que el objetivo principal de la Ingeniería de Software es entregar un producto que satisfaga las necesidades del usuario, de forma eficiente y predecible[Ref Bib 1, pag 399] y se podría pensar que este principio se ha mantenido vigente durante los últimos quince años, pues desde entonces la Ingeniería de Software siempre ha perseguido este fin. De otra parte es interesante notar que la ingeniería de software ha basado el logro de este ideal utilizando dos metodologías principales: La metodología de proceso y la metodología de desarrollo, en donde hoy por hoy se tiene bastante difundida la metodología de proceso RUP, que traduce “Proceso unificado de desarrollo”III, lo interesante del asunto es ver que ésta metodología no solamente es compatible con una metodología de desarrollo, sino que lo es con muchas, lo que sucede es que los desarrolladores de éstas metodologías recomiendan que se implemente ésta metodología de proceso con una metodología de desarrollo orientada a objetos, y bueno, dado que las metodologías orientadas a objetos modernas usan a UML como su lenguaje base, no es raro comprender que incluso se documente el proceso con UML. [Ref Bib 3, pag 25]. En este punto es importante II En esta referencia encuentra también como configurar estos permisos para los diversos usuarios del servidor de control de versiones. III Sobre este proceso podemos encontrar bastante información en el libro [Ref Biblio 2] denominado “The Unified Software Development Process” aclarar que el proceso de desarrollo unificado es más que una metodología de desarrollo y como lo describen algunos autores: “Soporta las técnicas orientadas a objetos” [Ref Bib 1, pag 400]. Pues bien, el proceso unificado de desarrollo tiene unas fases que son: Iniciación Elaboración Construcción Transición y en cada una de estas fases se tienen unos flujos de trabajo del proceso que son: Modelado del negocio Requisitos análisis y diseño implementación Pruebas Despliegue Flujos de trabajo de soporte Gestión del Cambio y configuraciones Gestión del proyecto Entorno La pregunta que hasta ahora se ha hecho la Ingeniería de Software es: ¿Cómo hacer una verdadera gestión del cambio y configuraciones?. Para responder a éste pregunta se han establecido una serie de pasos a nivel metodológico y algunos de estos pasos se encuentran incluso dentro de metodologías como CMM cuando la incluyen en las primeras etapas para llevar a los equipos de desarrollo a niveles de calidad altos[Ref 12], pero lo interesante es que hasta hace muy poco se cuenta con herramientas computaciones que permitan el desarrollo de ésta tarea en forma efectiva, es entonces cuando surge CSV como un sistema que se puede implementar para el control de versiones y por supuesto las grandes empresas de software han ahondado en esfuerzos tendientes a dar soluciones al problema del control de versiones e incluso como se verá más adelante algunas no solamente se quedan en el problema de las versiones, sino que quieren detallar más el proceso y piensan en el problema de las subversiones. 34.7. SISTEMAS PARA GESTIONAR LOS CVS Existen muchos desarrollos tendientes a dar soluciones a implementaciones reales de CVS, uno de ellos es “aegis”[Ref 6], el cual pone especial énfasis en la seguridad del almacén y es por hoy una buena solución debido a que permite un acceso web a los administradores y usuarios del sistema. Este sistema podríamos decir que implementa la idea de “modelos de proyectos” (proyect templates) que no son más que plantillas sobre las que se consigna información sobre los diversos proyectos que son administrados por el CVS[IV] Existe un sistema que ha sido desarrollado para manejar versiones y subversiones y que ha tenido gran aceptación en el mundo y es “arch”[Ref 7], el cual tiene muchas posibilidades de distribución y es bastante ligero, incluso hay quienes lo consideran el mejor sistema para el manejo de versiones. De todas formas lo único cierto es que ha tenido gran aceptación mundial y un crecimiento grande del número de empresas y entidades que lo implementan. Existe un sistema llamado “Vesta”[Ref 8], el cual permite el control de versiones y adicionalmente está concebido con énfasis en el rendimiento y ha sido pensado para grandes sistemas, lo malo es que hasta el momento ha sido difícil de portar, por cuanto actualmente funciona solamente sobre LINUX. Para el caso de Microsoft tenemos que esta gran empresa de desarrollo de soluciones informáticas ha pensado en dar soluciones específicas para desarrolladores pequeños y para desarrolladores grandes. Para las empresas de desarrollo pequeñas y/o desarrolladores independientes la solución es “Visual Source Safe 2005” y para desarrollos complejos la solución está basada en “Visual Studio 2005 Team System: Enterprise Class Source Control and work Item Tracking”[Ref 9]. Entre las cosas más atractivas de las soluciones ofrecidas por Microsoft, podemos citar el hecho que dichas herramientas ofrecidas por esta empresa para el control de versiones cubren aspectos como el modelado, la documentación, las pruebas, la administración del software y en sí se podría decir que son herramientas que satisfacen las necesidades completas para la administración del ciclo de vida del software. 34.8. OTROS SISTEMAS QUE APOYAN A LOS CVS Algunos desarrollos de software han hecho que los CVS indirectamente cojan fuerza y sean día por día una realidad en la ingeniería de software. Tenemos por ejemplo muchas herramientas tipo “gnu”[IV] que ayudan a definir y catalogar cadenas de texto que van a ser usadas por los programas[V], otros que ayudan a automatizar la gestión de cambios de idioma[Ref 10,VI] IV Es importante notar que personas como el Dr Jesús M. González Barahona profesor de la Universidad de Juan Rey en España dicen que “aegis” tiene una funcionalidad similar a los CVS. Al doctor lo podemos encontrar en la dirección eletrónica: [email protected] [email protected] IV V Si quiere saber más sobre GNU puede entrar a la dirección electrónica: http://www.gnu.org Estos programas ayudan a catalogar programas y algunos autores lo denominan “catálogo de mensajes” VI Es importante notar que para automatizar la gestión de cambio de idioma se deben primero establecer reglas simples para especificar las traducciones que se deben hacer, 34.9. CARACTERISTICAS QUE DEBE TENER UN BUEN CONTROL DE VERSIONES Antes de mostrar algunas de las características más importantes que debe tener un buen control de versiones, es necesario pensar en algunas cuestiones preliminares que ayuden a comprender el tema y la importancia del control de versiones. Veamos: Cuando se habla de control de versiones, se piensa inmediatamente en el código fuente de las aplicaciones, pero es necesario comprender que el control de versiones no solamente debe abarcar éste aspecto sino que debe cubrir aspectos como los requisitos, los diagramas, la documentación. El establecer cuando se llega a una versión es algo importante y debe obedecer a políticas institucionales de desarrollo de versiones. Es importante pues en este sentido que no se establezcan versiones definitivas sin antes haber pasado dichos productos por otro tipo de versiones. En este sentido tenemos pues que un buen mecanismo para establecer versiones, es definir tipos de versiones como pueden ser: versiones alfa, versiones beta y versiones definitivas. Ahora bien, veamos entonces algunas de las características que debe tener un buen control de versiones: Un sistema de control de versiones debe primero que todo tener la posibilidad de darle al desarrollador la posibilidad de establecer el momento en el que desea indicarle al sistema que tiene una versión. Obviamente este momento tiene que estar acompañado de un almacenamiento confiable de toda la información del proyecto en el momento de tomar la decisión de establecer la fijación de una versión. De otra parte podemos pensar que de la anterior característica surge otra bien importante y que tiene que ver con la posibilidad que debe tener el desarrollador de sistemas de conocer cuales son las diferencias que se tienen entre lo que se tiene actualmente con la última versión, esto con el fin de saber si ya es el momento preciso para tener una nueva versión, o de si todavía los esfuerzos hechos no ameritan el lanzamiento de una nueva versión. Los sistemas de control de versiones deben ser sistemas que soporten varios programadores trabajando al mismo tiempo, algo similar a lo que pasaba cuando comenzaron los primeros entornos de desarrollo para trabajar en aplicaciones web. Recordemos por ejemplo lo que hizo Microsoft con su herramienta inicial “Microsoft Visual Interdev 6.0” en la que se trabajaban simultáneamente los conceptos de servidor tal como lo menciona el Dr Jesús M. González Barahona a quien le podemos escribir a la dirección: [email protected] [email protected] de producción (que procesaba las páginas), servidor maestro (que procesaba las copias principales) y servidor local (que se encontraba en una estación de trabajo y proporcionaba funcionalidades necesarias para probar todos los tipos de elementos web antes de extenderlos a la aplicación web maestra) [Ref Bib 4, pag 476]. Pues bien en los sistemas de control de versiones se mejoran estos conceptos y se permiten seguridades más grandes y controles no solamente a nivel de código fuente, sino a nivel de auditoría para saber en determinado momento que desarrollador hizo un cambio que dañó el desarrollo del sistema, para que sea almacenado por medio de registros recuperables que permitan con un gran alto grado de seguridad recuperar la versión con toda su funcionalidad. Los buenos sistemas de control de versiones deben permitir al equipo desarrollador recuperar versiones previas en el desarrollo del ciclo de vida del software que muestren no solamente las líneas que han cambiado, sino la documentación que ha sido agregada y/o eliminada, entendiendo por documentación los diagramas, los diccionarios, la documentación del código fuente, tal como por ejemplo lo implementa Visual Source Safe [Ref 13] Los sistemas de control de versiones deben tener capacidades de compartir y enlazar archivos de desarrollo para promover la reutilización de código y componentes entre proyectos y simplificarel mantenimiento de código al preparar los cambios entre todos los archivos compartidos y enlazados cuando un archivo sea actualizado, lo cual por ejemplo es algo que también implementa Visual Source Save[Ref 13] Las características de desarrollo en parelelo, como el "branching", permite que los equipos separen el proceso de desarrollo en proyectos y archivos paralelos, creando copias idénticas que heredan toda la documentación de versiones pero que se les puede dar seguimiento como proyectos nuevos e individuales[Ref 13]. Esto obviamente debe estar soportado por una alta tecnología que permita reconciliar diferencias entre diferentes versiones del mismo archivo y permita ver como se comportaría una determinada versión al ser incluida dentro del proyecto, pero todo esto bajo la premisa de evitar al máximo la pérdida potencial de cambios valiosos. Al igual que con los usuarios de cualquier otro sistema, los sistemas de control de versiones deben permitir manejar niveles de usuarios aunque globalmente todos sean desarrolladores de software y de sistemas es bueno que el sistema de control de versiones permita la gestión de usuarios en el equipo de desarrollo basado en políticas de seguridad y niveles de permisos [Ref 3] [Ref 4]. 34.10. EL FUTURO DE LOS CVS Como sucede con casi todas las cosas del mundo, los desarrollos tecnológicos también están en constante cambio y evolución, pues bien, los CVS que fueron concebidos para manejar versiones pueden llegar a ser desplazados por los sistemas que manejan subversiones, los cuales a parte de ser netamente web permiten gestionar directorios renombrados y tienen algoritmos bastante eficientes para hacer búsquedas y para gestionar subversiones[Ref 11]. 34.11. CONCLUSIONES SOBRE LOS CVS Es importante notar que los CVS han evolucionado a sistemas que permiten un alto grado de confiabilidad para la gestión de versiones en el ciclo de vida de sistemas y se enfoca principalmente en permitir el trabajo de múltiples usuarios que físicamente se pueden encontrar en cualquier parte del mundo. Podemos decir entonces que aunque los CVS que existen actualmente funcionan preferencialmente en entornos LAN, también soportan WAN y tienden a soportar ésta última de forma robusta cada vez más. Se puede ver claramente que de todas formas existe algo de responsabilidad grande delegada al administrador del CVS, debido a que de los permisos que éste conceda a los usuarios y de la buena gestión que haga del sistema dependerá en buena medida el éxito del manejo de versiones en un proyecto de desarrollo. Esto obviamente tiene una limitación y es que el administrador de control de versiones debe ser una persona con alto grado de conocimientos de programación y buena responsabilidad del control de versiones recae sobre el mismo. Cuando surgen problemas en el desarrollo del sistema y se toma la decisión de volver a una versión previamente almacenada se puede fácilmente volver con las herramientas actuales, pero si por desgracia se quiere volver a un tiempo en el ciclo de desarrollo del sistema que no halla sido previamente almacenado y establecido en el sistema, se tienen actualmente muchas limitaciones en todos los sistemas CVS actuales. También podemos decir que aunque los CVS actuales permiten combinar archivos diferentes que correspondan a versiones diferentes, existe todavía un alto grado de posibilidad que al hacerlo un archivo pueda estropear indirectamente otras cosas, pero que no sea tan evidente. En estos casos, decimos que para reconciliar de una mejor manera los problemas al mezclar archivos se deben hacer simulaciones de cómo sería la integración del sistema, pero dichas simulaciones todavía no son posibles con los CVS actuales. Otra cuestión bien relacionada con la conclusión anterior es que al combinar diversas versiones se toman decisiones basadas en la experiencia, el buen conocimiento de programación y otras cuestiones que de ninguna manera pueden ser reemplazadas por sistemas actuales. Decimos entonces que técnicas como la inteligencia artificial todavía no se han integrado de forma plena a los CVS actuales. Podemos pensar que los actuales CVS están diseñados para gestionar versiones de desarrollo de software en lenguajes específicos, por ejemplo los sistemas creados por Microsoft, son para ser utilizados en equipos de desarrollo que usen herramientas de Microsoft, de la misma forma otros sistemas en software amparado por GNU siguen siendo específicos para ciertos lenguajes de programación y esto obviamente lleva a pensar que estamos muy lejos de construir sistemas de control de versiones que soporten desarrollos de sistemas basados en múltiples lenguajes. 34.12. BIBLIOGRAFIA DE LA UNIDAD [Ref Bib 1] Nombre: Autor(es): Editorial: Año: El Lengueje Unificado de Modelado Grady Booch, James Rumbaugh, Ivar Jacobson Addison Wesley 1999 [Ref Bib 2] Nombre: Autor(es): Editorial: Año: El Lengueje Unificado de Modelado Grady Booch, James Rumbaugh, Ivar Jacobson Addison Wesley 2002 [Ref Bib 3] Nombre: Autor(es): Editorial: Año: The Unified Software Development Process Grady Booch, James Rumbaugh, Ivar Jacobson Addison Wesley Object Technology Series 2003 [Ref Bib 4] Nombre: Autor(es): Editorial: Año: Microsoft Visual Interdev 6.0 Manual del programador Microsort Press Mc Graw Hill 1999 34.13. INFOGRAFIA DE LA UNIDAD [Ref 1] Dirección: Copias: Fecha: http://gsyc.escet.urjc.es/pub/actividades/linuxprog/prog-html.tar.gz http://gsyc.escet.urjc.es/pub/actividades/linuxprog/prog-dvi.tar.gz http://gsyc.escet.urjc.es/pub/actividades/linuxprog/prog.ps.gz 31 de Mayo de 2001 [Ref 2] Dirección: Fecha: http://qref.sourceforge.net/Debian/reference/reference.es.html#contents 14 de Enero de 2005 [Ref 3] Dirección: Fecha: http://www.cvshome.org 30 de Octubre de 2003 [Ref 4] Dirección: Fecha: http://www.gnu.org/software/cvs/cvs.html 27 de septiembre de 2004 [Ref 5] Dirección: Fecha: http://cvsbook.red-bean.com 3 de Enero de 2005 [Ref 6] Dirección: Fecha: [Ref 7] Dirección: Fecha: [Ref 8] Dirección: Fecha: [Ref 9] Dirección: http://aegis.sourceforge.net/index.html 13 de Agosto de 2005 http://regexps.com/arch.html 14 de enero de 2005 http://www.vestasys.org 17 de diciembre de 2005 Fecha: http://msdn.microsoft.com/library/default.asp?url=/library/enus/dnvsent/html/vsts-arch.asp 5 de Febrero de 2005 [Ref 10] Dirección: Fecha: http://www.gnu.org/software/gettext/gettext.html 10 de septiembre de 2004 [Ref 11] Dirección: Fecha: http://subversion.tigris.org 17 de diciembre de 2005 [Ref 12] Dirección: Fecha: http://www.acis.org.co/index.php?id=108 18 de octubre de 2005 [Ref 13] Dirección: Fecha: http://www.microsoft.com/latam/ssafe/producto/resumen.asp 29 de diciembre de 2004 35. ARQUITECTURA CENTRADA EN MODELOS 35.1. INTRODUCCIÓN A MDA MDA es actualmente una corriente muy importante en el desarrollo del software que promete proporcionar mayor reusabilidad, interoperabilidad entre sistemas y menor tiempo de desarrollo. 35.2. PALABRAS CLAVE Métodos MDA, MDD, enfoque al desarrollo de software, MDA, Lenguajes para aplicar MDD, UML, MOF, CMW y QVT 35.3. INTRODUCCION A MDA El siguiente trabajo intenta dar una vistazo rápido a lo que es MDA, diciendo que tiene que ver con los enfoques de desarrollo, diferenciando entre MDD y MDA, explicando que trae de nuevo con respecto al modelamiento que se viene trabajando hace un tiempo e incluso a los esfuerzos de unificación de modelamiento que se viene trabajando desde el lanzamiento de la primera versión de UML. Se intenta explicar lo que se podría hacer con los modelos, si realmente deberían existir tipos de modelos y si existen cuáles tipos de modelos se trabajan con MDA. Se explican lo que son las transformaciones y qué lenguajes utilizará MDA. Por último se muestra un cuadro resumen con las semejanzas y diferencias de opiniones de los autores más representativos de este tema en el mundo y finaliza el trabajo con unas conclusiones. 35.4. ¿MDA UN ENFOQUE DE DESARROLLO O ESTANDAR DE DESARROLLO? Algunos autores sostienen que MDA es un enfoque de desarrollo 3 (o bueno aunque no lo digan explícitamente es como si lo dijeran) otros en cambio lo tratan como una gran 3 Atkinson lo trata como un modelo MDD es decir que lo trata como un desarrollo dirigido por modelos filosofía de desarrollo 4 , de todas formas, sea como sea, son muchos los autores modernos que tratan esta nueva forma de desarrollo como algo que promete grandes ventajas al desarrollar software con gran cantidad de complejidad. Atkinson incluso habla de MDD como una infraestructura de desarrollo dirigido por modelos que permitirá definir: Conceptos disponibles para crear modelos La notación para usar los modelos Conceptos que facilitarán dinámicamente al usuario extender sus modelos conceptuales y notaciones para que sean correctamente capturadas por los desarrolladores. 35.5. ¿MDD O MDA? La verdad, podríamos pensar que lo mejor es hablar de MDD, debido a que se trata básicamente es de desarrollar modelos y que el desarrollo verdaderamente esté dirigido por dichos modelos. La idea es que dichos modelos sean tan potentes que incluso se puedan construir con ellos metamodelos, también se pretende que los modelos al ser llevados a código sen maleables con una sintaxis correcta y siguiendo una serie de transformaciones definidas.[1] 35.6. ¿ACASO NO TRABAJAMOS CON MODELOS DESDE HACE MUCHO TIEMPO? Una buena parte de los ingenieros y en general de los profesionales en tecnologías de la información que escuchamos por primera hablar de este tema, nos hemos hecho alguna vez ésta pregunta, pero la verdad es que después de estudiar más a fondo la cuestión podemos incluso a llegar a concluir que sigue siendo otro modelo más, o de pronto pensemos que es una filosofía novedosa, pero para ello, vamos a plasmar el pensamiento de uno de los grandes en este campo como es “Mellor”, quien afirma que el estándar OMG es un estándar de modelamiento que no ha podido ser completamente maleable hasta código debido a la carencia de otros modelos[2]. También afirma que si se permite la creación de otros modelos que ayuden a especificar el sistema la documentación en términos de modelos estaría completa. En pocas palabras se podría decir que “Mellor” abre la posibilidad a otras técnicas de MDD. De otra parte Bichler dice que el objetivo de MDA es definir un estándar que permita el desarrollo de software basado en modelos[3 ]. Volvemos pues a la pregunta que estamos haciendo: ¿No es acaso eso lo que se ha venido haciendo desde hace algún tiempo?. Sigamos escuchando entonces a Bichler quien además menciona que cada fase del proceso de desarrollo de software genera información adicional la cual necesita ser adicionada al 4 Bichler lo trata como una estandarización MDD que hace un gran aporte al MDA brindando los estándares para el MDA modelo por medio de unas transformaciones. La idea para Bichler es que éstas transformaciones estén soportadas por unas herramientas en forma ordenada de tal forma que se facilite la gestión del desarrollo del proceso de software y se pueda incrementar fácilmente el número de transformaciones debido a que esto se haría por medio de dichas herramientas. Analizando las frases anteriores podemos afirmar que Bichler se da cuenta que el software sufre ciertas modificaciones en el proceso y que pueden surgir cosas nuevas que deban tenerse en cuenta, pero no como producto de un mal diseño, sino como producto de la naturaleza misma del proceso de desarrollo el cual tiende a aumentar cosas que es necesario añadir al sistema para mejorar la documentación. Es pues en ésta parte dónde se podría decir que hasta ahora no se ha trabajado y que por tanto según Bichler MDA promete ser la compañera ideal para todos los profesionales de la informática. 35.7. REALMENTE: ¿QUÉ ES LO NUEVO? La verdad en esta parte, las discusiones son fuertes, por cuanto algunos autores consideran que lo más importante es que aporta lenguajes estándar, en tanto que otros consideran que estandariza MDD Lo único cierto es que la gran mayoría coincide en que aporta lenguajes estándar y estandariza a MDD, los autores que no se ponen en éste pedacito la verdad a veces ni son claros. De otra manera es importante notar que las aportaciones hechas a MDD, son básicamente dos: Los modelos son el artefacto principal Las transformaciones entre modelos son la clave. Dicho en otras palabras, aunque actualmente se viene modelando sistemas en forma gráfica, es importante notar que esto no era lo trascendental cuando se desarrollaba el software, cosa que ahora con MDA sí va a ser y explícitamente lo será. De la misma manera decimos que las transformaciones hasta ahora de han hecho de cualquier forma, pero la verdad no existía una directriz seria que dijera que ésta parte era realmente importante y esto tal vez dio lugar a la salida en falso de muchas herramientas de software que intentaban automatizar de cualquier manera y por falta de esta directriz, en muchos casos lo hacían mal. Ahora con MDA, esta parte cobra importancia y los desarrolladores pueden contar con la certeza que se están haciendo esfuerzos con MDA para que las transformaciones sean y sigan siendo la clave. Por fin! 35.8. ¿TODO CON MODELAMIENTO NO ES ACASO UNA UTOPIA? Aunque a veces a muchas personas les parezca una utopía, existen personas célebres de la Ingeniería de Software que el primer paso necesario para lograr esta utopía es comenzar por MDD, de tal suerte que al mejorarlo y pulirlo se logre la gran hazaña “que los programas sean generados automáticamente por sus correspondientes modelos” Es más Selic dice en una parte de su libro que es imprescindible la generación automática de código a partir de los modelos[4]. Vemos pues que la idea que tiene Selic de MDA es una idea bien interesante y es muy posible que con los avances que se están teniendo cada día en software, se logre cumplir con éste objetivo. 35.9. ¿QUÉ SE PODRÍA HACER CON LOS MODELOS? Tradicionalmente con los modelos de software se documentan programas, pero existen personas que son enfáticas en decir que MDA no es otro modelo más para incorporar a la documentación de nuestros sistemas de software, sino que son modelos por medio de los cuales se capturan requisitos, diseño, implementación y esto abre entonces una clara idea de lo que se persigue con MDA y es que verdaderamente se capture todo por medio de modelos[5]. Esto obviamente va de la mano con el pensamiento de Selic, quien como decíamos anteriormente decía que se pretendía que la generación del software y del código se hiciera de forma automática a partir de sus modelos y esto obviamente se lograría entre otras cosas si los modelos están presentes en todas etapas del desarrollo de software. Existe un autor llamado “Gardner” quien afirma entro otras cosas que si los modelos son la base fundamental del desarrollo de software, es muy posible que cuando se genere código a partir de dichos modelos se tenga una información previa sobre las generaciones anteriores de código y esto haga que en algunos casos no se genere toda la aplicación, sino únicamente la parte que ha cambiado[8] El anterior pensamiento si se analiza con mucho cuidado es también bastante interesante, por cuanto menciona la posibilidad de incorporar modelos como una guía para compilar y ensamblar 35.10. LOS MODELOS DEBEN SER: ¿DEPENDIENTES O INDEPENDIENTES DE LA PLATAFORMA? Ësta pregunta entre otras es más o menos descrita por “Czarnecki”, quien define a MDA como una iniciativa del grupo OMG para definir un entorno apropiado de desarrollo de software basado en modelamiento y que permita el mapeo del modelo a la implementación Menciona que los patrones básicos de MDA definen un modelo independiente de la plataforma (PIM) y estos son automáticamente mapeados a un modelo para una o más plataformas específicas (PSMs)[6]. Podemos ver entonces que la respuesta a la pregunta de si los modelos deben ser dependientes o independientes de la plataforma es bien clara en el sentido que se dice que existen unos modelos que deben ser lo suficientemente globales para ser aplicables a cualquier plataforma, pero que deben poderse generar a partir de ellos otros modelos que sean específicos de las diversas plataformas. Esto nos da la idea de colocar un framework o una capa intermedia para lograr convertir un modelo general en otro específico y por lo tanto debe darnos una clara idea de la complejidad que un desarrollo de este tipo invlucraría. Podríamos pensar que es algo similar a lo que tiene java, el cual coloca por ejemplo una máquina virtual como capa intermedia para lograr que sus sistemas corran en múltiples plataformas 35.11. ¿QUÉ SON LOS MODELOS DEPENDIENTES DEL SISTEMA? El autor “Varro”, habla a cerca de dichos modelos e incluso dice que dichos modelos describen la arquitectura específica del software[7]. Al igual que “Czarnecki” “Varro” habla a cerca de los modelos dependientes y los modelos dependientes del sistema, con lo cual podemos asegurar que efectivamente MDA se basa en un desarrollo completamente orientado por modelos y para ello, existen modelos que sean independientes del sistema y modelos que sean dependientes del sistema, pero que pueden ser fácilmente generados a partir de modelos independientes. 35.12. ¿SE DEBEN AUTOMATIZAR LAS TRANSFORMACIONES? “Weis” dice que usando MDA los desarrolladores pueden crear específicas que a su vez son generadas de plataformas independientes del modelo del sistema. Lo interesante de este autor es que comparte la idea de otros en cuanto a que la última fase de codificación se debe hacer en forma automática y es entonces cuando escribe toda una teoría sobre como se deberían automatizar las transformaciones para convertir tanto el modelo independiente a un modelo dijéramos de más bajo nivel dependiente y cómo convertir éste último en código[9]. 35.13. ¿QUÉ LENGUAJES USARÁ MDA? Es importante notar que según la concepción global que se tiene actualmente de MDA, se concibe a MDA como en concenso (teniendo en cuenta la opinión de la gran mayoría de autores, aunque no todos lo tratan como un método) como un método que usa los lenguajes de OML. Entre los lenguajes de OML que puede usar MDA, tenemos los siguientes: UML MOF CMW QVT 35.14. ¿QUÉ INTERPRETACIONES HAY DE MDA? En realidad son muchos los textos que hablan de MDA como una plataforma y desde este punto de vista uno pensaría que todos están de acuerdo en muchas cosas, pero la verdad si se examina la cuestión más a fondo, se logra percibir que las interpretaciones que se tienen sobre plataforma son diferentes de un autor a otro. A continuación se muestran tres interpretaciones de plataforma que se manejan en MDA: Interpretación de tecnología concreta. En este punto se dice que MDA es acorde con el concepto de plataforma, en donde este concepto se refiere a tecnologías como las conocen los ingenieros de sistemas, ejemplo EJB, NET, etc. Otros autores hablan de plataforma en el sentido abstracto y dicen tecnología orientación a objetos y por supuesto esto no es una tecnología específica, sino muy abstracta que abarca otras tecnologías y finalmente otros hablan de generador de implementacion como plataforma y en este punto tenemos el caso de los señores: “Varro” y “Weis” 35.15. CONCLUSIONES SOBRE MDA Aunque suene un poco atrevido en esta parte de las conclusiones tomaré el gran atrevimiento de citar un cuadro a cerca de las posiciones de los autores, veamos pues: Atkinson Mellor Naturaleza de MDA MDD Selic Agrawal Gardner Transform. Estandarizar MDD Transformación de modelos Transf. de modelos/ Modelos de Diseño/Impl. No automático Automáticas Aproximación al desarrollo de SW Automáticas Transf. de modelos Automáticas Varró Weis Plataforma Estándares para MDD Bichler Czarnecki Aportación MDA Automáticas Arquitectura del Sistema Tecnologías de Impl. Bueno y ahora sí el aporte: Podríamos pensar que la mayoría de autores coinciden en afirmar que ésta nueva forma de concebir el desarrollo de sistemas es adecuada para los desarrollos que le esperan en estos tiempos a la humanidad en cuanto a software se trata. De otra parte es bueno anotar que aunque existe alguna diferencia leve entre la concepción que se tiene de MDA, si algunos la consideran un estándar para MDD, otros como Atkinson la consideran como de naturaleza puramente MDD, tenemos que éste tipo de diferencias entre los autores no los alejan sustancialmente de las potencialidades que todos le encuentran a esta forma de ver el mundo del desarrollo de software. En pocas palabras todos ven a MDA como algo positivo en cuanto al desarrollo de software se trata. Es bueno tener en cuenta que la mayoría de autores no hablan sobre la plataforma del sistema tal vez por que no quieren involucrarse a describir lo que todos creemos que es una panacea o mejor dicho una utopía, pero a pesar que son pocos los que hablan de la arquitectura del sistema, se podría decir que ninguno está en desacuerdo con ésta aproximación. Otro punto importante a tener en cuenta es que las transformaciones que se pretenden hacer para generar modelos más completos a partir de modelos la conciben en forma automática los diversos autores en su gran mayoría, aunque en sí, el concepto de transformaciones difiera de un autor a otro. Por ejemplo para unos automática sería que a partir del modelo se generase el código fuente, en tanto que para otro la palabra automática sería que a partir de un modelo y su correpondiente implementación, se genere información que sea necesaria describir del nuevo software que sea necesaria añadir al modelo inicial después de hacer algunas trasformaciones. En pocas palabras, todos hablan de transformaciones, pero el concepto es distinto, por lo que la comparación sobre el concepto de automatismo en las transformaciones no aplica mucho. Un aspecto interesante es la siguiente conclusión: No es imprescindible automatizar las transformaciones para seguir el estándar MDA, pero en cambio Sí es necesario automatizar las transformaciones para que MDD sea útil Finalmente se podría pensar que tal cual como está escrita la guía MDA, se da para muchas malas interpretaciones y esto obviamente dificulta muchas cosas, pero lo único cierto es que ofrece y promete muchas ventajas que muchos desarrolladores creen que se conseguirán. 35.16. BIBLIOGRAFIA SOBRE MDA [1] Colin Atkinson and Thomas K¨uhne. Model-Driven Development: A Metamodeling Foundation. IEEE Software, 20(5):46–51, September/October 2003. [2]Mellor, S.J. and Clark, A.N. and Futagami, T. Model-driven development – Guest editor’s introduction. IEEE Software, 20(5):14– 18, Sept.-Oct. 2003. [3]Lutz Bichler. A flexible code generator for MOF-based modeling languages. In 2nd OOPSLA Workshop on Generative Techniques in the context of Model Driven Architecture, 2003. [4]Bran Selic. The Pragmatics of Model-Driven Development. IEEE Software, 20(5):46– 51, September/October 2003. [5]Aditya Agrawal and Tihamer Levendovszky and Jon Sprinkle and Feng Shi and Gabor Karsai. Generative Programming via Graph Transformations in the Model-Driven Architecture. In Workshop on Generative Techniques in the Context of Model Driven Architecture, 2002. [6]Krzysztof Czarnecki and Simon Helsen. Classification of model transformation approaches. In 2nd OOPSLA Workshop on Generative Techniques in the Context of the Model Driven Architecture, 2003. [7]Daniel Varró and András Pataricza. UML Action Semantics for Model Transformation Systems. Periodica Politechnica, 2003. [8]T. Gardner and C. Grin and J. Koehler and R. Hauser. A review of OMG MOF 2.0 Query / Views / Transformations Submissions and Recommendations towards the final Standard,. In MetaModelling for MDA Workshop, 2003. [9]Torben Weis and Andreas Ulbrich and Kurt Geihs. Model Metamorphosis. IEEE Software, 20(5):46–51, September/October 2003. 36. BIBLIOGRAFIA 36.1. BIBLIOGRAFIA SOBRE PROCESOS DE DESARROLLO Y RUP Ivar Jacobson, Grady Booch e James Rumbaugh. The Unified Software Development Process. Capítulos 1 a 5. Philippe Kruchten. The Rational Unified Process – an Introduction. Pressman Roger. Ingeniería del Software. Quinta edición. Editorial Mc Graw Hill. 2002. Booch, G. Rumbaugh, J. Jacobson, I. El Proceso Unificado de Desarrollo de Software. Editorial Addison Wesley. 2000 Bruegge, Bern. Dutoit, Allen. Ingeniería de Software Orientada a Objetos. Editorial Prentice Hall. 2000. Fraude, Eric. Ingeniería de Software una perspectiva orientada a objetos. Editorial Alafaomega. 2003. Sommerville, Ian. Ingeniería de Software. Editorial Pearson Education. Sexta edición. 2002. Amescua, Antonio. Cuadrado, Juan Jose. Ernica, Emilio. García, Javier. García, Luis. Martinez, Paloma. Análisis y diseño estructurado y orientado a objetos de sistemas informáticos. Editorial Mc Graw-Hill. 2003. 36.2. BIBLIOGRAFIA SOBRE MODELAMIENTO CON UML Booch, G. Rumbaugh, J. Jacobson, I. El lenguaje unificado de modelado. Editorial Addison Wesley. 1999. Sintes, Anthony. Programación Orientada a Objetos. Editorial Prentice Hall. 2002. Modelado y Diseno orientado a objetos. Metodologia OMT. James Rumbaught, Michael Blaha, William Premerlani, Frederick Eddy y William Lorensen. Editorial Prentice Hall. 1995. (Este libro no habla de UML, pero muchas de estas cosas las tomo UML) 36.3. BIBLIOGRAFIA SOBRE IMPLEMENTACIONES CON UML UML para programadores Java, Rober C. Martin. Pearson Prentice Hall. 2004 37. ANEXO 1: CORRECCIONES HECHAS A PROYECTOS DE GRADO 37.1. ALGUNAS CORRECCIONES PASADAS A ALGUNOS PROYECTOS DE GRADO: CARTA 1 Bogotá 19 de Mayo de 2008 Ingeniero MSc. CARLOS ALBERTO VANEGAS Coordinador Proyecto Curricular Sistematización de Datos e Ingeniería Telemática Universidad Distrital F.J.C. Ciudad Respetado Ingeniero: Me permito hacerle entrega formal de las correcciones que a mi juicio y en calidad de evaluador asignado creo pertinentes para el proyecto de grado titulado ”DISEÑO E IMPLEMENTACIÓN DE UN PROTOTIPO DE CLUSTER DE BALANCEO DE CARGA PARA LOS PROYECTOS DE SOFTWARE DEL GRUPO DE INVESTIGACIÓN METIS”, realizado por los estudiantes “DANIEL ARTURO BOJACA VANEGAS” y “JOHAN FERNANDO CAMACHO GOMEZ”, quienes aspiran al titulo de “INGENIERO EN REDES DE COMPUTADORES” en calidad de monografía. PUNTO ANALIZADO Una grilla tiene algunos servicios básicos como son, autenticación de procesos, proceso de autorización, comunicación de procesos, control de procesos y la forma como la grilla va a adquirir los recursos. CORRECCION SUGERIDA Detallar en el documento como estos servicios se prestan en el desarrollo hecho por los estudiantes. Cordialmente, LUIS FELIPE WANUMEN SILVA Docente Sistematización de Datos e Ingeniería Telemática Evaluador asignado 37.2. ALGUNAS CORRECCIONES PASADAS A ALGUNOS PROYECTOS DE GRADO: CARTA 2 Bogotá 19 de Mayo de 2008 Ingeniero MSc. CARLOS ALBERTO VANEGAS Coordinador Proyecto Curricular Sistematización de Datos e Ingeniería Telemática Universidad Distrital F.J.C. Ciudad Respetado Ingeniero: Me permito hacerle entrega formal de las correcciones que a mi juicio y en calidad de evaluador asignado creo pertinentes para el proyecto de grado titulado ”SISTEMA DE INFORMACIÓN Y CONTROL PARA EL COBRO COACTIVO Y PERSUASIVO DEL FONDO DE PRESTACIONES ECONOMICAS, CESANTIAS Y PENSIONES - FONCEP”, realizado por los estudiantes “JHONATTAN ALEXANDER SUATERNA ALVARADO” y “JOHN EDISON MORENO MARIN”, quienes aspiran al titulo de “TECNÓLOGO EN SISTEMATIZACIÓN DE DATOS” en calidad de pasantía. PUNTO ANALIZADO En la pagina 62 se habla de Delphi y el proyecto no fue desarrollado con esta herramienta. La metodología ORACLE METHOD usa métodos, herramientas y técnicas que son: PUNTO Elemento Métodos Método Case Herramientas Herramientas de desarrollo de aplicaciones. Herramientas Case Técnicas Módulo Entidad Relación Diseño de Bases de Datos Modelo Funcional Diagrama de Flujo de Datos Una Serie de matrices para llegar al modelo Entidad Relación. Al parecer se usa la metodología ANCORA para el análisis de requisitos. Así conforme para la metodología RUP lo mas importante son los requerimientos, para ORACLE METHOD se da especial énfasis en que el desarrollo del sistema de información sea lo más estratégico posible CORRECCION SUGERIDA En general hablar en el marco teórico y en todo lado del documento solamente de las cosas que fueron usadas en el proyecto de grado o que sirvieron de base para el mismo. Mostrar cada uno de estos puntos más claramente en el documento. Mostrar en el documento cuales son los guiones que se establecieron ya que los guiones son una parte fundamental en la metodología ANCORA para el establecimiento de requisitos. Darle al documento este énfasis si se usa la metodología de Oracle y usar en la medida de lo posible las y esto lo logra mediante la aplicación de herramientas de Oracle para diagramación y generación de reportes. Observo total viabilidad para la aceptación del proyecto una vez se hagan las correcciones que son en su mayoría de forma y no de fondo sobre la forma como se desarrollo físicamente el sistema. Cordialmente, LUIS FELIPE WANUMEN SILVA Docente Sistematización de Datos e Ingeniería Telemática Evaluador asignado 38. ANEXO 2: COSAS HA TENER EN CUENTA EN LOS PROYECTOS DE GRADO Todo proyecto de grado bien sea para optar a ser profesional en cualquiera de las carreras relacionadas con las tecnologías de la información debe tener como mínimo las siguientes características: Si es pasantía puede usar las tecnologías que use la empresa, es más, aunque hay empresas que dan la posibilidad para que el pasante elija las tecnologías que va ha usar, teniendo casi siempre como parámetro que sea una tecnología de software no propietario y de libre distribución. Para el caso de las monografías recomiendo que se usen tecnologías robustas, es decir que brinden alto escalamiento y gran capacidad de almacenamiento. En la parte del modelamiento recomiendo que se usen metodologías robustas como RUP, Métrica 3 que son ampliamente aceptadas por la comunidad científica. Dado que las monografías tienen un carácter más científico que las pasantías aconsejo que busque metodologías que estén avaladas por grandes grupos de investigación y por comunidades de investigación. A pesar de las anteriores consideraciones creo oportuno mencionar las características que deben tener los proyectos dependiendo del tipo de aplicaciones que se estén desarrollando. 38.1 SI EL PROYECTO QUE SE VA A REALIZAR ES SOBRE APLICACIONES MOVILES Y ES DE TECNOLOGÍA EN SISTEMATIZACIÓN DE DATOS. Debe aplicar mínimo cuatro capas en su desarrollo, puesto que creo que aplicar tres es cosa demasiado sencilla que no tiene mucho trabajo, puesto que la tecnología obliga a que tenga uno que hacerlo. Cuando hablo de cuatro capas, estoy hablando de hacer la capa en el lado del cliente, no se dejar que las tecnologías existentes en el móvil actúen de capa del cliente cosa que es muy sencilla. Se deben usar patrones arquitectónicos de software y creo que se deberían mínimo usar tres o cuatro patrones para el desarrollo de aplicaciones. Se deben usar estándares de programación y es bueno que el estudiante indague sobre los principales estándares de programación. Se debe usar lenguajes robustos. Se debe hacer un modelamiento totalmente acorde con la implementación. Se deben usar frameworks en el lado de las aplicaciones de servidor que permitan que el desarrollo tenga unos ciertos patrones, mínimo se debe usar struts o Jface, aunque en lo personal aconsejo usar este último. En el lado de la aplicación del cliente aconsejo usar tecnologías de presentación como AJAX y usarlo de la mejor forma. Se deben usar interacciones con servidores y no simplemente limitarse a realizar aplicaciones en el movil que no se comuniquen con servidores de algun tipo. 38.2. SI EL PROYECTO QUE SE VA A REALIZAR ES SOBRE APLICACIONES MOVILES Y ES DE INGENIERÍA EN REDES DE COMPUTADORES O INGENIERÍA EN TELEMÁTICA. No debe limitarse únicamente a realizar conexiones a servidores Web vía wap, sin manipular con un nivel profundo dicho protocolo. No deben usar únicamente los micro navegadores y el lenguaje WML o XHTML, dado que de esta forma no hay que hacer nada en el lado del cliente y esto se queda para proyectos de tecnología, aunque siendo sinceros este tipo de proyecto con WML, creo que se deberían dejar únicamente para las pasantías donde se obligue a usar este tipo de cosas, debido a que esto no tiene mucha ciencia. 38.3. SI VAS A REALIZAR UN PROYECTO SOBRE APLICACIONES CON AGENTES MOVILES REQUIERES Si vas a trabajar aplicaciones móviles con Java, se requiere estudiar el J2ME. Es bueno comprender los aspectos básicos de J2SE, debido a que la forma de programar en J2ME es la misma. Se requiere un compilador para compilar los fuentes y en el caso de aplicaciones móviles con java tenemos el compilador CLDC (1.0, 1.1) y al menos un perfil (MIDP, PDAP), ambos disponibles en www.java.sun.com Existen Herramientas de desarrollo que incluyen estos compiladores y una de ellas es el Wireless Toolkit 2.5.1. for CLDC. Otra herramienta es Nokia Developer Suite for J2ME el cual se puede descargar de www.nokia.com Otra herramienta es Motorola SDK for J2ME que no tiene incluido e J2SDK y se puede bajar de http://developer.motorola.com Otro entorno de desarrollo es Code Warrior de Motorota que se puede conseguir en http://codewarrior-development-studio.softonic.com/movil Otro entorno es el Sun ONE Studio disponible también en www.java.sun.com También se requieren entornos de desarrollo, aunque puede usar simplemente el bloc de notas para programar y compilar todo en el emulador. Hay un buen emulador de aplicaciones móviles que también sirve de entorno de desarrollo, es decir tienes todo en uno y esto se logra con el NetBeans claro que bajándole el MobilityPack. Para comenzar en el desarrollo de aplicaciones móviles es bueno visitar las siguientes direcciones: http://www.mygnet.net/manuales/j2me/ http://www.culturamovil.com/ Los entornos se pueden bajar de: http://www.eclipse.org/downloads/ http://www.netbeans.org/ Después de hecho este trabajo se puede proceder a comprender como comunicar aplicaciones móviles, por ejemplo usando bluetooth o alguna otra tecnología de comunicaciones. También se podría pensar en usar servicios Web para comunicar agentes por medio de un servidor de servicios Web. Si este es el caso se requiere instalar en las aplicaciones móviles el API “KSOAP” que es un API que permite a los dispositivos móviles que tengan aplicaciones Java acceder a servidores de servicios Web. Después es bueno aprender sobre algunos estándares para comunicación entre aplicaciones, lenguajes y protocolos de intercambio para aplicaciones. Por ejemplo algunos lenguajes procedimentales para comunicar agentes son Perl y TCL, pero además de estudiar estos lenguajes se requieren estudiar algunos lenguajes declarativos para comunicación entre agentes y entre estos podemos encontrar el lenguaje ACL. En este punto voy a detenerme por cuanto el estudiar ACL involucra estudiar KIF y KQML en donde el primero es formato para intercambio de conocimiento “Knowledge Interchange Format” y el segundo es lenguaje de manipulación y consultas de dicho conocimiento “Knowledge Query Manipulation Language”. No se puede olvidar que los agentes móviles interactúan la mayoría de las veces con computadoras y esto hace que se haga necesario estudiar también algunos protocolos de comunicación entre computadoras y que son bastante aplicables a los agentes, entre los que podemos mencionar MICK, ATP, CORBA y RMI. Aunque no se requiere dominar todos los pormenores de las aplicaciones distribuidas, si es bueno que se tengan buenas bases sobre el desarrollo de aplicaciones distribuidas y esto se logra sobre todo haciendo algunos ejercicio prácticos con CORBA y RMI. Cuando ya se tenga todo este recorrido ahora se puede comenzar a comprender algunos algoritmos para desarrollar agentes, comprendiendo sus características y estándares de modelamiento. Casi al final se pueden aplicar estos algoritmos y usar la comunicación que ya se ha hecho para desarrollar los agentes móviles tanto entre dispositivos móviles, como entre y con computadoras. El problema muy posiblemente de estos agentes es que sean demasiado sencillos y que las aplicaciones que se desarrollen con estos agentes sean muy sencillas debido a la complejidad que se requiere al hacer muchas cosas casi manualmente. Finalmente ya se esta en capacidad de usar frameworks que implementan agentes y si es necesario hacer algunos ajustes a mano, ya se ha hecho por lo menos un agente a mano y se tiene idea de su funcionamiento interno y a bajo nivel. Algunos de estos frameworks son por ejemplo JADE y aunque no se requiere nada de JENA, los que han trabajado este tipo de cosas les puede ser mas fácil comprender JADE. Se pueden instalar plataformas que permitan ejecutar agentes como por ejemplo SMA y metodológicamente se puede seguir la metodología INGENIAS para el desarrollo de agentes software. Se comienza ahora si la fase no de capacitación, sino de desarrollo del proyecto y aconsejaría que después se buscara si existen frameworks para probar los agentes, así como existe JUNIT para probar aplicaciones Java, es muy probable que cuando se este terminando el proyecto ya existan frameworks para probar los agentes desarrollados. 39. ANEXO 3: PREGUNTAS SOBRE LO VISTO EN CLASE DE ANALISIS DE SISTEMAS CON EL PROFESOR LUIS FELIPE WANUMEN 39.1. CUESTIONARIO 1: SOBRE GENERALIDADES RUP Y UML (Tenga en cuenta amigo lector / estudiante que el material necesario para responder estas preguntas esta en el libro de análisis expuesto en clase) 1. Cuales son las fases de RUP. 1. Iniciación, construcción. 2. Análisis, Diseño, implementación y pruebas. 3. Requerimientos, análisis, diseño, implementación y pruebas. 4. Planeación, Modelamiento del negocio, requerimientos, análisis, diseño, implementación, pruebas, despliegue y pruebas 5. Ninguna de las anteriores 2. Cuantos son los diagramas de UML 1. 7 2. 4 3. 8 4. 19 5. Ninguna de las anteriores. 3. ¿Qué es un requerimiento no funcional? 1. Es un requerimiento que no cumple una funcion alguna. 2. Un requerimiento relacionado con programación funcional. 3. Un requerimiento que hace parte de las funciones de quien desarrolla el sistema. 4. Un requerimiento que hace no forma parte de las funciones de quien desarrolla el sistema. 5. Ninguna de las anteriores 4. Un diagrama de secuencia puede contener: 1. Interacciones 2. Estados y objetos 3. Realizaciones 4. Asociaciones 5. Generalizaciones 6. Ninguna de las anteriores 5. Un diagrama de secuencia no puede contener 1. Interacciones 2. Objetos 3. Líneas de vida 4. Estereotipos 5. Ninguna de las anteriores. 6. Sobre las vistas de RUP podemos decir 1. Que son cuatro 2. Que pueden variar de acuerdo al proyecto. 3. Que son seis. 4. Que son la vista dinámica y la estática 5. Ninguna de las anteriores. 7. Una tarjeta CRC es importante porque 1. De ella se derivan las fases de diseño e implementación 2. De ella se deriva las fases de análisis, diseño, implementación. 3. Con ella se pueden hacer pruebas unitarias. 4. Con ellas se pueden bosquejar los diagramas del proyecto y son la base de la vista 5. mas importante de UML que es la vista de análisis 5. Ninguna de las anteriores 8. Una variable estática es: 1. Una variable a la cual no se le puede cambiar su valor. 2. Una variable que tiene asociados dos objetos como mínimo. 3. Una variable global a un objeto. 4. Es lo mismo que una variable de instancia. 5. Ninguna de las anteriores 9. Cual de las siguientes frases es verdadera: 1. RUP tiene tres vistas. 2. RUP posee fases y en cada fase se debe hacer una iteración. 3. RUP tiene tiene fases e interacciones. 4. RUP enfatiza que lo mas importante es la fase de implementacion, debido a que es la que consume mayor cantidad de tiempo en su desarrollo. 5. Ninguna de las anteriores. FAVOR OBLIGATORIO Favor traer para la próxima clase investigadas las respuestas correctas y no solamente las respuestas sino también la justificación de dichas respuestas en donde se coloquen las referencias bibliograficas de donde se obtuvo la respuesta. 39.2. RESPUESTAS SOBRE CUESTIONARIO 1 1. Cuales son las fases de RUP. Respuesta: 5. Ninguna de las anteriores. 2. Cuantos son los diagramas de UML Respuesta: 5. Ninguna de las anteriores. 3. ¿Qué es un requerimiento no funcional? Respuesta: 5. Ninguna de las anteriores. 4. Un diagrama de secuencia puede contener: Respuesta: 5. Ninguna de las anteriores. 5. Un diagrama de secuencia no puede contener Respuesta: 5. Ninguna de las anteriores. 6. Sobre las vistas de RUP podemos decir Respuesta: 5. Ninguna de las anteriores. 7. Una tarjeta CRC es importante porque Respuesta: 5. Ninguna de las anteriores. 8. Una variable estática es: Respuesta: 5. Ninguna de las anteriores. 9. Cual de las siguientes frases es verdadera: Respuesta: 5. Ninguna de las anteriores. INDICE ALFABETICO A abstract, 205 Accesibilidad, 44 Acoplamiento, 55, 63 Adaptador, 334, 335, 337, 339 Administracion, 17, 19, 21, 23, 24, 25, 26 Agregacion, 148 Alcance, 41, 47, 208 Ambiente, 17, 19, 21, 23, 24, 25 Ambito, 206 Análisis, 16, 71, 72, 73, 74, 75, 77, 78, 362, 368, 371, 391, 400 anteproyecto, 33, 42, 45 anulacion, 202, 203 Autenticación, 43 flujos de proceso, 15, 16, 28, 30 flujos de soporte, 15, 16, 28 flujos de trabajo de proceso, 14 G Gestión, 16, 71, 368, 369, 371, 374, 375 H herencia, 54, 63, 114, 119, 128, 157, 158, 162, 164, 169, 172, 173, 174, 205, 206, 323 Hilos, 285, 297 I Identidad, 43 Implementación, 16, 71, 72, 73, 74, 75, 77, 78 Include, 88 Ingeniería de Software, 14, 36, 371, 372, 373, 374, 375, 385, 391 Iniciacion, 16, 17, 23 Instancia, 115, 117, 120, 121, 205, 207, 307, 311, 401 Integridad, 43 interdependencia, 63 Interfaz, 26, 164, 166, 168, 170, 171, 172, 174, 177, 237, 242, 244, 245, 255, 260, 266, 273, 287, 288, 289, 315, 316, 331, 355 invalidacion, 203 Iteracion, 210 Iterator, 315 B Base de datos, 38, 39, 48, 62, 107, 108, 130 C calidad, 15, 28, 30, 361, 363, 366, 367, 369, 370, 375, 393, 394 Casos de uso, 23, 24, 25, 26, 54, 65, 70, 71, 72, 73, 74, 75, 77, 78, 85, 87, 88, 89, 90, 91, 93, 94, 95, 99, 100, 101, 102, 103, 104, 105, 108, 371 Cohesion, 55, 57, 58, 59, 60, 62, 63 componentes, 24, 25, 26, 30, 46, 63, 65, 68, 70, 71, 72, 74, 75, 76, 78, 79, 332, 378 Confidencialidad, 43 Configuacion, 17, 19, 20, 21, 23, 24, 25, 26 Construccion, 20, 25, 347, 350 Costos, 49 Cronograma, 12, 23 Cualidades, 41 CVS, 25, 26, 371, 372, 373, 374, 375, 376, 379, 380 D J J2EE, 55, 63 Junit, 346, 356, 399 L Lenguaje, 13, 48, 50, 54, 63, 64, 65, 81, 82, 83, 112, 129, 174, 250, 256, 308, 332, 333, 375, 391, 397, 398 M Delegacion, 257, 260, 263 Delimitaciones, 47 dependencia, 63, 82, 102, 258, 259, 331 Despliegue, 16, 71, 72, 73, 74, 75, 77, 78, 375 diagrama de actividad, 24, 293, 295, 296 diagrama de clase, 113, 114 Diagrama de colaboración, 24, 65, 70, 71, 72, 73, 75, 76, 77, 79 diagrama de estados, 24, 275 Diseño, 16, 71, 72, 73, 74, 75, 77, 78, 371, 388, 394, 400 DOM, 50 Marco Conceptual, 49 Marco Historico, 49 Marco Referencial, 49 Marco Teorico, 48 MDA, 383, 384, 385, 386, 387, 388, 389, 390 Metodología, 28, 29, 30, 34, 46, 48, 50, 374, 375, 394, 399 Métricas, 36, 37, 38, 41, 371 Modelado, 13, 16, 71, 72, 73, 74, 75, 77, 78, 375, 380, 391 Modelamiento, 1, 17, 18, 20, 21, 23, 24, 25, 26, 50, 69, 70, 112, 285, 385, 391 Modelo, 24, 25, 26, 45, 50, 69, 82, 83, 130, 315, 316, 317, 365, 366, 383, 384, 385, 386, 387, 389, 394 E Elaboracion, 18, 24, 354 entorno, 48, 367, 386, 397, 398 Entorno, 16, 71, 369, 371, 375 estereotipo, 95, 99, 100, 316, 320, 351 N negocio, 15, 16, 19, 26, 48, 69, 71, 72, 73, 74, 75, 76, 77, 78, 133, 134, 366, 368, 371, 375, 400 F Factibilidad, 49 Fases, 13 Fiabilidad, 43 Finalizador, 108 O Objetivos Generales, 36 Observable, 250, 251, 252, 256 Observer, 250, 251, 252, 256 OCL, 26, 81, 82, 83, 84 Resumen de la Tesis, 34 Riesgo, 48 Rup, 12, 13, 15, 16, 18, 19, 20, 21, 22, 23, 28, 29, 30, 34, 50, 71, 210, 374, 391, 394, 396, 400, 401, 402 P Paquetes, 340, 341, 345 Patrones, 1, 303, 304 Personal, 23, 24, 25, 26, 33, 34, 108, 147, 374, 397 Polimorfismo, 198, 199, 200, 201 Problema, 42 Procedimiento, 57 proceso, 14, 15, 20, 28, 30, 34, 36, 38, 87, 106, 265, 290, 291, 307, 308, 347, 361, 362, 363, 366, 367, 368, 371, 374, 375, 378, 384, 385, 393 Producto, 50 Programador, 10, 38, 146, 244, 380 Proyecto, 32, 39, 41, 47, 48, 49, 51, 396, 397 pruebas, 15, 19, 23, 24, 25, 26, 29, 346, 347, 352, 355, 356, 371, 376, 400, 401 Pruebas, 16, 24, 25, 26, 71, 72, 73, 74, 75, 77, 78, 371, 375 S secuencia, 24, 25, 54, 60, 65, 68, 70, 71, 72, 73, 75, 76, 77, 79, 105, 107, 332, 400, 401, 402 Serializacion, 264, 271, 275, 279 Singleton, 311, 312, 313 sistema de información, 20, 36, 85, 394 T Test, 17, 18, 20, 21, 23, 24, 25, 26 Transicion, 21, 26 Transientes, 271 U UML, 1, 10, 50, 65, 68, 69, 71, 81, 82, 83, 84, 85, 87, 100, 112, 129, 135, 144, 146, 147, 257, 258, 259, 260, 267, 275, 276, 311, 344, 345, 375, 383, 387, 390, 391, 392, 400, 401, 402 R Recursos, 17, 23, 24, 25, 26, 34, 45, 46, 48, 51, 208, 256, 311, 367, 370, 393 redefinicion, 202 Requisitos, 16, 71, 72, 73, 74, 75, 77, 78, 371, 375 V Veracidad, 43 LO QUE SE LLEVA DEFINITIVO ESTA EN VERDE EL RESTO EN ROJO TABLA DE CONTENIDO 2 CONVENCIONES 9 NOTAS ACLARATORIAS 10 1. EL CRONOGRAMA EN RUP 11 2.1. LAS FASES Y LOS FLUJOS DE RUP 12 2.2. FASE DE INICIACION EN RUP 15 2.3. FASE DE ELABORACION EN RUP17 2.4. FASE DE CONSTRUCCION EN RUP 19 2.5. FLUJO DE TRANSICION EN RUP 20 2. CONSIDERACIONES AL REALIZAR SU PROYECTO DE GRADO 31 2.1. SOBRE LAS FUNCIONES QUE DEBEN REALIZAR LOS PASANTES EN LOS PROYECTOS DE GRADO 31 2.2. CONSIDERACIONES SOBRE LAS PALABRAS QUE DEBE INCLUIR EL DOCUMENTO DE GRADO O PROYECTO DE SOFTWARE 31 2.3. SOBRE LA INTRODUCCION DE LA TESIS 33 2.4. SOBRE El RESUMEN DE LA TESIS 33 2.5. SOBRE EL TITULO DE LA TESIS 35 2.6. PLANTEAR OBJETIVOS GENERALES Y ESPECIFICOS 35 2.7. OTRAS COSAS SOBRE LOS OBJETIVOS ESPECIFICOS 38 2.8. ALGUNOS EJEMPLOS DE OBJETIVOS Y SUS CORRECCIONES 39 2.9. CUIDADOS AL PLANTEAR EL ALCANCE DEL PROYECTO 40 2.10. COSAS HA TENER EN CUENTA EN EL PLANTEAMIENTO DEL PROBLEMA 41 2.11. EJEMPLO DESGLOSADO DE DESCRIPCION DEL PROBLEMA 45 2.12. COSAS SOBRE LAS DELIMITACIONES 46 2.13. SOBRE EL ALCANCE Y LAS DELIMITACIONES 46 2.14. COSAS SOBRE EL RIESGO 47 2.15. SOBRE EL MARCO TEORICO. 47 2.16. COSAS HA TENER EN CUENTA SOBRE EL MARCO HISTORICO 48 2.17. COSAS SOBRE EL MARCO CONCEPTUAL 48 2.18. COSAS SOBRE EL MARCO REFERENCIAL 48 2.19. COSAS SOBRE LOS COSTOS DEL PROYECTO 48 2.20. COSAS SOBRE LA FACTIBILIDAD OPERATIVA DEL PROYECTO 48 2.21. COSAS SOBRE LA METODOLOGIA 48 2.22. COSAS HA TENER EN CUENTA EN EL MODELAMIENTO 49 2.23. TALLER PROPUESTO PARA MEJORAR LA FASE DE PLANEACION DEL PROYECTO 50 2.24. TALLER PROPUESTO PARA PENSAR EN OBJETOS 53 3. LA COHESIÓN Y EL ACOPLAMIENTO ENTRE CLASES Y OBJETOS 54 3.1. GENERALIDADES SOBRE LA COHESIÓN 54 3.2. COHESIÓN CASUAL 56 3.3. COHESIÓN LÓGICA 57 3.4. COHESIÓN TEMPORAL 58 3.5. COHESIÓN DE PROCEDIMIENTO 59 3.6. COHESIÓN DE COMUNICACIÓN 61 3.7. COHESIÓN SECUENCIAL 61 3.8. COHESIÓN FUNCIONAL 62 3.9. ACOPLAMIENTO 62 3.10. TALLER PROPUESTO 62 4. GENERALIDADES DE UML 64 4.1. DIAGRAMAS DE CASOS DE USO 64 4.2. DIAGRAMAS DE ACTIVIDADES 65 4.3. DIAGRAMAS DE CLASES 65 4.4. DIAGRAMAS DE INTERACCION 67 4.5. DIAGRAMAS DE ESTADO 67 4.6. DIAGRAMAS DE COMPONENTES 67 4.7. DIAGRAMAS DE DESPLIEGUE 67 5. MODELANDO CON UML 68 5.1. MODELAMIENTO DEL DOMINIO DEL PROBLEMA 68 5.2. MODELAMIENTO DE LA SOLUCION DEL PROBLEMA 69 5.3. MODELAMIENTO DE LA CODIFICACION DEL PROBLEMA 69 6. MODELOS UML EN LOS FLUJOS DE TRABAJO RUP 70 6.1. DIAGRAMAS USADOS EN EL FLUJO DE MODELADO DEL NEGOCIO 71 6.2. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO REQUERIMIENTOS72 6.3. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO ANALISIS Y DISENO 73 6.4. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO IMPLEMENTACION 74 6.5. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO DESPLIEGUE 76 6.6. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO PRUEBAS 77 7. EL LENGUAJE OCL 80 7.1. OCL Y MOF 80 7.2. UML Y OCL 80 7.3. EVOLUCION DE OCL 81 7.4. COSAS QUE SE PUEDEN HACER CON OCL 82 7.5. OCL Y LOS REQUISITOS 82 7.6. CONCLUSIONES SOBRE OCL 82 7.7. BIBLIOGRAFIA SOBRE OCL 82 8. SOBRE LOS CASOS DE USO EN UML 2.0 84 8.1. IDENTIFICAR ACTORES Y CASOS DE USO 84 8.2. TIPOS DE RELACIONES ENTRE LOS CASOS DE USO 87 8.3. IDENTIFICAR RELACIONES TIPO <<EXTENDS>> 88 8.4. ERRORES COMUNES CON RELACIONES TIPO <<EXTENDS>> 92 8.5. RELACIONES DE GENERALIZACION SIN ESTEREOTIPO 94 8.6. IDENTIFICAR RELACIONES TIPO <<USES>> O <<INCLUDE>> 99 8.7. EJEMPLO DE RELACION TIPO <<USES>> O <<INCLUDE>> 101 8.8. CASO ESPECIAL DE RELACION TIPO <<USES>> O <<INCLUDE>> 102 8.9. DOCUMENTACION DE CASOS DE USO 103 9. MODELAMIENTO UML Y SU IMPLEMENTACIÓN EN JAVA 111 9.1. DEFINICIÓN DE RELACIONES 111 9.2. GENERALIZACIÓN VS HERENCIA 112 9.3. EL ACCESO PRIVADO 114 9.4. EL ACCESO PROTECTED 118 9.5. ACCESO A LOS ATRIBUTOS: PRIVATE, PROTECTED O PUBLIC 121 9.6. ASOCIACIONES 121 9.7. LAS AGREGACIONES 123 9.8. RELACIONES DE DEPENDENCIA 125 9.9. HERENCIA MÚLTIPLE EN JAVA 127 10. ESTEREOTIPOS DE LAS CLASES EN UML 2.0 128 10.1. LAS CLASES CON ESTEREOTIPO VIEW 128 10.2. LAS CLASES CON ESTEREOTIPO TABLE 128 10.3. LAS CLASES CON ESTEREOTIPO SERVICE 129 10.4. LAS CLASES CON ESTEREOTIPO RESOURCE 129 10.5. OTROS ESTEREOTIPOS DE CLASES 130 11. DIAGRAMAS DE CLASE Y CONCEPTOS 134 11.1. CASO 1: CUANDO NO SE PUEDE COLOCAR ESPECIFICADOR DE ACCESO A UNA CLASE 134 11.2. ASOCIACIONES CON CARDINALIDAD FINITA 136 11.3. ASOCIACIONES CON CARDINALIDAD INFINITA 137 11.4. CLASES TIPO UTILITY 140 11.5. LAS CLASES UTILITARIAS NO PUEDEN ESTAR CONTENIDAS EN OTRAS 141 11.6. LAS AGREGACIONES 143 11.7. EN LAS AGREGACIONES UN TODO NO PUEDE SER UNA PARTE DE SI MISMO 146 11.8. CICLO ILEGAL DE AGREGACION ENTRE DOS INSTANCIAS DE DISTINTA CLASE 147 11.9. DIAGRAMAS DE CLASES DE EJEMPLOS 149 12. P.O.O. EN JAVA Y CLASES ABSTRACTAS 153 12.1. LAS CLASES ABSTRACTAS 153 12.2. CASO 1: SOBRE LAS CLASES ABSTRACTAS 154 12.3. CASO 2: SOBRE LAS CLASES ABSTRACTAS 154 12.4. CASO 3: SOBRE LAS CLASES ABSTRACTAS 155 12.5. CASO 4: SOBRE LAS CLASES ABSTRACTAS 156 12.6. CASO 5: SOBRE LAS CLASES ABSTRACTAS 157 12.7. CASO 6: SOBRE LAS CLASES ABSTRACTAS 158 12.8. CASO 7: SOBRE LAS CLASES ABSTRACTAS 160 12.9. CASO 8: SOBRE LAS CLASES ABSTRACTAS 161 13. P.O.O. EN JAVA Y LAS INTERFACES 163 13.1. LAS INTERFACES DEBEN INICIALIZAR SUS ATRIBUTOS 164 13.2. EN LAS INTERFACES NO ES OBLIGATORIO MODIFICADORES DE ATRIBUTOS 165 13.3. EL MODIFICADOR DE ATRIBUTO POR DEFECTO ES PUBLIC EN LAS INTEFACES 165 13.4. EL MODIFICADOR DE ATRIBUTO PROTECTED NO ESTA PERMITIDO EN LAS INTERFACES 166 13.5. EL MODIFICADOR DE ATRIBUTO PRIVATE NO ESTA PERMITIDO EN LAS INTERFACES 166 13.6. UNA INTERFAZ NO PUEDE SER INSTANCIADA DIRECTAMENTE 167 13.7. UNA CLASE NO INTERFAZ PUEDE IMPLEMENTAR UNA CLASE INTERFAZ 168 13.8. UNA CLASE INTERFAZ NO PUEDE IMPLEMENTAR UNA CLASE INTERFAZ 169 13.9. UNA CLASE INTERFAZ PUEDE EXTENDER DE UNA CLASE INTERFAZ 170 13.10. UNA CLASE NO INTERFAZ PUEDE IMPLEMENTAR VARIAS CLASES TIPO INTERFAZ 171 13.11. UNA CLASE INTERFAZ PUEDE EXTENDER DE VARIAS CLASES TIPO INTERFAZ 173 13.12. UNA CLASE NO INTERFAZ NO PUEDE EXTENDER DE UNA CLASE TIPO INTERFAZ 174 13.13. NO SE PUDE MODIFICAR VARIABLE DE UNA CLASE TIPO INTERFAZ 175 13.14. CLASE QUE IMPLEMENTE CLASE TIPO INTERFAZ DEBE DEFINIR SUS MÉTODOS 178 14. SOBRE LAS CLASES Y ATRIBUTOS TIPO FINAL 181 14.1. LOS ATRIBUTOS FINAL DEBEN ESTAR INICIALIZADOS 182 14.2. ATRIBUTOS FINAL Y CLASES NO FINAL 183 14.3. RECUPERACION DE ATRIBUTOS FINALES 184 14.4. ASIGNACION DE VALORES A LOS ATRIBUTOS TIPO FINAL 185 14.5. CREACION DE METODOS TIPO FINAL 187 14.6. TALLER PROPUESTO SOBRE CLASES Y ATRIBUTOS TIPO FINAL 189 15. CASOS VARIADOS SOBRE CLASES INTERFACE, FINALES Y ABSTRACTAS 190 15.1. CASO 1: 190 15.2. CASO 2: 190 15.3. CASO 3: 191 15.4. CASO 4: 191 15.5. CASO 5: 193 15.6. CASO 6: 193 15.7. CASO 7: 194 15.8. CASO 8: 195 15.9. CASO 9: 195 15.10. TALLER 196 16. EL POLIMORFISMO PARECE NO SER EXLUSIVO DE LA HERENCIA NI DE LA ORIENTACION A OBJETOS 197 16.1. UNA DEFINICION MÁS FORMAL 197 16.2. UN EJEMPLO DE NO POLIMORFISMO 198 16.3. UN EJEMPLO DE POLIMORFISMO 199 16.4. TALLER PROPUESTO SORE POLIMORFISMO 200 17. REDEFINICIÓN Y ANULACION DE METODOS EN LA HERENCIA 201 17.1. ANULACION POR EXTENSION 202 17.2. ANULACION POR RESTRICCION 202 17.3. ANULACION POR OPTIMACIÓN 202 17.4. INVALIDACION POR CONVENIENCIA 202 17.5. TALLER SOBRE REDEFINICION DE METODOS EN LA HERENCIA 202 18. TODO A CERCA DE CLASES 204 18.1. TIPOS DE CLASES 204 18.2. VARIABLES Y METODOS DE INSTANCIA 205 18.3. AMBITO DE UNA VARIABLE 205 18.4. METODOS Y CONSTRUCTORES 206 18.5. FINALIZADORES 207 18.6. ALCANCE DE OBJETOS Y RECICLADO DE MEMORIA 207 19. EJERCICIO DEL PIRATA RESULADO DE LA PRIMERA ITERACION CON RUP 209 19.1. PLANTEAMIENTO DEL ENUNCIADO 209 19.2. ESTABLECIMIENTO DE FRASES IMPORTANTES. 209 19.3. ESTABLECIMIENDO DE CLASES 210 19.4. PROGRAMA EN JAVA 211 19.5. EJECUCIÓN DEL PROGRAMA: 216 20. EJERCICIO DEL AVION 219 20.1. DIAGRAMA DE CLASE 219 20.2. EXPLICACIÓN DE LA IMPLEMENTACIÓN 220 20.3. EJECUCIÓN DEL PROGRAMA 228 21. LA CLONACION DE OBJETOS 231 21.1. COPIA DE OBJETOS LIMITADA 231 21.2. COPIAR OBJETOS CON INTERFAZ CLONEABLE 241 21.3. LA INTERFAZ CLONEABLE ABARCA SUBOBJETOS 244 22. CLASES TIPO OBSERVER Y OBSERVABLE 249 22.1. ESTRUCTURA DE LAS CLASES OBSERVABLES 249 22.2. ESTRUCTURA DE LAS CLASES OBSERVER 250 22.3. CREACION DE OBJETOS DE TIPO OBSERVER Y OBSERVABLE 250 22.4. VINCULACION DEL OBJETO OBSERVABLE AL OBJETO OBSERVER 251 22.5. UN EJEMPLO COMPLETO CON OBSERVER Y OBSERVABLE 251 22.6. PREGUNTAS SOBRE OBSERVER Y OBSERVABLE 255 23. COMO DELEGAR CLASES 256 23.1. PLANTEAMIENTO TEORICO DE LA DELEGACION 256 23.2. EJERCICIO PRÁCTICO SOBRE DELEGACION 259 23.3. PREGUNTAS SOBRE DELEGACION 262 24. SERIALIZACION DE OBJETOS 263 24.1. SERIALIZAR UN OBJETO COMPLETAMENTE 263 24.2. SERIALIZAR UN OBJETO COMPLETAMENTE EN JAVA 265 24.3. ATRIBUTOS TRANSIENTES EN LA SERIALIZACION 270 24.4. LA SERIALIZACION Y EL DIAGRAMA DE ESTADOS 274 24.5. TALLER PROPUESTO SOBRE SERIALIZACION 278 25. EJERCICIOS QUE TIENEN DIAGRAMAS DE SECUENCIA 284 25.1. MODELAMIENTO DE DETENCION SINCRONICA DE MULTIPLES HILOS CON UN EJEMPLO. 284 25.2. IMPLEMENTACION DE DETENCION SINCRONICA DE MULTIPLES HILOS CON UN EJEMPLO. 296 26. INTRODUCCION A LOS PATRONES DE SOFTWARE 302 26.1. PATRONES CON FUNCIONALIDAD DE CREACIÓN 302 26.2. PATRONES CON FUNCIONALIDAD ESTRUCTURAL 302 26.3. PATRONES CON FUNCIONALIDAD DE COMPORTAMIENTO 302 27. EXPLICACION DETALLADA DE LOS PATRONES 303 27.1. EJEMPLO PRÁCTICO DE APLICACIÓN DE FACTORY 303 27.2. EJEMPLO MAS ELABORADO USANDO FACTORY 306 28. PATRON DE CREACION SINGLETON 310 28.1. PARTE TEORICA DEL PATRON SINGLETON 310 28.2. PARTE PRACTICA DEL PATRON SINGLETON 311 28.3. OBSERVACIONES AL EJERCICIO DE SINGLETON 312 29. PATRON ITERATOR 314 29.1. DESCRIPCION 314 29.2. APLICABILIDAD 314 29.3. IMPLEMENTACION DE LA SOLUCION 317 29.4. OBSERVACIONES GENERALES AL EJERCICIO DESARROLLADO 329 29.5. TALLER PROPUESTO SOBRE EL EJERCICIO. 331 30. PATRON ADAPTADOR 333 30.1. DEFINICION DEL PATRON ADAPTADOR 333 30.2. UN EJEMPLO QUE USA EL PATRON ADAPTADOR 333 30.3. ESTRUCTURA GENERAL DEL PATRON ADAPTADOR 336 30.4. OTRAS APLICACIONES DEL PATRON ADAPTADOR 338 31. PAQUETES Y DIAGRAMA DE PAQUETES 339 31.1. LOS JAR Y LOS PAQUETES 340 31.2. PAQUETES ANIDADOS 344 32. FLUJO DE PRUEBAS 345 32.1. FUNCIONAMIENTO DE JUNIT 345 32.2. CONSTRUCCION DE LA CLASE QUE VAMOS A PROBAR 346 32.3. CONSTRUCCION DE CASO DE PRUEBA PARA CLASE LISTA 349 32.4. ELABORACION DEL PROGRAMA QUE EJECUTA LA PRUEBA 353 32.5. EJECUCION DEL TESTRUNNER 353 33. SOBRE LA CALIDAD DEL SOFTWARE 360 33.1. MODELOS DE CALIDAD 360 33.2. MODELO SPICE 364 33.3. NORMA ISO 9000-2000 364 33.4. NORMA ISO 90003 365 33.5. NORMA ISO/IEC TR 15504 365 33.6. ESTANDAR ISO 9126 366 33.7. MODELOS CMMI366 33.8. TALLER PROPUESTO DE CALIDAD 369 34. LOS SISTEMAS DE CONTROL DE VERSIONES 370 34.1. LOS CVS Y EL PROCESO DE DESARROLLO UNIFICADO 370 34.2. LA GESTION DE CONFIGURACIONES Y LOS CVS 371 34.3. CONTENIDO DE LA UNIDAD 372 34.4. CONCRETANDO LO QUE ES UN CVS 372 34.5. TIPOS DE SISTEMAS DE CONTROL DE VERSIONES 373 34.6. LOS CVS Y LA INGENIERÍA DE SOFTWARE 373 34.7. SISTEMAS PARA GESTIONAR LOS CVS 374 34.8. OTROS SISTEMAS QUE APOYAN A LOS CVS 375 34.9. CARACTERISTICAS QUE DEBE TENER UN BUEN CONTROL DE VERSIONES 376 34.10. EL FUTURO DE LOS CVS 378 34.11. CONCLUSIONES SOBRE LOS CVS 378 34.12. BIBLIOGRAFIA DE LA UNIDAD 379 34.13. INFOGRAFIA DE LA UNIDAD 379 35. ARQUITECTURA CENTRADA EN MODELOS 382 35.1. INTRODUCCIÓN A MDA 382 35.2. PALABRAS CLAVE 382 35.3. INTRODUCCION A MDA 382 35.4. ¿MDA UN ENFOQUE DE DESARROLLO O ESTANDAR DE DESARROLLO? 382 35.5. ¿MDD O MDA? 383 35.6. ¿ACASO NO TRABAJAMOS CON MODELOS DESDE HACE MUCHO TIEMPO? 383 35.7. REALMENTE: ¿QUÉ ES LO NUEVO? 384 34.8. ¿TODO CON MODELAMIENTO NO ES ACASO UNA UTOPIA? 384 34.9. ¿QUÉ SE PODRÍA HACER CON LOS MODELOS? 385 34.10. LOS MODELOS DEBEN SER: ¿DEPENDIENTES O INDEPENDIENTES DE LA PLATAFORMA? 385 34.11. ¿QUÉ SON LOS MODELOS DEPENDIENTES DEL SISTEMA? 386 34.12. ¿SE DEBEN AUTOMATIZAR LAS TRANSFORMACIONES? 386 34.13. ¿QUÉ LENGUAJES USARÁ MDA? 386 34.14. ¿QUÉ INTERPRETACIONES HAY DE MDA? 387 34.15. CONCLUSIONES SOBRE MDA 387 34.16. BIBLIOGRAFIA SOBRE MDA 389 35. BIBLIOGRAFIA 390 35.1. BIBLIOGRAFIA SOBRE PROCESOS DE DESARROLLO Y RUP 390 35.2. BIBLIOGRAFIA SOBRE MODELAMIENTO CON UML 390 35.3. BIBLIOGRAFIA SOBRE IMPLEMENTACIONES CON UML 391 36. ANEXO 1: CORRECCIONES HECHAS A PROYECTOS DE GRADO 392 36.1. ALGUNAS CORRECCIONES PASADAS A ALGUNOS PROYECTOS DE GRADO: CARTA 1 392 36.2. ALGUNAS CORRECCIONES PASADAS A ALGUNOS PROYECTOS DE GRADO: CARTA 2 393 37. ANEXO 2: COSAS HA TENER EN CUENTA EN LOS PROYECTOS DE GRADO 395 37.1 SI EL PROYECTO QUE SE VA A REALIZAR ES SOBRE APLICACIONES MOVILES Y ES DE TECNOLOGÍA EN SISTEMATIZACIÓN DE DATOS. 395 37.2. SI EL PROYECTO QUE SE VA A REALIZAR ES SOBRE APLICACIONES MOVILES Y ES DE INGENIERÍA EN REDES DE COMPUTADORES O INGENIERÍA EN TELEMÁTICA. 396 37.3. SI VAS A REALIZAR UN PROYECTO SOBRE APLICACIONES CON AGENTES MOVILES REQUIERES 396 38. ANEXO 3: PREGUNTAS SOBRE LO VISTO EN CLASE DE ANALISIS DE SISTEMAS CON EL PROFESOR LUIS FELIPE WANUMEN 399 38.1. CUESTIONARIO 1: SOBRE GENERALIDADES RUP Y UML 399 38.2. RESPUESTAS SOBRE CUESTIONARIO 1 401 INDICE ALFABETICO 402