RUP-UML

257
LIBRO PARA LA ASIGNATURA DE 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

Transcript of RUP-UML

Page 1: RUP-UML

LIBRO PARA LA ASIGNATURA DE

ANALISIS DE SISTEMAS

AUTORES JUAN CARLOS GUEVARA BOLAÑOS Y

LUIS FELIPE WANUMEN SILVAGRUPO 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 CALDASFACULTAD TECNOLÓGICA

SISTEMATIZACIÓN DE DATOSBOGOTÁ D.C.

2008

Page 2: RUP-UML

TABLA DE CONTENIDO

TABLA DE CONTENIDO ..................................................................................................... 2 1. EL CRONOGRAMA EN RUP ........................................................................................... 7

2.1. LAS FASES Y LOS FLUJOS DE RUP ...................................................................... 8 2.2. FASE DE INICIACION EN RUP ............................................................................. 11 2.3. FASE DE ELABORACION EN RUP ....................................................................... 13 2.4. FASE DE CONSTRUCCION EN RUP .................................................................... 15 2.5. FLUJO DE TRANSICION EN RUP ......................................................................... 16

2. CONSIDERACIONES AL REALIZAR SU PROYECTO DE GRADO ......................... 27 2.1. CONSIDERACIONES SOBRE LAS PALABRAS QUE DEBE INCLUIR EL DOCUMENTO DE GRADO O PROYECTO DE SOFTWARE ..................................... 27 2.2. SOBRE LA INTRODUCCION DE LA TESIS ......................................................... 28 2.2. SOBRE EL TITULO DE LA TESIS ......................................................................... 29 2.3. PLANTEAR OBJETIVOS GENERALES Y ESPECIFICOS ................................... 29 2.4. OTRAS COSAS SOBRE LOS OBJETIVOS ESPECIFICOS .................................. 31 2.5. CUIDADOS AL PLANTEAR EL ALCANCE DEL PROYECTO .......................... 32 2.6. COSAS HA TENER EN CUENTA EN EL PLANTEAMIENTO DEL PROBLEMA ........................................................................................................................................... 33 EJEMPLO DESGLOSADO DE DESCRIPCION DEL PROBLEMA ............................ 36 2.7. COSAS SOBRE LAS DELIMITACIONES .............................................................. 38 2.8. SOBRE EL ALCANCE Y LAS DELIMITACIONES .............................................. 38 2.9. COSAS SOBRE EL RIESGO .................................................................................... 38 2.10. COSAS HA TENER EN CUENTA SOBRE EL MARCO HISTORICO ............... 39 2.11. COSAS SOBRE EL MARCO CONCEPTUAL ...................................................... 39 2.12. COSAS SOBRE EL MARCO REFERENCIAL ..................................................... 39 2.13. COSAS SOBRE LOS COSTOS DEL PROYECTO ............................................... 39 2.14. COSAS SOBRE LA FACTIBILIDAD OPERATIVA DEL PROYECTO ............. 40 2.15. COSAS SOBRE LA METODOLOGIA .................................................................. 40 2.16. COSAS HA TENER EN CUENTA EN EL MODELAMIENTO ........................... 40 2.17. TALLER PROPUESTO PARA MEJORAR LA FASE DE PLANEACION DEL PROYECTO ...................................................................................................................... 41 2.18. TALLER PROPUESTO PARA PENSAR EN OBJETOS ...................................... 44

3. GENERALIDADES DE UML ......................................................................................... 45 3.1. DIAGRAMAS DE CASOS DE USO ........................................................................ 45 3.2. DIAGRAMAS DE ACTIVIDADES ......................................................................... 45 3.3. DIAGRAMAS DE CLASES ..................................................................................... 45 3.4. DIAGRAMAS DE INTERACCION ......................................................................... 45 3.5. DIAGRAMAS DE ESTADO .................................................................................... 46 3.6. DIAGRAMAS DE COMPONENTES ....................................................................... 46 3.7. DIAGRAMAS DE DESPLIEGUE ............................................................................ 46

4. MODELANDO CON UML .............................................................................................. 46

Page 3: RUP-UML

4.1. MODELAMIENTO DEL DOMINIO DEL PROBLEMA ........................................ 47 4.2. MODELAMIENTO DE LA SOLUCION DEL PROBLEMA .................................. 47 4.3. MODELAMIENTO DE LA CODIFICACION DEL PROBLEMA ......................... 47

5. MODELOS UML EN LOS FLUJOS DE TRABAJO RUP ............................................. 48 5.1. DIAGRAMAS USADOS EN EL FLUJO DE MODELADO DEL NEGOCIO ....... 49 5.2. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO REQUERIMIENTOS .... 50 5.3. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO ANALISIS Y DISENO . 50 5.4. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO IMPLEMENTACION ... 52 5.5. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO DESPLIEGUE ............... 53 5.6. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO PRUEBAS ..................... 54

6. EL LENGUAJE OCL ....................................................................................................... 57 6.1. OCL Y MOF .............................................................................................................. 57 6.2. UML Y OCL .............................................................................................................. 57 6.3. EVOLUCION DE OCL ............................................................................................. 58 6.4. COSAS QUE SE PUEDEN HACER CON OCL ...................................................... 58 6.5. OCL Y LOS REQUISITOS ....................................................................................... 58 6.6. CONCLUSIONES SOBRE OCL .............................................................................. 59 6.7. BIBLIOGRAFIA SOBRE OCL ................................................................................. 59

7. SOBRE LOS CASOS DE USO EN UML 2.0 .................................................................. 61 7.1. IDENTIFICAR ACTORES Y CASOS DE USO ...................................................... 61 7.2. TIPOS DE RELACIONES ENTRE LOS CASOS DE USO ..................................... 63 7.3. IDENTIFICAR RELACIONES TIPO <<EXTENDS>> ........................................... 64 7.4. ERRORES COMUNES CON RELACIONES TIPO <<EXTENDS>> .................... 68 7.5. RELACIONES DE GENERALIZACION SIN ESTEREOTIPO .............................. 70 7.6. IDENTIFICAR RELACIONES TIPO <<USES>> O <<INCLUDE>> .................... 75 7.7. EJEMPLO DE RELACION TIPO <<USES>> O <<INCLUDE>> ......................... 77 7.8. CASO ESPECIAL DE RELACION TIPO <<USES>> O <<INCLUDE>> ............ 78 7.9. DOCUMENTACION DE CASOS DE USO ............................................................. 79

8. MODELAMIENTO UML Y SU IMPLEMENTACIÓN EN JAVA ................................ 86 8.1. DEFINICIÓN DE RELACIONES ............................................................................. 86 8.2. GENERALIZACIÓN VS HERENCIA .................................................................... 87 8.3. EL ACCESO PRIVADO ........................................................................................... 88 8.4. EL ACCESO PROTECTED ...................................................................................... 90 8.5. ACCESO A LOS ATRIBUTOS: PRIVATE, PROTECTED O PUBLIC ................. 91 8.6. ASOCIACIONES ...................................................................................................... 92 8.7. LAS AGREGACIONES ............................................................................................ 93 8.8. RELACIONES DE DEPENDENCIA ........................................................................ 96 8.9. HERENCIA MÚLTIPLE EN JAVA ......................................................................... 97

9. ESTEREOTIPOS DE LAS CLASES EN UML 2.0 ......................................................... 98 9.1. LAS CLASES CON ESTEREOTIPO VIEW ............................................................ 98 9.2. LAS CLASES CON ESTEREOTIPO TABLE .......................................................... 98 9.3. LAS CLASES CON ESTEREOTIPO SERVICE ...................................................... 99 9.4. LAS CLASES CON ESTEREOTIPO RESOURCE .................................................. 99 9.5. OTROS ESTEREOTIPOS DE CLASES ................................................................. 100

10. P.O.O. EN JAVA Y CLASES ABSTRACTAS ........................................................... 104 10.1. LAS CLASES ABSTRACTAS ............................................................................. 104 10.2. CASO 1: SOBRE LAS CLASES ABSTRACTAS ............................................... 105

Page 4: RUP-UML

10.3. CASO 2: SOBRE LAS CLASES ABSTRACTAS ................................................ 105 10.4. CASO 3: SOBRE LAS CLASES ABSTRACTAS ................................................ 106 10.5. CASO 4: SOBRE LAS CLASES ABSTRACTAS ................................................ 107 10.6. CASO 5: SOBRE LAS CLASES ABSTRACTAS ................................................ 108 10.7. CASO 6: SOBRE LAS CLASES ABSTRACTAS ................................................ 109 10.8. CASO 7: SOBRE LAS CLASES ABSTRACTAS ................................................ 111 10.9. CASO 8: SOBRE LAS CLASES ABSTRACTAS ................................................ 112

11. P.O.O. EN JAVA Y LAS INTERFACES ..................................................................... 113 11.1. LAS INTERFACES DEBEN INICIALIZAR SUS ATRIBUTOS ........................ 114 11.2. EN LAS INTERFACES NO ES OBLIGATORIO MODIFICADORES DE ATRIBUTOS .................................................................................................................. 115 11.3. EL MODIFICADOR DE ATRIBUTO POR DEFECTO ES PUBLIC EN LAS INTEFACES ................................................................................................................... 115 11.4. EL MODIFICADOR DE ATRIBUTO PROTECTED NO ESTA PERMITIDO EN LAS INTERFACES ........................................................................................................ 115 11.5. EL MODIFICADOR DE ATRIBUTO PRIVATE NO ESTA PERMITIDO EN LAS INTERFACES ........................................................................................................ 116 11.6. UNA INTERFAZ NO PUEDE SER INSTANCIADA DIRECTAMENTE ......... 116 11.7. UNA CLASE NO INTERFAZ PUEDE IMPLEMENTAR UNA CLASE INTERFAZ ..................................................................................................................... 117 11.8. UNA CLASE INTERFAZ NO PUEDE IMPLEMENTAR UNA CLASE INTERFAZ ..................................................................................................................... 118 11.9. UNA CLASE INTERFAZ PUEDE EXTENDER DE UNA CLASE INTERFAZ ......................................................................................................................................... 120 11.10. UNA CLASE NO INTERFAZ PUEDE IMPLEMENTAR VARIAS CLASES TIPO INTERFAZ ............................................................................................................ 121 11.11. UNA CLASE INTERFAZ PUEDE EXTENDER DE VARIAS CLASES TIPO INTERFAZ ..................................................................................................................... 122 11.12. UNA CLASE NO INTERFAZ NO PUEDE EXTENDER DE UNA CLASE TIPO INTERFAZ ..................................................................................................................... 123 11.13. NO SE PUDE MODIFICAR VARIABLE DE UNA CLASE TIPO INTERFAZ ......................................................................................................................................... 125 11.14. CLASE QUE IMPLEMENTE CLASE TIPO INTERFAZ DEBE DEFINIR SUS MÉTODOS ..................................................................................................................... 127

12. TODO A CERCA DE CLASES ................................................................................... 129 12.1. TIPOS DE CLASES .............................................................................................. 130 12.2. VARIABLES Y METODOS DE INSTANCIA .................................................... 130 12.3. AMBITO DE UNA VARIABLE ........................................................................... 131 12.4. METODOS Y CONSTRUCTORES ...................................................................... 131 12.5. FINALIZADORES ................................................................................................ 132 12.6. ALCANCE DE OBJETOS Y RECICLADO DE MEMORIA .............................. 132

13. EJERCICIO DEL PIRATA RESULADO DE LA PRIMERA ITERACION CON RUP ............................................................................................................................................. 134

13.1. PLANTEAMIENTO DEL ENUNCIADO ............................................................ 134 13.2. ESTABLECIMIENTO DE FRASES IMPORTANTES. ....................................... 134 13.3. ESTABLECIMIENDO DE CLASES .................................................................... 135 13.4. PROGRAMA EN JAVA ........................................................................................ 136

Page 5: RUP-UML

13.5. EJECUCIÓN DEL PROGRAMA: ........................................................................ 141 14. EJERCICIO DEL AVION ............................................................................................ 144

14.1. DIAGRAMA DE CLASE ...................................................................................... 144 14.2. EXPLICACIÓN DE LA IMPLEMENTACIÓN ................................................... 145 14.3. EJECUCIÓN DEL PROGRAMA .......................................................................... 155

15. LA CLONACION DE OBJETOS ................................................................................ 157 15.1. COPIA DE OBJETOS LIMITADA ....................................................................... 157 15.2. COPIAR OBJETOS CON INTERFAZ CLONEABLE ........................................ 166 15.3. LA INTERFAZ CLONEABLE ABARCA SUBOBJETOS .................................. 169

16. CLASES TIPO OBSERVER Y OBSERVABLE ......................................................... 174 16.1. ESTRUCTURA DE LAS CLASES OBSERVABLES ......................................... 174 16.2. ESTRUCTURA DE LAS CLASES OBSERVER ................................................. 175 16.3. CREACION DE OBJETOS DE TIPO OBSERVER Y OBSERVABLE .............. 175 16.4. VINCULACION DEL OBJETO OBSERVABLE AL OBJETO OBSERVER .... 176 16.5. UN EJEMPLO COMPLETO CON OBSERVER Y OBSERVABLE .................. 176 16.6. PREGUNTAS SOBRE OBSERVER Y OBSERVABLE ..................................... 179

17. COMO DELEGAR CLASES ....................................................................................... 181 17.1. PLANTEAMIENTO TEORICO DE LA DELEGACION .................................... 181 17.2. EJERCICIO PRÁCTICO SOBRE DELEGACION .............................................. 184 17.3. PREGUNTAS SOBRE DELEGACION ................................................................ 186

18. SERIALIZACION DE OBJETOS ................................................................................ 187 18.1. SERIALIZAR UN OBJETO COMPLETAMENTE ............................................. 187 18.2. SERIALIZAR UN OBJETO COMPLETAMENTE EN JAVA ............................ 189 18.3. ATRIBUTOS TRANSIENTES EN LA SERIALIZACION ................................ 194 18.4. LA SERIALIZACION Y EL DIAGRAMA DE ESTADOS ................................ 198 18.4. TALLER PROPUESTO SOBRE SERIALIZACION ........................................... 201

19. EJERCICIOS QUE TIENEN DIAGRAMAS DE SECUENCIA ................................. 206 19.1. MODELAMIENTO DE DETENCION SINCRONICA DE MULTIPLES HILOS CON UN EJEMPLO. ...................................................................................................... 206 19.2. IMPLEMENTACION DE DETENCION SINCRONICA DE MULTIPLES HILOS CON UN EJEMPLO. ...................................................................................................... 218

20. INTRODUCCION A LOS PATRONES DE SOFTWARE ......................................... 224 20.1. PATRONES CON FUNCIONALIDAD DE CREACIÓN .................................... 224 20.2. PATRONES CON FUNCIONALIDAD ESTRUCTURAL .................................. 224 20.3. PATRONES CON FUNCIONALIDAD DE COMPORTAMIENTO .................. 224

21. EXPLICACION DETALLADA DE LOS PATRONES .............................................. 224 21.1. EJEMPLO PRÁCTICO DE APLICACIÓN DE FACTORY ................................ 224 21.2. EJEMPLO MAS ELABORADO USANDO FACTORY ...................................... 228

22. PATRON DE CREACION SINGLETON .................................................................... 231 22.1. PARTE TEORICA DEL PATRON SINGLETON ................................................ 231 22.2. PARTE PRACTICA DEL PATRON SINGLETON ............................................. 232 22.3. OBSERVACIONES AL EJERCICIO DE SINGLETON ...................................... 233

23. SOBRE LA CALIDAD DEL SOFTWARE ................................................................. 235 23.1. MODELOS DE CALIDAD ................................................................................... 235 22.2. MODELO SPICE ................................................................................................... 238 23.3. NORMA ISO 9000-2000 ....................................................................................... 239 23.4. NORMA ISO 90003 .............................................................................................. 239

Page 6: RUP-UML

23.5. NORMA ISO/IEC TR 15504 ................................................................................. 239 23.6. ESTANDAR ISO 9126 .......................................................................................... 240 23.7. MODELOS CMMI ................................................................................................ 241 23.8. TALLER PROPUESTO DE CALIDAD ............................................................... 243

24. LOS SISTEMAS DE CONTROL DE VERSIONES ................................................... 244 24.1. LOS CVS Y EL PROCESO DE DESARROLLO UNIFICADO .......................... 244 24.2. LA GESTION DE CONFIGURACIONES Y LOS CVS ...................................... 245 24.2. CONTENIDO DE LA UNIDAD ........................................................................... 245 24.3. CONCRETANDO LO QUE ES UN CVS ............................................................. 246 24.4. TIPOS DE SISTEMAS DE CONTROL DE VERSIONES .................................. 246 24.5. LOS CVS Y LA INGENIERÍA DE SOFTWARE ................................................ 247 24.6. SISTEMAS PARA GESTIONAR LOS CVS ........................................................ 248 24.7. OTROS SISTEMAS QUE APOYAN A LOS CVS .............................................. 249 24.8. CARACTERISTICAS QUE DEBE TENER UN BUEN CONTROL DE VERSIONES ................................................................................................................... 249 24.9. EL FUTURO DE LOS CVS .................................................................................. 251 24.10. CONCLUSIONES SOBRE LOS CVS ................................................................ 251 24.11. BIBLIOGRAFIA DE LA UNIDAD .................................................................... 252 24.12. INFOGRAFIA DE LA UNIDAD ........................................................................ 253

25. BIBLIOGRAFIA ........................................................................................................... 256 25.1. BIBLIOGRAFIA SOBRE PROCESOS DE DESARROLLO Y RUP .................. 256 25.2. BIBLIOGRAFIA SOBRE MODELAMIENTO CON UML ................................. 256 25.3. BIBLIOGRAFIA SOBRE IMPLEMENTACIONES CON UML ......................... 257

Page 7: RUP-UML

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”.

Page 8: RUP-UML

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:

Diagrama elaborado por Luis Felipe Wanumen Silva.

FLUJOS DE RUP

Flujos de trabajo de proceso

Flujos de trabajo de soporte

Page 9: RUP-UML

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 clases2. Participar en proyectos institucionales3. Investigar4. Preparar clase5. Atender estudiantes6. Orientar pasantias y tesis7. Participar en comités institucionales8. Apoyar actividades de extensión de la universidad9. 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

Page 10: RUP-UML

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:

LOS FLUJOS DE TRABAJO EN RUP

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

Dan calidad a los flujos de proceso

Page 11: RUP-UML

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 FLUJOS DE SOPORTEModelado del negocioRequisitosAnálisis y DiseñoImplementaciónPruebasDespliegue

Gestión del cambio y configuracionesGestión del proyectoEntorno

De otra parte es interesante observar que las fases de RUP son las mostradas en el siguiente diagrama:

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,

Iniciación

Elaboración

Construcción

TransiciónFASES DE RUP

Page 12: RUP-UML

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 . FLUJOS DE TRABAJO PORCENTAJE

FASE DE INICIACION 22%

NEGOCIOS Y MODELAMIENTO 9,00%

REQUERIMIENTOS 5,00%

ANALISIS Y DISEÑO 1,00%IMPLEMENTACION 1,00%TEST PRUEBAS 0,00%DESPLIEGUE 0,00%

CONFIGURACION Y MANTENIMIENTO 2,00%

ADMINISTRACION 2,00%

AMBIENTE 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:

Page 13: RUP-UML

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 . FLUJOS DE TRABAJO PORCENTAJE

FASE DE ELABORACION

22%

NEGOCIOS Y MODELAMIENTO 4,00%

REQUERIMIENTOS 4,00%

ANALISIS Y DISEÑO 5,00%

IMPLEMENTACION 2,00%TEST PRUEBAS 1,00%

DESPLIEGUE 1,00%

Page 14: RUP-UML

CONFIGURACION Y MANTENIMIENTO 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”).

Page 15: RUP-UML

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 . FLUJOS DE TRABAJO PORCENTAJE

FASE DE CONSTRUCCION

30%

NEGOCIOS Y MODELAMIENTO 2,00%

REQUERIMIENTOS 2,00%ANALISIS Y DISEÑO 4,00%

IMPLEMENTACION 10,00%TEST PRUEBAS 2,00%DESPLIEGUE 1,00%

CONFIGURACION Y MANTENIMIENTO 5,00%

ADMINISTRACION 3,00%

Page 16: RUP-UML

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 . FLUJOS DE TRABAJO PORCENTAJE

FASE DE TRANSICION 26%

NEGOCIOS Y MODELAMIENTO 0,00%

REQUERIMIENTOS 1,00%ANALISIS Y DISEÑO 1,00%

IMPLEMENTACION 4,00%

TEST PRUEBAS 3,00%

DESPLIEGUE 11,00%

CONFIGURACION Y MANTENIMIENTO 5,00%

ADMINISTRACION 1,00%

Page 17: RUP-UML

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:

Page 18: RUP-UML

CRONOGRAMA BASADO EN RUP PLANTILLA

FASE . FLUJOS DE TRABAJO PORCENTAJE ACTIVIDAD DIAS

FASE DE INICIACION 22%

NEGOCIOS Y MODELAMIENTO 9,00%

Modelo de Dominio

27

Establecimiento de viabilidad del sistemaEstablecimiento de factibilidad Técnica del sistemaEstablecimiento de factibilidad Operativa del SistemaEstablecimiento de factibilidad Legal del SistemaModelo de procesos

REQUERIMIENTOS 5,00%

Definición de actores

15

Lista preliminar de casos de usoDocumentación de las excepciones de los casos de usoDocumentación de descripción de casos de usoDepuración de los casos de usoModelo de casos de Uso

ANALISIS Y DISEÑO 1,00% Lista preliminar de clases 3IMPLEMENTACION 1,00% Definición de las características de la herramienta 3TEST PRUEBAS 0,00% 0DESPLIEGUE 0,00% 0

CONFIGURACION Y MANTENIMIENTO 2,00%Creación de casos de uso de prueba

6Montaje de un servidor de pruebas

ADMINISTRACION 2,00%

Administración del personal

6Administración de recursosAdministración de recursos de computo

AMBIENTE 2,00% Adquisición del espacio de trabajo 6

Page 19: RUP-UML

FASE . FLUJOS DE TRABAJO PORCENTAJE ACTIVIDAD DIAS

FASE DE ELABORACION 22%

NEGOCIOS Y MODELAMIENTO 4,00%

Depuración del Modelo De Dominio

12Depuración del modelo de procesosDiagnostico de viabilidad del sistema

REQUERIMIENTOS 4,00%

Depuración de actividades de los actores

12

Depuración de requerimientos funcionalesDepuración de requerimientos no funcionalesDocumentación de casos de usoDepuración de la lista de casos de usoDepuración del diagrama final de casos de uso

ANALISIS Y DISEÑO 5,00%

Elaboración del Diagrama de secuencia

15

Elaboración del Diagrama de colaboraciónElaboración del diagrama de estadosElaboración de diagrama de actividadDiagrama de actividades

IMPLEMENTACION 2,00% Elaboración del diagrama de componentes inicial 6

TEST PRUEBAS 1,00%Creación de clases de prueba

3Pruebas basadas en objetosDESPLIEGUE 1,00% Elaboración del diagrama de despliegue inicial 3

CONFIGURACION Y MANTENIMIENTO 2,00%Creación de casos de uso de prueba

6Montaje de un servidor de pruebas

ADMINISTRACION

2,00%

Administración del personal

6Administración de recursosAdministración de recursos de computo

AMBIENTE 1,00% Adquisición del espacio de trabajo 3

Page 20: RUP-UML

FASE . FLUJOS DE TRABAJO PORCENTAJE ACTIVIDAD DIAS

FASE DE CONSTRUCCION

30%

NEGOCIOS Y MODELAMIENTO 2,00% Corrección de políticas con respecto a la misión y visión 6REQUERIMIENTOS 2,00% Depuración de casos de uso extendido 6

ANALISIS Y DISEÑO

4,00%

Elaboración de diagramas de clase final

12

Elaboración de diagramas de actividad finalesElaboración de diagramas de secuencia finalesElaboración de diagramas de colaboración finalesElaboración de diagramas de estado finales

IMPLEMENTACION 10,00% Elaboración de diagrama de componentes final 30TEST PRUEBAS 2,00% Pruebas basadas en escenarios 6DESPLIEGUE 1,00% Elaboración de diagrama de despliegue final 3

CONFIGURACION Y MANTENIMIENTO 5,00%

Establecimiento de un modelo de pruebas

15

Montaje de un servidor de pruebasMontaje de un servidor de control de escenariosMontaje de un servidor de control de versiones de softwarePruebas del servidor CVSMontaje de un servidor de subversionesMontaje de un servidor de pruebas

ADMINISTRACION

3,00%

Administración del personal

9Administración de recursosAdministración de recursos de computo

AMBIENTE 1,00% Mejoras locativas a la estructura física de trabajo 3

Page 21: RUP-UML

FASE . FLUJOS DE TRABAJO PORCENTAJE ACTIVIDAD DIAS

FASE DE TRANSICION 26%

NEGOCIOS Y MODELAMIENTO 0,00% 0REQUERIMIENTOS 1,00% Depuración de casos de uso extendido 3

ANALISIS Y DISEÑO 1,00%Depuración del modelo de análisis y colocación de etiquetas OCL 3

IMPLEMENTACION 4,00%

Creación de módulos de interfaz de usuario

12Creación de módulos de lógica del negocioCreación de módulos de acceso a datos

TEST PRUEBAS 3,00%

Pruebas basadas en escenarios

9

Pruebas unitarias de clasePruebas de acoplamientoPruebas de cohesiónPruebas de concurrencia

DESPLIEGUE

11,00%

Empaquetamiento de componentes de lógica de aplicación

33

Empaquetamiento de componentes de acceso a datosEmpaquetamiento de componentes de interfaz graficaDistribución de paquetes en los distintos nodos

CONFIGURACION Y MANTENIMIENTO 5,00%

Establecimiento de un modelo de pruebas

15

Montaje de un servidor de pruebasMontaje de un servidor de control de escenariosMontaje de un servidor de control de versiones de softwarePruebas del servidor CVSMontaje de un servidor de subversiones

ADMINISTRACION 1,00%

Montaje de un servidor de pruebas

3

Administración del personalAdministración de recursosAdministración de recursos de computo

Page 22: RUP-UML
Page 23: RUP-UML

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 falsasf. todas las afirmaciones de la a) a la e) son falsasg. 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ónb. 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

Page 24: RUP-UML

1. Las afirmaciones A, B, C, F y G son falsas2. La afirmación A es falsa3. 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.

Page 25: RUP-UML

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.

Page 26: RUP-UML
Page 27: RUP-UML

2. CONSIDERACIONES AL REALIZAR SU PROYECTO DE GRADO

2.1. 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 PERMITIDAS

RAZON POR LA QUE NO SE PERMITE

UNA PALABRA PROPUESTA PARA REEMPLAZARLA

Etc, entre otros. Deja entrever que existen otros elementos

Es mejor omitir la palabra y no colocar una palabra que signifique lo mismo.

Yo pienso que Dios es Bueno

En los documentos de tesis 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.

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.

Yo puedo concluir Deja entrever que la conclusión es subjetiva.

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 tesis

Las causas del fenómeno X son:

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 la tesis

Entra las causas mas visibles del fenómeno X podemos citar:

Page 28: RUP-UML

Palabra o frase que hay que sacar de una tesis

Para mi…

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 la tesis

Podemos encontrar que..

Palabra o frase que hay que sacar de una tesis

Lo dijo fulanito o “sutangano”

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 la tesis

Los siguientes autores coinciden en afirmar que

2.2. 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.

Page 29: RUP-UML

2.2. 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.3. 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.

OBJETIVO QUE NO PARECE SER OBJETIVO

RAZON POR LA CUAL NO PARECE SER

UNA FORMA ALTERNATIVA DE

1 Esta clasificacion fue tomada de http://www.virtual.unal.edu.co/cursos/enfermeria/2002847/lecciones/tematica4/subtema4-8.html

Page 30: RUP-UML

OBJETIVO COLOCAR EL OBJETIVOConstruir el sistema operativo mas pequeño.

Aunque es posible medir el 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 un sistema operativo que respecto a los actuales este entre los 10 sistemas operativos mas pequeños del mundo.

Construir el mejor sistema operativo en cuento a seguridad de ingreso.

Es posible construir este objetivo y cumplirlo 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 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 sistema bonito No existen métricas para medir lo bonito de un sistema.

Construir un procesador de textos con una apariencia similar a la del procesador de textos Start Office. <<Este un objetivo mejorado, pero le falta mejorar mas>>

Construir un sistema agradable

No existen métricas de agradabilidad.

Seria bueno suprimir este objetivo

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,

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

Page 31: RUP-UML

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

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.

Desarrollar un sistema de registro de notas que permita agilizar los procesos de preinscripción automática de notas.

Es posible que el sistema permita agilizar los procesos de preinscripción de notas, pero de ser esto lo que se quiere se debe tener en cuenta que el proceso como tal depende de otros factores y no del software en su totalidad.

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.

Desarrollar un sistema de consulta bibliotecaria

Esta bien, pero le falta mas cosas como en donde y que tipo de sistema va a ser.

Sistema intranet de consulta bibliotecaria en la Facultad Tecnológica de la Universidad Distrital

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.

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.4. 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 ESDesarrollar un editor de textos.

Page 32: RUP-UML

ALGUNOS OBJETIVOS ESPECIFICOS SERANRealizar 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 ESPECIFICOSSi 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 REDACTADOSDisenar y desarrollar una base de datos.RAZON POR LA QUE ESTA MALLas 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 REDACTADOSEntender las necesidades de la organizacionRAZON POR LA QUE ESTA MALLas necesidades son muy grandes y todas no se pueden abarcar.CORRECTO.Concretarlo mas.

2.5. 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 ESTA BIEN REDACTADO

RAZON POR LA QUE EL ALCANCE NO ESTA BIEN REDACTADO.

ALCANCE MEJORADO QUE POSIBLEMENTE FALTE DEPURARLO

El sistema alcanzara a ser el sistema mas seguro en

Es bastante osado este objetivo y esta subvalorando

Sistema que valide la entrada de los usuarios basado en el

Page 33: RUP-UML

Colombia. la capacidad de otros desarrolladores, cosa que nunca se puede hacer.

mecanismo de clave y nombre de usuario.El sistema usara cookies o 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.6. 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 PROFESION DEL QUE DIO LA SOLUCION.

LA SOLUCION NO SIEMPRE ES LA MEJOR

El señor Mario Silva no ve bien por un ojo.

Colocarle unas gafas. Oftalmólogo 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.

Page 34: RUP-UML

Mi Padre tiene problemas con su contabilidad.

Desarrollar un sistema contable para las necesidades de mi Padre.

Ingeniero de Sistemas

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:

VeracidadIdentidadIntegridadCapacidadSeguridadFiabilidadConfidencialidadAutenticaciónNo denegaciónNo repudiaciónAccesibilidad

Page 35: RUP-UML

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 PLANTEADO

SOLUCION CUALIDAD AFECTADA

PLANTEAMIENTO MEJORADO PERO EN PROCESO

El problema es que uso Excel para almacenar la información de 65536888888 clientes.

Desarrollar un sistema informático en Access.

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.

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 PLANTEADOPLANTEMIENTO DEL PROBLEMAEl problema es que la información se almacena no es veraz e integra.RAZON POR LA QUE EL PROBLEMA ESTA MAL PLANTEADOLa 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 PROBLEMANo es un problema para solucionar un profesional de la informática.

OTRO EJEMPLO DE PROBLEMA MAL PLANTEADO

PLANTEMIENTO DEL PROBLEMAEl 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 PLANTEADOEl 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

Page 36: RUP-UML

forma como se definió el problema no da para construir alternativas de solución.UN PLANTEAMIENTO NUEVO DEL PROBLEMALos 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 PROBLEMAEl problema es que la empresa usa Word para almacenar los datosRAZON POR LA QUE EL PROBLEMA ESTA MAL PLANTEADOSi 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 PROBLEMAEl 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.

NOTASe 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.

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 LABORALComponente12= ETICA

FRASE QUE ENGLOBA EL KERNEL DEL PROBLEMA.

Page 37: RUP-UML

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 actualActualmente 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 problemaMuchas personas no se capacitan para ejercer puestos en el área de la salud y sin embargo ejercen usando títulos falsos

Situación deseadaSolamente 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 temaPorque 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.

Page 38: RUP-UML

2.7. COSAS SOBRE LAS DELIMITACIONES

Recuerde que en las delimitaciones se colocan las cosas que no me comprometo a hacer.

SI EL PROYECTO ESDesarrollar 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 SERIAEsta 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.8. 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 DELIMITACION

SUBDIVISION EXPLICACION EJEMPLOS

TECNICA PLATAFORMALENGUAJEHARDWAREMODELADOINFRAESTRUCTA DE RED

OPERATIVA FORMACIONEXPERIENCIA ACADEMICAESPACIODISPOSICION

FUNCIONAL NAVEGACIONALACTORES INTERNOSESCENARIOS

GEOGRAFICATEMPORAL

2.9. 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.

Page 39: RUP-UML

SI EL PROYECTO ESDesarrollar 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 SERIACambien 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 ADesarrollar un sistema que también se pueda ejecutar en Linux.PLAN BDesarrollar el software web en un servidor externo para que pueda ser accedido usando el navegador de internet de Linux.

2.10. 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.11. COSAS SOBRE EL MARCO CONCEPTUAL

En el marco conceptual se colocan diccionario de términos raros y técnicos.

2.12. 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.

2.13. 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.

Page 40: RUP-UML

2.14. COSAS SOBRE LA FACTIBILIDAD OPERATIVA DEL PROYECTO

Es necesario observar si los usuarios del sistema tienen las habilidades necesarias para manipular el sistema.

2.15. 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:

ProductoProcesoProyectoPersonal

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.16. 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.

Page 41: RUP-UML

2.17. TALLER PROPUESTO PARA MEJORAR LA FASE DE PLANEACION DEL PROYECTO

PROFESOR: LUIS FELIPE WANUMEN SILVASegú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 aparecen en objetivo alguno, pero que usted cree que hacen parte del sistema.

Sustantivos que aparecen en el titulo

Sustantivos que aparecen en el objetivo general

Sustantivos que aparecen en los objetivos específicos

Llene la siguiente tabla:Acciones que debe desempeñar el sistema, pero que no están en el titulo, ni en el objetivo general, ni especifico.

Lista de verbos que aparecen en el titulo del proyecto

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 desempeñar el sistema, pero

Lista de verbos que aparecen en el titulo del

Empresa, sustantivo, persona, cargo,

Page 42: RUP-UML

que no están en el titulo, ni en el objetivo general, ni especifico.

proyecto departamento o similar con el que se encuentra asociada la acción de la anterior columna.

Llene la siguiente tabla:Acciones que debe desempeñar el sistema, y que se encuentran en el objetivo general del proyecto.

Acciones que debe desempeñar el sistema, y que se encuentran en los objetivos específicos 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.

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.

Llene la siguiente tabla:Lista de actores del 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.

Page 43: RUP-UML
Page 44: RUP-UML

2.18. 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 uso2. Construir el diagrama de secuencia3. Construir los diagramas de Actividad

Individual.Hora de Entrega 4:00 PMDía de entrega: 01 de Abril de 2008

Para la próxima Clase4. 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.)

Page 45: RUP-UML

3. GENERALIDADES DE UML

UML es un lenguaje que tiene elementos, relaciones y diagramas, tal como se especifica en la siguiente tabla

VISION GENERAL DE UMLElementos Elementos estructurales

Elementos de comportamientoElementos de agrupaciónElementos de anotación

RelacionesDiagramas Diagrama de casos de uso

Diagrama de clasesDiagrama de objetosDiagrama de secuenciaDiagrama de colaboraciónDiagrama de estadoDiagrama de actividadDiagrama de componentesDiagrama de despliegue

3.1. DIAGRAMAS DE CASOS DE USO

Son los encargados de documentar los requisitos de sistema a nivel general.

3.2. DIAGRAMAS DE ACTIVIDADES

Son equivalentes a los diagramas de flujo de las metodologías estructuradas y se usan para analizar procesos.

3.3. DIAGRAMAS DE CLASES

Muestran la vista estática del sistema, con sus clases y las relaciones entre las mismas.

3.4. DIAGRAMAS DE INTERACCION

En UML existen dos tipos de diagramas de interacción que son:

Page 46: RUP-UML

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.

3.5. DIAGRAMAS DE ESTADO

Muestra el estado cambiante de un solo objeto

3.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.

3.7. DIAGRAMAS DE DESPLIEGUE

Muestra una visión general que incluye los nodos que son los elementos que contienen los componentes del sistema.

4. 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

Page 47: RUP-UML

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.

4.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 FORMA DE MODELARLOMODELAMIENTO PARTE ESTATICA Modelo de DominioMODELAMIENTO PARTE DINAMICA Modelo de procesos

4.2. MODELAMIENTO DE LA SOLUCION DEL PROBLEMA

MODELAMIENTO DE SOLUCION FORMA DE MODELARLOMODELAMIENTO PARTE ESTATICA Diagrama de clases

Diagrama de estadoMODELAMIENTO PARTE DINAMICA Diagrama de casos de uso

Diagrama de secuenciaDiagrama de colaboraciónDiagrama de Actividad

4.3. MODELAMIENTO DE LA CODIFICACION DEL PROBLEMA

Page 48: RUP-UML

MODELAMIENTO DE LA CODIFICACION DEL PROBLEMA

FORMA DE MODELARLO

MODELAMIENTO PARTE ESTATICA Diagrama de ClasesDiagrama de componentesDiagrama de despliegue

MODELAMIENTO PARTE DINAMICA Diagrama de objetosDiagrama de secuenciaDiagrama de colaboraciónDiagrama de actividad

5. 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 usoDiagrama de clasesDiagrama de objetosDiagrama de secuenciaDiagrama de colaboraciónDiagrama de estadoDiagrama de actividadDiagrama de componentesDiagrama de despliegue

Y que los flujos de trabajo de RUP son:

FLUJOS DE PROCESO FLUJOS DE SOPORTEModelado del negocioRequisitosAnálisis y DiseñoImplementaciónPruebasDespliegue

Gestión del cambio y configuracionesGestión del proyectoEntorno

A continuación vamos a bosquejar los diagramas que se pueden asociar con cada uno de dichos flujos de RUP.

Page 49: RUP-UML

5.1. DIAGRAMAS USADOS EN EL FLUJO DE MODELADO DEL NEGOCIO

Teniendo en cuenta

Modelado del negocio

Requisitos Análisis y Diseño

Implementación Despliegue Pruebas

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

En alto porcentaje

Diagrama de componentesDiagrama de despliegue

Page 50: RUP-UML

5.2. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO REQUERIMIENTOS

Modelado del negocio

Requisitos Análisis y Diseño

Implementación Despliegue Pruebas

Diagrama de casos de uso

En bajo porcentaje

En alto porcentaje

Diagrama de clases

En alto porcentaje, pero diagramas de clases globales

Diagrama de objetos

Diagrama de secuencia

En bajo porcentaje

Diagrama de colaboración

Diagrama de estado

En un bajo porcentaje

Diagrama de actividad

En alto porcentaje

En un bajo porcentaje

Diagrama de componentesDiagrama de despliegue

5.3. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO ANALISIS Y DISENO

Page 51: RUP-UML

Modelado del negocio

Requisitos

Análisis y Diseño

Implementación

Despliegue

Pruebas

Diagrama de casos de uso

En bajo porcentaje

En alto porcentaje e incluyendo casos de uso extendidos

Diagrama de clases

En alto porcentaje, pero diagramas de clases generales

En alto porcentaje, incluyendo funcionalidades que no estaban en la fase de modelado del negocio.

Diagrama de objetos

En alto porcentaje, sobre todo en el flujo de diseño, mas que en el de análisis.

Diagrama de secuencia

En bajo porcentaje

En alto porcentaje

Diagrama de colaboración

En alto porcentaje

Diagrama de estado

En un bajo porcentaje

En alto porcentaje

Diagrama de actividad

En alto porcentaje

En un bajo porcentaje

En alto porcentaje

Diagrama de

Page 52: RUP-UML

componentesDiagrama de despliegue

5.4. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO IMPLEMENTACION

Modelado del negocio

Requisitos

Análisis y Diseño

Implementación

Despliegue

Pruebas

Diagrama de casos de uso

En bajo porcentaje

En alto porcentaje e incluyendo casos de uso extendidos

Diagrama de clases

En alto porcentaje, pero diagramas de clases generales

En alto porcentaje, incluyendo funcionalidades que no estaban en la fase de modelado del negocio.

Diagrama de objetos

En alto porcentaje, sobre todo en el flujo de diseño, mas que en el de análisis.

Diagrama de secuencia

En bajo porcentaje

En alto porcentaje

En alto porcentaje

Diagrama En alto En bajo

Page 53: RUP-UML

de colaboración

porcentaje porcentaje

Diagrama de estado

En un bajo porcentaje

En alto porcentaje

Diagrama de actividad

En alto porcentaje

En un bajo porcentaje

En alto porcentaje

Diagrama de componentes

En alto porcentaje

Diagrama de despliegue

5.5. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO DESPLIEGUE

Modelado del negocio

Requisitos

Análisis y Diseño

Implementación

Despliegue

Pruebas

Diagrama de casos de uso

En bajo porcentaje

En alto porcentaje e incluyendo casos de uso extendidos

Diagrama de clases

En alto porcentaje, pero diagramas de clases generales

En alto porcentaje, incluyendo funcionalidades que no estaban en la fase de

Page 54: RUP-UML

modelado del negocio.

Diagrama de objetos

En alto porcentaje, sobre todo en el flujo de diseño, mas que en el de análisis.

Diagrama de secuencia

En bajo porcentaje

En alto porcentaje

En alto porcentaje

En alto porcentaje

Diagrama de colaboración

En alto porcentaje

En bajo porcentaje

En bajo porcentaje

Diagrama de estado

En un bajo porcentaje

En alto porcentaje

Diagrama de actividad

En alto porcentaje

En un bajo porcentaje

En alto porcentaje

Diagrama de componentes

En alto porcentaje

Diagrama de despliegue

En alto porcentaje

5.6. DIAGRAMAS USADOS EN EL FLUJO DE TRABAJO PRUEBAS

Modelado del negocio

Requisitos

Análisis y Diseño

Implementación

Despliegue

Pruebas

Diagrama En bajo En alto En alto

Page 55: RUP-UML

de casos de uso

porcentaje

porcentaje e incluyendo casos de uso extendidos

porcentaje

Diagrama de clases

En alto porcentaje, pero diagramas de clases generales

En alto porcentaje, incluyendo funcionalidades que no estaban en la fase de modelado del negocio.

En alto porcentaje

Diagrama de objetos

En alto porcentaje, sobre todo en el flujo de diseño, mas que en el de análisis.

En alto porcentaje

Diagrama de secuencia

En bajo porcentaje

En alto porcentaje

En alto porcentaje

En alto porcentaje

En alto porcentaje

Diagrama de colaboración

En alto porcentaje

En bajo porcentaje

En bajo porcentaje

En alto porcentaje

Diagrama de estado

En un bajo porcentaje

En alto porcentaje

En alto porcentaje

Diagrama de actividad

En alto porcentaje

En un bajo porcentaje

En alto porcentaje

En alto porcentaje

Diagrama de componentes

En alto porcentaje

En alto porcentaje

Diagrama de

En alto porcentaj

En alto porcenta

Page 56: RUP-UML

despliegue e je

Page 57: RUP-UML

6. 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]

6.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]

6.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]

Page 58: RUP-UML

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.

6.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.

6.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]

6.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

Page 59: RUP-UML

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.

6.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 OCL7. OCL ayuda a que los modelos UML tengan coherencia.

6.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 .

Page 60: RUP-UML
Page 61: RUP-UML

7. 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.

7.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:

Captura de quejas del cliente

Envio de quejas a la empresa

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

Page 62: RUP-UML

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:

Evaluacion de quejas no atendidas

Almacenamiento de quejas de clientes

Solicitud de envio de queja a Empresa

Envio de quejas a la empresa

Captura de quejas del cliente

Seguimiento de queja expuesta por el ClienteEvaluacion de quejas 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.

Page 63: RUP-UML

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:

Envio de quejas a la empresa

funcionario

Captura de quejas del cliente

Cliente

Solicitud de envio de queja a Empresa

Almacenamiento de quejas de clientes

sistema

Seguimiento de queja expuesta por el Cliente

Evaluacion de quejas no atendidas

auditorInterno

Evaluacion de quejas atendidas

7.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:

Page 64: RUP-UML

Relaciones ExtendsRelaciones Include yRelaciones de generalización.

En las siguientes secciones se explicaran cada una de estas tres.

7.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:

Envio de quejas a la empresa

ClienteSolicitud de envio de queja a

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ísicoQuejas 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:

Page 65: RUP-UML

Solicitud de envio de queja

Enviar quejas de maltrato fisico

Envia quejas de maltrato psicologico

Envio de quejas

<<<<extends>>>>

<<<<extends>>>>

Cliente

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:

Page 66: RUP-UML

Solicitud de envio de queja

Enviar quejas de maltrato fisico

Envia quejas de maltrato psicologico

Envio de quejas de maltrato

<<<<extends>>>>

<<<<extends>>>>

Cliente

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:

Page 67: RUP-UML

solicitar envio de queja

enviar quejas de maltrato fisico

enviar quejas de maltrato psicologico

enviar quejas de maltrato

<<<<extends>>>>

<<<<extends>>>>

Cliente

Page 68: RUP-UML

7.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

Envio de quejas de maltrato

Enviar quejas de maltrato fisico<<<<extends>>>>

Cliente

Envia quejas de maltrato psicologico

<<<<extends>>>>

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:

Page 69: RUP-UML

Solicitud de envio de queja

Envia quejas de maltrato psicologico

ClienteEnvio de quejas de maltrato

<<<<extends>>>>

Funcionario

Enviar quejas de maltrato fisico<<<<extends>>>>

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:

Page 70: RUP-UML

Solicitud de envio de queja a Empresa

Envia quejas de maltrato psicologico a clientes

ClienteEnvio de quejas de maltrato a clientes

Enviar quejas de maltrato fisico a clientes

FuncionarioEnviar quejas de maltrato fisico a

funcionarios

Envio de quejas de maltrato a funcionarios

<<<<extends>>>>

<<<<extends>>>>

<<<<extends>>>>

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.

7.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:

Page 71: RUP-UML
Page 72: RUP-UML

solicitar envio de queja

enviar quejas de maltrato fisico a clientes

enviar quejas de maltrato psicologico a clientes

enviar quejas de maltrato a clientes<<<<extends>>>>

<<<<extends>>>>

Cliente

enviar quejas de maltrato fisico a funcionarios

enviar quejas de maltrato psicologico a funcionarios

enviar quejas de maltrato a funcionarios

<<<<extends>>>>

<<<<extends>>>>

Funcionario

enviar quejas de maltrato fisico a auditores

enviar quejas de maltrato psicologico a auditores

enviar quejas de maltrato a auditores

<<<<extends>>>>

<<<<extends>>>>

Auditor

Page 73: RUP-UML
Page 74: RUP-UML

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 psicologico

enviar quejas de maltrato fisico

enviar quejas de maltrato psicologico a auditores

Auditor

enviar quejas de maltrato fisico a auditores

enviar quejas de maltrato psicologico a funcionarios

Funcionario

enviar quejas de maltrato fisico a funcionarios

enviar quejas de maltrato psicologico a clientes

Cliente

enviar quejas de maltrato fisico a clientes

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:

Page 75: RUP-UML

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.

7.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:

Caso de USO A

Caso de USO B

Caso de USO XACTOR

<<<<include>>>>

<<<<include>>>>

Diagrama NO VALIDO

No son validos, al igual que tampoco son validos diagramas como el siguiente:

Page 76: RUP-UML

Diagrama NO VALIDO

Caso de USO A

Caso de USO B

ACTORvalidar usuario

<<<<include>>>>

<<<<include>>>>

En tanto que diagramas como los siguientes si son validos:

Diagrama VALIDO

validar usuario

Caso de USO A

ACTOR

Caso de USO B

<<<<include>>>>

<<<<include>>>>

Y no esta demás recordar que diagramas de casos de uso como los siguientes:

Page 77: RUP-UML

Caso de USO X

Diagrama NO VALIDOCaso de USO A

<<<<extends>>>>

ACTOR

Caso de USO B

<<<<extends>>>>

No son validos, en tanto que diagramas como los siguientes:

Diagrama VALIDO

Caso de USO A

Caso de USO B

ACTOR Caso de USO X

<<<<extends>>>>

<<<<extends>>>>

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.

7.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>>:

Page 78: RUP-UML

Diagrama VALIDO

validar usuario

Consultar Cliente

funcionario

Matricular Cliente

<<<<include>>>>

<<<<include>>>>

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:

Diagrama NO VALIDO

validar usuario

Consultar Cliente

funcionario

Matricular Cliente

<<<<include>>>>

<<<<include>>>>

7.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:

Page 79: RUP-UML

BACTORA

<<<<include>>>>CASO DE USO ABSTRACTO

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:

ACTOR AA

CASO DE USO CONCRETO

ACTOR B

B

<<<<include>>>>

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”.

7.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.

Page 80: RUP-UML

A continuación se muestra una plantilla sugerida para documentar casos de uso

Numero del caso de uso

<<Nombre del Caso de Uso.>>Ejemplo:

<<Numero>>

Ingresar estudiante

Cabecera del caso de uso

<<Id del requisito funcional>>

<<Nombre del requisito funcional>>

Ejemplo:

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

<<Versión>> <<Numero de versión y fecha>>

Ejemplo:Version 1.3 del 14 de abril de 2008

<<Autores>> <<Autor>>

Ejemplo:

Luis Felipe Wanumen Silva y Juan Carlos Guevara BolañosTipo de Caso de USO

Abstracto No Abstracto X

Fuentes <<Fuente de la versión actual>>

Ejemplo:

Documento almacenado en http://www.udistrital.edu.co/facultados.tecnologica/documento1.doc

Estado del documento

DEFINITIVO

Evento de Activación

<<Nombre del evento de 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.

Page 81: RUP-UML

<<Objetivo general del caso de uso>>

<<Nombre del objetivo general>>

Ejemplo:

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.

<<Objetivos específicos>>

<<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 caso de Uso

<<Numero modal en el que los actores o entidades son afectadas>>

Ejemplo:

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.

Descripción: 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 matricula de estudiantes ingresando los datos personales, económicos, sociales y académicos de los nuevos y futuros estudiantes de la Universidad.

Actores <<Listado de actores>>

Ejemplo:Administrador, profesor, estudiante

Objetivo <<Objetivo en infinitivo>><<elementos que se ven afectados por el verbo incluyendo actores o estados del sistema>>

Page 82: RUP-UML

Ejemplo:Registrar en la base de datos un estudiante

Precondiciones

<<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.

Pos condiciones

<<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

Flujo de Eventos o secuencia Normal de acciones.

<<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<<Identificación del paso>>

<<acción a realizar o situación que produce una alternativa, mostrando las alternativas para este ultimo caso>>

<<Actor>>. Especificando si es una acción o una respuesta de algún agente del sistema.

Ejemplo: Ejemplo:Si << situación que produce una alternativa>>, el sistema deberá <<acción a realizar>>

Ejemplo:

1 Digitar todos los datos del estudiante Actividades del Actor

Ejemplo:

2

Ejemplo:

Validar formulario2a. 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.

- - - - - - - - - -

Ejemplo:

Invocada por el actor e implementada por el sistema

Page 83: RUP-UML

Ejemplo:

2

Ejemplo:

Almacenar los datos en la base de datos

Ejemplo:

Respuesta del Sistema

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

N - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Flujos alternos

1 - - - - - - - - - - - - - - - - - - - - - - - - - - - -2 - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -N - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Situaciones Anormales

<<Recuerde que en esta parte de la documentación se pretende modelar el 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 LA EXCEPCION.<<Actor, entidad o sistema que es capaz de atrapar la excepcion>>

Ejemplo:

Page 84: RUP-UML

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 <<Recuerde que toda acción es acción si cambia el estado de alguna entidad

Page 85: RUP-UML

estado 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.

Rendimiento

Paso Cota de tiempo

Ejemplo: Ejemplo:1 N segundos2 N segundos

Frecuencia esperada

<<No de veces>>veces <<unidad de tiempo>>

Importancia <<sin importancia o importancia vital>>. (Recuerde “o” excluyente)

Urgencia <<Puede esperar, hay presión, inmediatamente>>

Comentarios

<<Comentarios adicionales>>

Periodicidad

Page 86: RUP-UML

8. 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.

8.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

Page 87: RUP-UML

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:

8.2. GENERALIZACIÓN VS HERENCIA

Supongamos el siguiente diagrama de clase:

MATERIA

COD_MAT : IntegerNOM_MAT : String

ASIGNATURA

COD_ASIG : IntegerNOM_ASIG : String

La implementación de dicho diagrama de clase se hace en dos archivos, los cuales se muestran a continuación:

TIPOS DE RELACIONES

Relaciones de DEPENDENCIA

Relaciones de GENERALIZACIÓN

Relaciones de ASOCIACIÓN

Page 88: RUP-UML

// 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.

8.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 {

Page 89: RUP-UML

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 MATERIAInteger cod_materia = obj_materia.getCOD_MAT();1 error

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:

Page 90: RUP-UML

getCOD_MAT() has private access in MATERIAIntege codigo_mat = getCOD_MAT();1 errors

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 MATERIAInteger cod_asignatura = ojb_asignatura.getCOD_MAT();1 errors

8.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

Page 91: RUP-UML

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);

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);

8.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

Page 92: RUP-UML

subclase en el mismo paquete N S S Sotras clases en el mismo paquete N S S Ssubclases en otros paquetes N X S Notras 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

8.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:

ASIGNATURA

COD_ASIGN : IntegerNOM_ASIGN : String

ESTUDIANTE

COD_ESTU : IntegerNOM_ESTU : String

0..35

0..6

+inscribe+tomada_por

0..35

0..6

INSCRIPCION

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.

Page 93: RUP-UML

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() { }}

8.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:

Page 94: RUP-UML

MONITOR

COD_MON : IntegerNOM_MON : String

TECLADO

COD_TECL : IntegerNOM_TECL : String

CPU

COD_CPU : IntegerNOM_CPU : String

IMPRESORA

CO_IMPR : IntegerNOM_IMP : String

COMPUTADOR

COD_COMP : IntegerNOM_COMP : String

1..1

+envia1

+envia3

+envia2

+envia4

+muestra

+manipula

+procesa

+imprime

MUESTRA PROCESA

MANIPULA

IMPRIME

1..1

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 MONITOR muestra; public TECLADO manipula; public CPU procesa; public 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

Page 95: RUP-UML

• 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;

Page 96: RUP-UML

TECLADO() { }}

Un TECLADO está relacionado con cero o un COMPUTADOR por medio del rol envia3

8.8. RELACIONES DE DEPENDENCIA

NOTA

COD_NOTA : IntegerVALOR_NOTA : IntegerDESCRIPCION : String

ESTUDIANTE

COD_ESTU : IntegerNOM_ESTU : String

CALIFICACION

0..n

1..1

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() {

Page 97: RUP-UML

}}

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:

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.

8.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.

COORDINACIÓN COORDINADOR

Dependencia

Page 98: RUP-UML

9. 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.

9.1. LAS CLASES CON ESTEREOTIPO VIEW

Clases como la siguiente:

ConsultaEstudiantesExcelentes

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:

ConsultaEstudiantesExcelentes

<<<<View>>>>

9.2. LAS CLASES CON ESTEREOTIPO TABLE

Clases como la siguiente:

Estudiante

Page 99: RUP-UML

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:

Estudiante<<<<Table>>>>

9.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>>.

Estudiante<<<<Service>>>>

9.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

Page 100: RUP-UML

O también se pueden diagramar así:

Estudiante<<<<Resource>>>>

9.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 EXPLICACION

Estudiante

Estudiante<<<<Physical Worker>>>>Trabajador

físico

Edificio

Edificio<<<<Location>>>> Clase que

especifica una localización

Edificio

Edificio<<<<Interface>>>> Interface

Edificio<<<<entity>>>> Entity.

Especifica que es una

Page 101: RUP-UML

Edificio

entidad.

Mundo

Mundo<<<<Domain>>>> Domain.

Generalmente son clases que aparecen en el dominio del problema.

Mundo

Mundo<<<<control>>>> Control

Mundo

Mundo<<<<Business Worker>>>>Business

Worker

Mundo

Mundo<<<<Business Goal>>>> Business

Goal. Meta de negocio

Page 102: RUP-UML

Mundo

Mundo<<<<Business Event>>>> Business

Event. Evento de negocio.

Mundo

Mundo<<<<Business Entity>>>>Business

Entity. Entidad e negocio.

Mundo

Mundo<<<<Business Document>>>>Business

Document. Documento de negocio

Mundo

Mundo<<<<Business Actor>>>> Business

Actor. Actor de negocio

Mundo

Mundo<<<<boundary>>>> Boundary

Page 103: RUP-UML

Mundo

Mundo<<<<Actor>>>> Actor. Esta

clase es mas comúnmente modelada con la figura similar a la humana

Page 104: RUP-UML

10. P.O.O. EN JAVA Y CLASES ABSTRACTAS

10.1. LAS CLASES ABSTRACTAS

TIPO DE CLASE COMO UTILIZARLAabstract Extendsinterface 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");}

}

Page 105: RUP-UML

Observe el amigo lector que la implementación del método “printf()” es obligatoria en la clase “MyApp”

10.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 errorExit code: 1There 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.

10.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{

Page 106: RUP-UML

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

10.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

Page 107: RUP-UML

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.

10.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{

Page 108: RUP-UML

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.

10.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.

Page 109: RUP-UML

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

10.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.

Page 110: RUP-UML

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{

Page 111: RUP-UML

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()”.

10.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.

Page 112: RUP-UML

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

10.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.

Page 113: RUP-UML

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

11. P.O.O. EN JAVA Y LAS INTERFACES

Como decíamos en secciones anteriores:

TIPO DE CLASE COMO UTILIZARLAAbstract ExtendsInterface 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:

Page 114: RUP-UML

// 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();}

11.1. LAS INTERFACES DEBEN INICIALIZAR SUS ATRIBUTOS

El siguiente código es correcto

// Esta clase no genera errorpublic 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 ERRORpublic interface transporte{ public int posicion_x; public int posicion_y; } // Cierra interface transporte

Page 115: RUP-UML

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.

11.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 errorpublic interface transporte{ public int posicion_x=2; int posicion_y=0; } // Cierra interface transporte

11.3. EL MODIFICADOR DE ATRIBUTO POR DEFECTO ES PUBLIC EN LAS INTEFACES

En el siguiente código:

// Esta clase no genera un errorpublic 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”.

11.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

Page 116: RUP-UML

public interface transporte{ public int posicion_x=2; // genera error por tener el // modificador protected protected int posicion_y=0; } // Cierra interface transporte

11.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 ERRORpublic 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.

11.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: Luis Felipe Wanumen Silva Tipo: Orientación a objetos

Page 117: RUP-UML

Clase: Interface Descripción: 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 errorpublic 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// transportetransporte zorra = new transporte();

}}

11.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:

Page 118: RUP-UML

/* Autor: Luis Felipe Wanumen Silva Tipo: Orientación a objetos Clase: Interface Descripción: 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 errorpublic interface transporte{ public int posicion_x=2; public int posicion_y=0; } // Cierra interface transporte

// Esta clase se crea correctamentepublic 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 OBJETOvaca pintada = new vaca();

}

public static void main(String args[]){

System.out.println("Starting App");MyApp f = new MyApp();f.setSize(100,100);f.show();

}}

11.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

Page 119: RUP-UML

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: Luis Felipe Wanumen Silva Tipo: Orientación a objetos Clase: Interface Descripción: 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 errorpublic 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 interfazpublic 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.

Page 120: RUP-UML

11.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: Luis Felipe Wanumen Silva Tipo: Orientación a objetos Clase: Interface Descripción: 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 errorpublic 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// interfazpublic 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();

Page 121: RUP-UML

}}

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”.

11.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: Luis Felipe Wanumen Silva Tipo: Orientación a objetos Clase: Interface Descripción: 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 errorpublic interface transporte{ public int posicion_x=2; public int posicion_y=0; } // Cierra interface transporte

// Esta clase no genera un errorpublic 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();

Page 122: RUP-UML

System.exit(0);}

});// NO HAY PROBLEMA CREANDO OBJETO PINTADAvaca 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.

11.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: Luis Felipe Wanumen Silva Tipo: Orientación a objetos

Page 123: RUP-UML

Clase: Interface Descripción: 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 errorpublic interface transporte{ public int posicion_x=2; public int posicion_y=0; } // Cierra interface transporte

// Esta clase no genera un errorpublic interface animal{ public String tipo="mamifero";} // Cierra interface animal

// ESTA CLASE NO GENERA UN ERRORpublic 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();

}}

11.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

Page 124: RUP-UML

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: Luis Felipe Wanumen Silva Tipo: Orientación a objetos Clase: Interface Descripción: 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 errorpublic 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// INTERFACEpublic 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();

}}

Page 125: RUP-UML

11.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: Luis Felipe Wanumen Silva Tipo: Orientación a objetos Clase: Interface Descripción: 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 errorpublic interface transporte{ public int posicion_x=2; public int posicion_y=0; } // Cierra interface transporte

// Esta clase no genera un errorpublic 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 correctamenteanimal vaca = new animal();

// No se puede asignar valor a variable// de tipo finalvaca.posicion_x = 3;

}

public static void main(String args[]){

System.out.println("Starting App");MyApp f = new MyApp();f.setSize(100,100);f.show();

}}

Page 126: RUP-UML

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: Luis Felipe Wanumen Silva Tipo: Orientación a objetos Clase: Interface Descripción: 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 errorpublic interface transporte{ public int posicion_x=2; public int posicion_y=0; public void moverse();} // Cierra interface transporte

// Esta clase no genera un errorpublic 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");

Page 127: RUP-UML

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

11.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: Luis Felipe Wanumen Silva Tipo: Orientación a objetos Clase: Interface Descripción: 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 errorpublic interface transporte{ public int posicion_x=2; public int posicion_y=0; public void moverse();} // Cierra interface transporte

// Esta clase no genera un errorpublic class animal implements transporte{ public String tipo="mamifero";

// SE REQUIERE QUE AQUI SE HUBIESE // IMPLEMENTADO EL MÉTODO moverse() } // Cierra interface animal

public MyApp(){

Page 128: RUP-UML

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: Luis Felipe Wanumen Silva Tipo: Orientación a objetos Clase: Interface Descripción: 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 errorpublic interface transporte{ public int posicion_x=2; public int posicion_y=0; public void moverse();} // Cierra interface transporte

// Esta clase no genera un errorpublic 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

Page 129: RUP-UML

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();

}}

12. 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.

Page 130: RUP-UML

12.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.

12.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;

Page 131: RUP-UML

} 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 ).

12.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; // ámbito exterior { // crea un nuevo ámbito int i = 2; // error de compilación } }

12.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:

Page 132: RUP-UML

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.

12.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(); }

12.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; // no se ha asignado todavia s = new String( "abc" ); // memoria asignada s = "def"; // se ha asignado nueva memoria // (nuevo objeto)

Page 133: RUP-UML

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.

Page 134: RUP-UML

13. EJERCICIO DEL PIRATA RESULADO DE LA PRIMERA ITERACION CON RUP

13.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.

13.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.

Page 135: RUP-UML

13.3. ESTABLECIMIENDO DE CLASES

pirata

pos_x : int = nullpos_y : int = nullpeso : int = 75estado_vida : boolean = true

moverse(int, int) : voiddejarse_ahogar: void()

mar

ahogados : int = 0

ahogar(pirata) : void

MyApp

grilla : GridLayout = newborde : BorderLayout = newpaneles : panel[][] = newgp : Graphics = newactual_x : int = nullactual_y : int = nullsuperior : Panel = newarriba : Panel = newinferior : Panel = newta : TextArea = newt1 : TextField = newIngSistemas : pirata = newRampa : rampa = newMar : mar = newsalvado : boolean = falseBarco : barco = newMuelle : muelle = new

paint(Graphics) : voidinit() : voidkeyDown(Event, int) : boolean

muelle

peso_actual : int = 70peso_cadena : String = ""

informar_peso: void()

barco

mensaje : String = ""

salvar_pirata: void()

rampa

pos_x : int = 0pos_y : int = 0mensaje : String = "El Muelle Habla"

validar_salida(int, int) : voidinformar_caer_al_mar: void()

Page 136: RUP-UML

13.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

Page 137: RUP-UML

} // 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{

Page 138: RUP-UML

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){

Page 139: RUP-UML

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

Page 140: RUP-UML

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

Page 141: RUP-UML

13.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:

Page 142: RUP-UML

Pero si el usuario lo deja desbordarse por la derecha o por la izquierda, aparecerá una pantalla similar a la siguiente:

Page 143: RUP-UML

Con lo cual se indica que efectivamente se ha caido el pirata al mar y por supuesto se ha ahogado.

Page 144: RUP-UML

14. EJERCICIO DEL AVION

14.1. DIAGRAMA DE CLASE

rectangulo

h : Graphics = nullposx : int = nullposy : int = nullancho : int = nullalto : int = nullrectangulillo : int[][] = new

rectangulo()devolver_grafica: int[][]()posicion_derecha: int()posicion_superior: int()posicion_inferior: int()posicionar(rectangulo) : voidactualizar_rectangulo(int int int int) : voidalargar: void()adelgazar: void()

triangulo

posx : int = nullposy : int = nullposx1 : int = nullposy1 : int = nullposx2 : int = nullposy2 : int = nullpos : int[][] = newalto : int = null

devolver_grafica: int[][]()ajustarse(String) : voidajustarse(String, rectangulo) : voidtriangulo()

MyApp

tablero : canvitas = newavioncito : avion = new

MyApp()main()

canvitas

gra : Graphics = nullpintar : int = 0puntos : int = nullapariciones : int = 100referencia_avion : avion = null

pintar(avion) : voidpaint(Graphics) : void

1..1

1..1

1..1

1..1

avion

h : Graphics = nullx : int = 150y : int = 400cuerpo : rectangulo = newcola : rectangulo = newala_superior : triangulo = newala_inferior : triangulo = newpunta : triangulo = newmatriz : int[][] = new int[17][4]colita : int[][] = nullcuerpito : int[][] = nullpuntica : int[][] = nullalita_arriba : int[][] = nullalita_abajo : int[][] = newtrompita : int[][] = new

alejarse() : voidascender()devolver_grafica() : int[][]moverse()avion()

Page 145: RUP-UML

14.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;

Page 146: RUP-UML

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;

Page 147: RUP-UML

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

Page 148: RUP-UML
Page 149: RUP-UML

canvitas.javaimport 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);

Page 150: RUP-UML

apariciones--; } // Cierra while

} // Cierra public void paint} // Cierra class canvitas

MyApp.javaimport 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

Page 151: RUP-UML

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] = posx; rectangulillo[1][1] = posy; rectangulillo[1][2] = posx; rectangulillo[1][3] = posy+alto;

rectangulillo[2][0] = posx+ancho; rectangulillo[2][1] = posy; rectangulillo[2][2] = posx+ancho; rectangulillo[2][3] = 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;

Page 152: RUP-UML

} // 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

Page 153: RUP-UML

import java.applet.*;

public class triangulo{ int posx; int posy; int posx1; int posy1; int posx2; int posy2; int pos[][] = new int[3][4]; int alto;

public int[][] devolver_grafica(){ pos[0][0] = posx; pos[0][1] = posy; pos[0][2] = posx1; pos[0][3] = posy1;

pos[1][0] = posx; pos[1][1] = posy; pos[1][2] = posx2; pos[1][3] = posy2;

pos[2][0] = posx1; pos[2][1] = posy1; pos[2][2] = posx2; pos[2][3] = 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;

Page 154: RUP-UML

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(){

Page 155: RUP-UML

} // Cierra triangulo } // Cierra class triangulo

14.3. EJECUCIÓN DEL PROGRAMA

Inicialmente el programa aparece el avión de la siguiente manera:

Page 156: RUP-UML

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.

Page 157: RUP-UML

15. 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.

15.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);

Page 158: RUP-UML

} // 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

Page 159: RUP-UML

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 Valorparametro1 1parametro2 2parametro3 3parametro4 4

estado 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 = 10; parametro2 = 20; parametro3 = 30; parametro4 = 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”:

Page 160: RUP-UML

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 Valorparametro1 1parametro2 2parametro3 3parametro4 4

estado 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 Valor

Page 161: RUP-UML

parametro1 10parametro2 20parametro3 30parametro4 40

estado 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 Valorparametro1 1parametro2 2parametro3 3parametro4 4

estado 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

Page 162: RUP-UML

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.javaDescripcion : 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] : No hay revisiones por el momento.Agradecimientos : No hayD.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){

Page 163: RUP-UML

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()

Page 164: RUP-UML

{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 AppParametros de Original Parametro 1 = 1Parametro 2 = 2Parametro 3 = 3Parametro 4 = 4Estado = trueParametros de Original Parametro 1 = 10Parametro 2 = 20Parametro 3 = 30Parametro 4 = 40Estado = falseCopiando objetoParametros de Destino Parametro 1 = 10Parametro 2 = 20Parametro 3 = 30Parametro 4 = 40Estado = false

En el cual queda claro que los datos del objeto “original” eran inicialmente los siguientes:

OBJETO “ORIGINAL”PARÁMETRO VALOR

parametro1 1parametro2 2

Page 165: RUP-UML

parametro3 3parametro4 4

Estado true

Se modificaron artesanalmente los datos del objeto en cuestión y se obtuvieron los siguientes datos:

OBJETO “ORIGINAL”PARÁMETRO VALOR

parametro1 10parametro2 20parametro3 30parametro4 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”PARÁMETRO VALOR

parametro1 10parametro2 20parametro3 30parametro4 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.

Page 166: RUP-UML

15.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.javaDescripcion : 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] : No hay revisiones por el momento.Agradecimientos : No hayD.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(){

Page 167: RUP-UML

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(); }

Page 168: RUP-UML

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 AppParametros de Original Parametro 1 = 1Parametro 2 = 2Parametro 3 = 3Parametro 4 = 4Estado = trueParametros de Original

Page 169: RUP-UML

Parametro 1 = 10Parametro 2 = 20Parametro 3 = 30Parametro 4 = 40Estado = falseCopiando objetoParametros de Destino Parametro 1 = 10Parametro 2 = 20Parametro 3 = 30Parametro 4 = 40Estado = falseExit code: 0

15.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.javaDescripcion : 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] : No hay revisiones por el momento.Agradecimientos : No hayD.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;

Page 170: RUP-UML

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");

Page 171: RUP-UML

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);

}});

Page 172: RUP-UML

} // 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 AppParametros de Original Parametro 1 = 1Parametro 2 = 2Parametro 3 = 3Parametro 4 = 4Estado = trueATRIBUTOS DEL OBJETO INTERNOp1 = 11p2 = 22p3 = 33Parametros de Original Parametro 1 = 10Parametro 2 = 20Parametro 3 = 30Parametro 4 = 40Estado = falseATRIBUTOS DEL OBJETO INTERNOp1 = 111p2 = 222p3 = 333Copiando objetoParametros de Destino Parametro 1 = 10Parametro 2 = 20Parametro 3 = 30Parametro 4 = 40Estado = falseATRIBUTOS DEL OBJETO INTERNOp1 = 111p2 = 222p3 = 333Exit code: 0

Page 173: RUP-UML

Con lo cual vemos que los valores del subojeto eran inicialmente:

p1 = 11p2 = 22p3 = 33

y fueron modificados intencionalmente por los siguientes en su objeto “ORIGEN”:

p1 = 111p2 = 222p3 = 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.

Page 174: RUP-UML

16. 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”.

16.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

Page 175: RUP-UML

16.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

16.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);

Page 176: RUP-UML

16.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 );

16.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);

Page 177: RUP-UML

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; }

Page 178: RUP-UML

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:

Page 179: RUP-UML

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”.

16.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:

Page 180: RUP-UML

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?

Page 181: RUP-UML

17. COMO DELEGAR CLASES

17.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:

MAMIFERO

expresarse()caminar()

ANIMAL

expresarse()caminar()

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

Page 182: RUP-UML

MAMIFERO

expresarse()caminar()Mamifero()

ANIMAL

expresarse()caminar()

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:

MAMIFERO

expresarse()caminar()Mamifero()

ANIMAL

expresarse()caminar()

PERRO

Page 183: RUP-UML

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:

MAMIFERO

expresarse()caminar()Mamifero()

ANIMAL

expresarse()caminar()

PERRO

expresarse()caminar()

HUMANO

expresarse()caminar()

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:

Page 184: RUP-UML

MAMIFERO

expresarse()caminar()Mamifero()toPerro()toHombre()

ANIMAL

expresarse()caminar()

PERRO

expresarse()caminar()

HUMANO

expresarse()caminar()

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(); }

17.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.javapublic interface Animal { void expresarse(); void caminar();}

Archivo Hombre.java

Page 185: RUP-UML

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.javapublic class Main {

public static void main(String[] args) { Mamifero c = new Mamifero(); c.expresarse(); c.caminar(); c.toHombre(); c.expresarse(); c.caminar();

}}

Archivo Mamifero.javapublic 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(); }

}

Page 186: RUP-UML

Archivo Perro.java

El cual al ser ejecutado arroja unos resultados similares a los siguientes:

Perro expresandose ladrandoPerro caminando en DOS PATASHombre expresarse hablandoHombre 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 ladrandoPerro 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 hablandoHombre caminando en DOS PIES

17.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?

Page 187: RUP-UML

18. 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.

18.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:

Ahora, imaginémonos que han transcurrido 2 anos y el objeto tiene 3 amigos, tendríamos entonces la siguiente situación:

Pensemos que queremos almacenar el estado del objeto en el tiempo 2. Gráficamente tendríamos la siguiente situación:

Int edad = 0;String nombre = “Hugo”;Int numeroAmigos=0

Int edad = 0;String nombre = “Hugo”;Int numeroAmigos=0

Int edad = 2;String nombre = “Hugo”;Int numeroAmigos=0

Tiempo 0NO ALMACENADO

Tiempo 2NO ALMACENADO

Int edad = 0;String nombre = “Hugo”;Int numeroAmigos=0

Int edad = 2;String nombre = “Hugo”;Int numeroAmigos=3

Tiempo 0NO ALMACENADO

Tiempo 2ALMACENADO

Page 188: RUP-UML

Pensemos que transcurridos 5 anos, el objeto tiene 6 amigos, situación que puede verse gráficamente como se muestra a continuación:

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:

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.

Int edad = 0;String nombre = “Hugo”;Int numeroAmigos=0

Int edad = 2;String nombre = “Hugo”;Int numeroAmigos=3

Tiempo 0NO ALMACENADO

Tiempo 2ALMACENADO

Int edad = 5;String nombre = “Hugo”;Int numeroAmigos=6

Tiempo 5NO ALMACENADO

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 0NO ALMACENADO

Tiempo 2ALMACENADO

Tiempo 5NO ALMACENAO

RECUPERADO DEL TIEMPO 2

Page 189: RUP-UML

18.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.javaimport java.io.*;public interface InterfazSerializable extends Serializable{}

Y posteriormente el objeto que implementa esta interfaz:

Archivo ClaseSerializable.javapublic 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; } }

Page 190: RUP-UML

En términos de UML tenemos la siguiente situación:

ClaseSerializable

int edadString nombreint numeroAmigos

crecer(int valor)imprimirDatosClase()conseguirAmigos(int numero)

InterfazSerializable

<<Serializable>>

Ahora tan solo resta mostrar el programa que crea un objeto de la clase “ClaseSerializable” lo usa:

Archivo MyApp1.javaimport 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);

Page 191: RUP-UML

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 0NO ALMACENADO

Tiempo 2ALMACENADO

Tiempo 5NO ALMACENAO

RECUPERADO DEL TIEMPO 2

Page 192: RUP-UML

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 objetoedad = 0nombre = HugonumeroAmigos = 0Transcurridos dos anos el objeto ha crecidoy ha conocido 3 amigosedad = 2nombre = HugonumeroAmigos = 3Escribimos el objeto en archivo.txtTranscurridos 5 anos el objeto ha crecidoy ha conocido 6 amigosedad = 5nombre = HugonumeroAmigos = 6Recuperamos el objetoImprimimos objeto recuperadoedad = 2nombre = HugonumeroAmigos = 3Exit code: 0No Errors

En donde se observa que los datos iniciales del objeto eran:

Datos iniciales del objetoedad = 0nombre = HugonumeroAmigos = 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();

Page 193: RUP-UML

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 crecidoy ha conocido 3 amigosedad = 2nombre = HugonumeroAmigos = 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

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 = 5nombre = HugonumeroAmigos = 6

edad = 2nombre = HugonumeroAmigos = 3

DATOS ALMACENADOS

USANDO SERIALIZACION

Page 194: RUP-UML

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:

18.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:

ClaseSerializable

int edadString nombreint numeroAmigos

crecer(int valor)imprimirDatosClase()conseguirAmigos(int numero)

InterfazSerializable

<<Serializable>>

edad = 2nombre = HugonumeroAmigos = 3

DATOS RECUPARADOS

DE LA SERIALIZACION

Page 195: RUP-UML

Y se declarará de tipo “transient”, con lo cual nuestro diagrama de clases toma la siguiente forma:

ClaseSerializable

int edadString nombretransient int numeroAmigos

crecer(int valor)imprimirDatosClase()conseguirAmigos(int numero)

InterfazSerializable

<<Serializable>>

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:

Page 196: RUP-UML

Archivo InterfazSerializable.javaimport 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.javaimport 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();

Page 197: RUP-UML

// 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 objetoedad = 0nombre = HugonumeroAmigos = 0Transcurridos dos anos el objeto ha crecidoy ha conocido 3 amigosedad = 2nombre = HugonumeroAmigos = 3Escribimos el objeto en archivo.txtTranscurridos 5 anos el objeto ha crecidoy ha conocido 6 amigosedad = 5nombre = HugonumeroAmigos = 6Recuperamos el objetoImprimimos objeto recuperadoedad = 2nombre = HugonumeroAmigos = 0Exit code: 0No Errors

Page 198: RUP-UML

En donde es claro que a pesar que el objeto “objeto1” se guardo cuando tenía los siguientes valores:

edad = 2nombre = HugonumeroAmigos = 3

También es cierto que al deserializarse se obtienen los siguientes datos:

edad = 2nombre = HugonumeroAmigos = 0

Lo que indica que el atributo “numeroAmigos” no fue almacenado en el momento de la serialización

18.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 = 0nombre = HugonumeroAmigos = 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 = 2nombre = HugonumeroAmigos = 3

Page 199: RUP-UML

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 = 5nombre = HugonumeroAmigos = 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:

Page 200: RUP-UML

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:

Page 201: RUP-UML

PRENATAL

BEBE

NINO

Aunque para el caso del programa que ya hicimos y que mostramos anteriormente tan solo podemos finalizar si somos “NINO”.

18.4. 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.javaimport java.io.*;public interface InterfazSerializable extends Serializable{}

Archivo ClaseSerializable.javapublic class ClaseSerializable implements InterfazSerializable{ public int edad; public String nombre; public transient int numeroAmigos; public ClaseSerializable(String nombrecin){ this.nombre = nombrecin; edad = 0;

Page 202: RUP-UML

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.javaimport java.io.*;import java.awt.*;import java.awt.event.*;

public class MyApp{

ClaseSerializable objeto1 = null;ClaseSerializable objeto2 = null;ClaseSerializable objeto3 = null;ClaseSerializable objeto4 = null;

public MyApp(){ objeto1 = new ClaseSerializable("Hugo"); objeto2 = new ClaseSerializable("Paco"); objeto3 = new ClaseSerializable("Luis"); objeto4 = new 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);

Page 203: RUP-UML

// 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();

Page 204: RUP-UML

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 objetosedad = 0nombre = HugonumeroAmigos = 0edad = 0nombre = PaconumeroAmigos = 0edad = 0nombre = LuisnumeroAmigos = 0edad = 0nombre = MickeynumeroAmigos = 0Escribimos los objetos en archivo.txtTranscurridos dos anos los objetos han crecido

Page 205: RUP-UML

Imprimimos los nuevos datos de los objetosedad = 2nombre = HugonumeroAmigos = 0edad = 2nombre = PaconumeroAmigos = 0edad = 2nombre = LuisnumeroAmigos = 0edad = 2nombre = MickeynumeroAmigos = 0Y uno de ellos el mas piloso ha conseguido 3 amigosImprimimos nuevamente datos de los objetosedad = 2nombre = HugonumeroAmigos = 0edad = 2nombre = PaconumeroAmigos = 0edad = 2nombre = LuisnumeroAmigos = 3edad = 2nombre = MickeynumeroAmigos = 0Volvemos a serializar los objetosRecuperamos los objetos una vezFalta Imprimir objetos recuperados una vezedad = 0nombre = HugonumeroAmigos = 0edad = 0nombre = PaconumeroAmigos = 0edad = 0nombre = LuisnumeroAmigos = 0edad = 0nombre = MickeynumeroAmigos = 0Recuperamos los objetos por segunda vezFalta Imprimir objetos recuperados segunda vezedad = 0nombre = HugonumeroAmigos = 0

Page 206: RUP-UML

edad = 0nombre = PaconumeroAmigos = 0edad = 0nombre = LuisnumeroAmigos = 0edad = 0nombre = MickeynumeroAmigos = 0Recuperamos el objeto 3Errores en algoExit code: 0No 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.

19. EJERCICIOS QUE TIENEN DIAGRAMAS DE SECUENCIA

19.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:

Page 207: RUP-UML

Burro

Perro

Zoologico

<<include>>

<<include>>

Domador

<<include>>

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:

Burro

Perro

Zoologico

<<include>>

<<include>>

Domador

<<include>>

Burro: higor

Burro: corcelin

Perro: doki

Perro: cuchufleto

Observe amigo lector / estudiante que el símbolo:

Page 208: RUP-UML

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:

Burro

Perro

Zoologico

<<include>>

<<include>>

Domador

<<include>>

Burro: higor

Burro: corcelin

Perro: doki

Perro: cuchufleto

Domador: pepito

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();

Page 209: RUP-UML

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:

Burro

Perro

Zoologico

<<include>>

<<include>>

Domador

<<include>>

Burro: higor

Burro: corcelin

Perro: doki

Perro: cuchufleto

Domador: pepito

Animal

dialogar()

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()

Page 210: RUP-UML

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:

Burro

dialogar()String getNombre()

Perro

dialogar()String getNombre()

Zoologico

<<include>>

<<include>>

Domador

<<include>>

Burro: higor

Burro: corcelin

Perro: doki

Perro: cuchufletoDomador:

pepito

Animal

dialogar()

Page 211: RUP-UML

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:

Zoologico

realizarActividadesPrevias()mostrarFuncion()

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”:

Page 212: RUP-UML

ThreadBurros.javapublic 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 trycatch(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");

Page 213: RUP-UML

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:

Burro

dialogar()String getNombre()

Perro

dialogar()String getNombre()

Zoologico

realizarActividadesPrevias()mostrarFuncion()

<<include>>

<<include>>

Domador

<<include>>

Burro: higor

Burro: corcelin

Perro: doki

Perro: cuchufleto

Domador: pepito

Animal

dialogar()

ThreadBurros

ThreadPerros

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);

Page 214: RUP-UML

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:

Page 215: RUP-UML

obtenerTamano<<<<size>>>>

obtenerElemento<<<<elementAt>>>>...>>

ImprimirTamano<<<<println>>>>

Exception?

imprimirError<<<<println>>>>

SI_Exception( e )

Conversion<<<<Casting>>>>

While( contador<2 )

<<<<Max 2>>>>

While ComenzarEjecucion

<<<<start>>>>

NO_Exception( e )

grupoBurros : ThreadBurrosobjSistema : Sistemav ectorBurros : Vector

Page 216: RUP-UML

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()

Page 217: RUP-UML

Ahora el diagrama de actividad asociado a dicho método:

obtenerTamano<<<<size>>>>

obtenerElemento<<<<elementAt>>>>...>>

ImprimirTamano<<<<println>>>>

Exception?

imprimirError<<<<println>>>>

SI_Exception( e )

Conversion<<<<Casting>>>>

While( contador<2 )

<<<<Max 2>>>>

While ComenzarEjecucion

<<<<start>>>>

NO_Exception( e )

grupoPerros : ThreadPerrosobjSistema : Sistemav ectorPerros : Vector

Page 218: RUP-UML

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.

19.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.javapublic interface Animal {

public void dialogar();} // Cierra interface Animal

Archivo: Burro.javapublic class Burro implements Animal{

String nombrecin ="";

Page 219: RUP-UML

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.javaimport 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{

Page 220: RUP-UML

// Thread.sleep(500);grupoBurrosHilos.start();

}catch(Exception e){

System.out.println("Burros no pueden rebusnar");

}// Cierra catchcontador++;

} // 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 catchcontador++;

} // 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");

}

Page 221: RUP-UML

catch(Exception e){System.out.println("No pude callar a Perros");

} // Cierra catch} // Cierra callarPeros()

} // Cierra class Domador

Archivo Perro.javapublic 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.javapublic 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 trycatch(Exception e){

System.out.println("Errores rebusnando");break;// objetoBurro1.estadoRebusnado(false);

} // Cierra catch();

Page 222: RUP-UML

} // Cierra while(true)} // Cierra public void run()

} // Cierra public class ThreadBurros

Archivo ThreadPerros.javapublic 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 trycatch(Exception e){

System.out.println("Errores ladrando");break;

} // Cierra catch();

} // Cierra while(true)} // Cierra public void run()

} // Cierra public class ThreadPerros

Archivo Zoologico.javapublic 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(){

Page 223: RUP-UML

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

Page 224: RUP-UML

20. INTRODUCCION A LOS PATRONES DE SOFTWARE

Una primera clasificación de los patrones es de acuerdo con las siguientes funcionalidades:

Funcionalidad de creaciónFuncionalidad estructuralFuncionalidad de comportamiento

20.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

20.2. PATRONES CON FUNCIONALIDAD ESTRUCTURAL

20.3. PATRONES CON FUNCIONALIDAD DE COMPORTAMIENTO

21. EXPLICACION DETALLADA DE LOS PATRONES

21.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

Page 225: RUP-UML

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

Est_sis_datos Est_ing_civil Est_electronica Est_literatura

Est_musica Est_preescolar Premiacion

dev_Nuevo_Cupo : Estudiante

Estudiante

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");

Page 226: RUP-UML

} } 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();

Page 227: RUP-UML

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 estudiantetipo Est_ing_civilSe ha creado un nuevocupo para un estudiante quepertenece a la carrera concodigo = 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 estudiantetipo Est_electronicaSe ha creado un nuevo

Page 228: RUP-UML

cupo para un estudiante quepertenece a la carrera concodigo = 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.

21.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.*;

Page 229: RUP-UML

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{

Page 230: RUP-UML

}

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();

Page 231: RUP-UML

}}

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.

22. PATRON DE CREACION SINGLETON

22.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:

Impresora

static String trabajo

Impresora getInstance()

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:

Page 232: RUP-UML

MyApp

static void main()

Impresora

static String trabajo

Impresora getInstance()

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:

MyApp

static void main()

Impresora

static String trabajo

Impresora getInstance() 0..10..1

22.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.javaimport 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

Page 233: RUP-UML

catch(Exception e){}

} // Cierra MyApp

public static void main(String args[]){

MyApp f = new MyApp();}

}

Archivo Impresora.javapublic 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

22.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.

Page 234: RUP-UML

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:

Page 235: RUP-UML

23. SOBRE LA CALIDAD DEL SOFTWARE

23.1. MODELOS DE CALIDAD

En la siguiente tabla se muestran los modelos mas conocidos sobre calidad:

MODELO CARACTERISTICAS VENTAJAS AREAS DE APLICACIÓN

NORMAS QUE APLICAN

SPICE • Se utiliza para la mejora de procesos y determinación de la capacidad.

• Incluye un proceso de medición.

• Combina la experiencia y conocimiento aportado por CMM, Trilliumy Bootstrapentre otros.

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 los

Alinear las actividades de

Page 236: RUP-UML

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, cuantitativamente

análisis de la medición

• Establecer los objetivos de la medición.

• Especificar medidas.

• Especificar procedimientos de recogida y almacenamiento.

• Especificar procedimientos 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

Page 237: RUP-UML

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.

• Proyectos cortos y de poca calidad.

• 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.

TSP • Enfocados en equipos

•Diseñado con el objetivo de

Page 238: RUP-UML

(incluye psp)

• Enfocados a la ingenieria del 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.

facilitar alcanzar el nivel 5 CMM.

• Contribuye a la administración eficiente de proyectos.

• Enfocados en reducir riesgos e incertidumbre en un proyecto de software.

TICKLT • Utiliza estrategias para lograr la certificación en productos software

ISO-9001ISO-9000-3

22.2. MODELO SPICE

Una norma que especifica el modelo SPICE es:Norma UNE 66-001-92 traducción de ISO 8402

Page 239: RUP-UML

23.3. NORMA ISO 9000-2000

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.

23.4. NORMA ISO 90003Esta 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.

23.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.

Page 240: RUP-UML

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

23.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.

Page 241: RUP-UML

Y aunque los anteriores atributos no se pueden medir directamente son una base para realizar medidas indirectas.

23.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 CMMISystems 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)

VENTAJASREPRESENTACIÓN POR ETAPASSu 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 CONTINUASu 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

Page 242: RUP-UML

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

Page 243: RUP-UML

Validación Ingeniería 3

Verificación Ingeniería 3

23.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.

Page 244: RUP-UML

24. 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.

24.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ónElaboraciónConstrucciónTransició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

Page 245: RUP-UML

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.

24.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.

24.2. 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)

Page 246: RUP-UML

• 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.

24.3. 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].

24.4. TIPOS DE SISTEMAS DE CONTROL DE VERSIONES

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

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]

Page 247: RUP-UML

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

24.5. 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 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ónElaboraciónConstrucciónTransición

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”

Page 248: RUP-UML

y en cada una de estas fases se tienen unos flujos de trabajo del proceso que son:

Modelado del negocioRequisitosanálisis y diseñoimplementaciónPruebasDespliegueFlujos de trabajo de soporteGestión del Cambio y configuracionesGestión del proyectoEntorno

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.

24.6. 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

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]

Page 249: RUP-UML

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.

24.7. 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]

24.8. 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,

IV Si quiere saber más sobre GNU puede entrar a la dirección electrónica: http://www.gnu.orgV 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, 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]

Page 250: RUP-UML

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 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

Page 251: RUP-UML

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].

24.9. 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].

24.10. 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.

Page 252: RUP-UML

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.

24.11. BIBLIOGRAFIA DE LA UNIDAD

[Ref Bib 1]Nombre: El Lengueje Unificado de ModeladoAutor(es): Grady Booch, James Rumbaugh, Ivar JacobsonEditorial: Addison WesleyAño: 1999

[Ref Bib 2]Nombre: El Lengueje Unificado de ModeladoAutor(es): Grady Booch, James Rumbaugh, Ivar JacobsonEditorial: Addison WesleyAño: 2002

[Ref Bib 3]Nombre: The Unified Software Development ProcessAutor(es): Grady Booch, James Rumbaugh, Ivar Jacobson

Page 253: RUP-UML

Editorial: Addison Wesley Object Technology SeriesAño: 2003

[Ref Bib 4]Nombre: Microsoft Visual Interdev 6.0 Manual del programadorAutor(es): Microsort PressEditorial: Mc Graw HillAño: 1999

24.12. INFOGRAFIA DE LA UNIDAD

[Ref 1]Dirección: http://gsyc.escet.urjc.es/pub/actividades/linuxprog/prog-html.tar.gzCopias: http://gsyc.escet.urjc.es/pub/actividades/linuxprog/prog-dvi.tar.gz

http://gsyc.escet.urjc.es/pub/actividades/linuxprog/prog.ps.gzFecha: 31 de Mayo de 2001

[Ref 2]Dirección: http://qref.sourceforge.net/Debian/reference/reference.es.html#contentsFecha: 14 de Enero de 2005

[Ref 3]Dirección: http://www.cvshome.orgFecha: 30 de Octubre de 2003

[Ref 4]Dirección: http://www.gnu.org/software/cvs/cvs.htmlFecha: 27 de septiembre de 2004

[Ref 5]Dirección: http://cvsbook.red-bean.comFecha: 3 de Enero de 2005

[Ref 6]Dirección: http://aegis.sourceforge.net/index.htmlFecha: 13 de Agosto de 2005[Ref 7]Dirección: http://regexps.com/arch.htmlFecha: 14 de enero de 2005

[Ref 8]Dirección: http://www.vestasys.orgFecha: 17 de diciembre de 2005

[Ref 9]

Page 254: RUP-UML

Dirección: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvsent/html/vsts-arch.asp

Fecha: 5 de Febrero de 2005

[Ref 10]Dirección: http://www.gnu.org/software/gettext/gettext.htmlFecha: 10 de septiembre de 2004

[Ref 11]Dirección: http://subversion.tigris.orgFecha: 17 de diciembre de 2005

[Ref 12]Dirección: http://www.acis.org.co/index.php?id=108Fecha: 18 de octubre de 2005

[Ref 13]Dirección: http://www.microsoft.com/latam/ssafe/producto/resumen.aspFecha: 29 de diciembre de 2004

Page 255: RUP-UML
Page 256: RUP-UML

25. BIBLIOGRAFIA

25.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.

25.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)

Page 257: RUP-UML

25.3. BIBLIOGRAFIA SOBRE IMPLEMENTACIONES CON UML

Java y UML.