FOTOS


BUENO NO HAY MAS SOLO QUE ELLA ME PERDONE PORLO QUE ESTOY HACIENDO
Y BUENO SE QUE FUE MI ERROR PUBLICARLOS SOLO TE PIDO PERDON GRACIAS
ATTE glbrt@glbrtcnz.com


BUENO NO HAY MAS SOLO QUE ELLA ME PERDONE PORLO QUE ESTOY HACIENDO
Y BUENO SE QUE FUE MI ERROR PUBLICARLOS SOLO TE PIDO PERDON GRACIAS
ATTE glbrt@glbrtcnz.com
ANALISIS Y DISEÑO
Orientado a
Objetos
Capítulo | Título |
I | Introducción |
II | Conceptos Básicos |
III | Análisis de |
IV | Diseño de |
V | Documentación |
VI | Metodologías Orientadas a Objetos |
VII | Preguntas más Comunes sobre la POO |
| Ejercicio |
|
|
Capítulo I.
Historia de
Las ideas básicas de la orientación a objetos nacen a principios de los años 60 en
Este enfoque resolvió los dos problemas planteados. Primeramente, ofrecía una forma natural de partir un programa muy complejo y, en segundo lugar, el mantenimiento pasaba a ser controlable. El primer punto es obvio ya que, a partir el programa en unidades informáticas paralelas a las físicas, la descomposición era automática. El segundo punto también se resuelve ya que, a cada iteración de simulación, el analista querrá cambiar o bien piezas enteras o bien el comportamiento de alguna pieza. En ambos casos la localización de los cambios está perfectamente clara y su alcance se reduce a un componente.
Pero, poco a poco, fue obteniéndose otro beneficio muy importante, que es la razón principal por la que la industria informática se ha abocado a la orientación a objetos. Se trata de la reusabilidad. En el proceso de construcción de un programa se obtienen piezas para futuros programas. Para dar soporte a estas ideas lo que se hizo fue crear un lenguaje para darle soporte, Simula-67, que continua utilizándose actualmente.
El siguiente paso se da en los años 70 en los Estados Unidos. Xerox tiene un centro de investigación en Palo Alto, donde trabajan en conceptos que puedan convertirse en productos industriales al cabo de
Smalltalk tuvo una gran difusión y cuando en los años 80 en ATT-Bell quisieron crear un sucesor al lenguaje C, incorporaron las principales ideas de Smalltalk y Simula, creando el lenguaje C++.
Este desarrollo que se ha descrito se refiere sólo a la evolución que ha tenido la orientación a objetos en el mundo de la ingeniería del software. Ha existido un desarrollo paralelo de los mismo conceptos en el mundo de la inteligencia artificial, donde el lenguaje CLOS, una variante de Lisp orientada a objetos, está muy extendido.
Términos y Conceptos de
Muchos de los términos y definiciones empleadas en
Objetos.
Los Objetos son cosas físicas que se encuentran alrededor de nosotros. Hardware, software, documentos, casas, coches son todos ejemplos de objetos. Los objetos que podría ver un ejecutivo son: mesas, empleados, documentos, .. Un ingeniero mecánico podría ver aceites, ruedas, medidores de nivel, ..
Los objetos son cosas que tienen un estado. El estado de un objeto es la condición de un objeto o el conjunto de circunstancias que describen a un objeto. Es común hablar de estado de información de un objeto, por ejemplo, el estado de información de un reloj es su hora actual, el estado de información de una lámpara puede ser apagada o encendida. Hacer una descripción exacta de los estados de objetos complejos puede resultar muy difícil, pero afortunadamente, cuando usamos objetos para modelar el mundo real o para imaginar situaciones, restringimos los posibles estados de los objetos y nos quedamos con aquellos estados relevantes a nuestro modelo.
Muchos de los objetos son estáticos, esto es, el estado de un objeto no cambia a menos que algo externo al objeto se lo requiera. Esto es lo común. Sin embargo, para algunos objetos es posible cambiar su propio estado. Si un objeto es capaz de cambiar su propio estado espontáneamente, se dice que ese objeto es un objeto con vida, también llamados objetos activos o actores. Un ejemplo de objeto con vida, podría ser un reloj. Si estamos modelando un proceso de negocios, podríamos considerar a los vendedores y comerciantes como objetos con vida.
Clases.
Hay dos grandes categorías de objetos: clases e instancias. Los usuarios de
1. Una clase es un patrón, una plantilla para una categoría de objetos con la misma estructura. Los ítem creados con la clase se llaman instancias. Es como si la clase fuera un molde y la instancia un pastel.
2. Una clase consiste en un patrón y en el mecanismo de crear ítem basados en ese patrón. A esta clase se le puede ver como a una fábrica de instancias. Las instancias son ítem manufacturados usando el mecanismo de creación de ítem de la clase.
3. Una clase es un conjunto de ítem creados usando un patrón especifico. Dicho de otra manera, la clase es el conjunto de todas las instancias de ese patrón.
Nosotros utilizaremos la segunda definición:
Una clase vista como una fábrica de instancias. |
Superclases.
Una superclase es una clase cuyas instancias también son clases. Esto significa que cuando se use el mecanismo de creación de instancias en una metaclase, la instancia creada será una clase.
Un concepto muy similar al de metaclase es el de clase parametrizada. Una clase parametrizada es una plantilla para una clase, es decir, una clase se crea rellenando la plantilla con los datos específicos de esa clase
Nosotros usaremos el termino de clase y haremos la distinción solo cuando sea necesario. Una definición que también usaremos es la de instanciación que tiene dos significados:
· como verbo, instanciación es el proceso de creación de la instancia de una clase, y
· como nombre, una instanciación es una instancia de una clase.
Beneficios y Riesgos de
Como todo en la informática (y tal vez en cualquier concepto de la vida),
Las Ventajas
Quienes adoptan la tecnología orientada a objetos suelen abrazar estas prácticas por una de dos razones. Primero, buscan una ventaja en la competitividad, como un tiempo reducido para la comercialización, mayor flexibilidad de los productos o fiabilidad en la planificación. Segundo, pueden tener problemas que sean tan complejos que parezcan no tener ninguna otra solución.
El uso del modelo de objetos conduce a construir sistemas que incorporan los cinco atributos de los sistemas complejos bien estructurados:
Orientados a procedimientos | Algoritmos |
Orientados a objetos | Clases y objetos |
Orientados a lógica | Objetivos, a menudo expresados como cálculo de predicados. |
Orientados a reglas | Reglas si-entonces (if-then) |
Orientados a restricciones | Relaciones invariantes |
El modelo de objetos forma el marco de referencia conceptual para la notación y el proceso del desarrollo orientado a objetos, y así el propio método se beneficia de estas ventajas. Algunas de ellas son:
· Explota la potencia expresiva de todos los lenguajes de programación orientados a objetos.
· Alienta la reutilización de componentes del software.
· Lleva a sistemas más flexibles al cambio
· Reduce el riesgo de desarrollo
· Resulta atractivo al funcionamiento de la mente humana.
Hay una serie de casos de estudio que apoyan estos hallazgos: en particular, apuntan que el enfoque orientado a objetos puede reducir el tiempo de desarrollo y el tamaño del código fuente resultante.
Los Riesgos
En el lado más oscuro del diseño orientado a objetos, se encuentran dos áreas de riesgo que deben ser consideradas: eficacia y costes de puesta en marcha.
En relación con los lenguajes procedimentales, definitivamente existe un coste de eficacia por enviar un mensaje de un objeto a otro en un lenguaje de programación orientado objetos. Para invocaciones de métodos que no pueden resolverse estáticamente, una implantación debe realizar una búsqueda dinámica con el fin de encontrar el método definido por la clase del objeto receptor. Los estudios indican que, en el peor caso, una invocación de método para llevar de
Otra fuente de sobrecarga para la ejecución proviene no tanto de la naturaleza de los lenguajes de programación orientados a objetos, sino de la forma en que se los utiliza en conjunción con el desarrollo orientado a objetos. Como ya se ha dicho muchas veces, el desarrollo orientado a objetos lleva a crear sistemas cuyos componentes están construidos en capas de abstracción. Una implicación de esta división en capas es que los métodos individuales son generalmente muy pequeños, ya que se construyen sobre otros de nivel inferior.
Otra implicación es que a veces hay que escribir métodos para conseguir un acceso protegido a los campos (de otro modo encapsulados) de un objeto. Este montón de métodos significa que se puede acabar con una saturación de invocaciones de métodos. La invocación de un método a un nivel alto de abstracción suele resultar en una cascada de llamadas a métodos; los métodos de alto nivel suelen llamar a otros de nivel inferior, y así sucesivamente. Para aplicaciones en las que el tiempo es un recurso limitado, tantas invocaciones a métodos pueden ser inaceptables. De nuevo desde el lado positivo, tal división en capas es esencial para la comprensión de un sistema; puede que no llegue nunca a ser posible tener un sistema complejo funcionando si no se empieza por un diseño en capas. Se recomienda diseñar primero por funcionalidad, e instrumentar después el sistema en funcionamiento para determinar dónde hay realmente cuellos de botella en la velocidad. Estos cuellos de botella pueden eliminarse muchas veces declarando los métodos apropiados como inline (intercambiando por tanto espacio por tiempo), reduciendo la jerarquía de clases o rompiendo el encapsulamiento de los atributos de una clase.
Un riesgo de eficacia relacionado se deriva de la sobrecarga de las clases: una clase profunda en una trama de herencias puede tener muchas superclases, cuyo código hay que incluir en la clase más específica al montar los enlaces (linking). Para aplicaciones orientadas a objetos pequeñas, esto puede significar en la práctica que las jerarquías de clases profundas deben evitarse, porque requieren demasiado código objeto. Este problema puede mitigarse un poco utilizando un compilador y un montador de enlaces experto que puedan eliminar todo el código muerto.
Hay aún otra fuente de cuellos de botella para la eficacia en el contexto de los lenguajes de programación orientados a objetos, que se deriva del comportamiento paginado de las aplicaciones en ejecución. La mayoría de los compiladores ubican el código objeto en segmentos, con el código de cada unidad de compilación (con frecuencia un solo archivo) situado en uno o más segmentos. Este modelo supone una alta localidad de la referencia; los subprogramas dentro de un segmento llaman a subprogramas del mismo segmento. Sin embargo, en sistemas orientados a objetos, raramente se da esa localidad de la referencia. Para sistemas mayores, las clases suelen declararse en archivos separados, y puesto que los métodos de una clase se construyen usualmente sobre los de otras clases, una sola invocación de método puede involucrar código de muchos segmentos. Esto viola las suposiciones que la mayoría de los computadores realizan sobre el comportamiento de los programas en tiempo de ejecución, particularmente los computadores con CPUs en tubería y sistemas de memoria por paginación. Volviendo al lado positivo, ésta es la razón por la que se separan las decisiones de diseño lógicas y físicas. Si un sistema en funcionamiento se ralentiza durante la ejecución debido a un intercambio de páginas excesivo, el acotar el problema es en gran medida cuestión de cambiar la asignación física de las clases a módulos. Esta es una decisión de diseño del modelo físico del sistema, que no tiene efecto sobre su diseño lógico.
Otro riesgo de eficacia en sistemas orientados a objetos proviene de la asignación y destrucción dinámica de objetos. Asignar memoria a un objeto en el heap (montón) es una acción dinámica, en oposición con la ubicación estática de un objeto, ya sea globalmente o en un marco de pila, y la ubicación en el heap suele costar más recursos de computación. En muchos tipos de sistema, heap suele costar más recursos de computación. En muchos tipos de sistema, esta propiedad no causa ningún problema real, pero en aplicaciones críticas respecto al tiempo, no pueden admitirse los ciclos que se necesitan para completar una asignación del heap. Hay soluciones simples para este problema: o bien preasignar espacio a tales objetos durante la elaboración del programa, en vez de asignarlo durante la ejecución de algún algoritmo crítico respecto al tiempo, o bien reemplazar el gestor de memoria del sistema por defecto por uno afinado para el comportamiento de este sistema específico.
Otra nota positiva: ciertas propiedades de los sistemas orientados a objetos a menudo ensombrecen todas las fuentes de problemas de eficacia. Por ejemplo, Russo y Kaplan relatan que el tiempo de ejecución de un programa en C ++ es en muchas ocasiones más rápido que el de su equivalente funcional en C. Ellos atribuyen esta diferencia al uso de funciones virtuales, que eliminan la necesidad de algunas formas de comprobación explícita de tipos y de algunas estructuras de control. En realidad, en nuestra experiencia, los tamaños del código de sistemas orientados a objetos suelen ser menores que sus implantaciones no orientadas a objetos funcionalmente equivalentes.
En algunos proyectos, los costes de puesta en marcha asociados con el desarrollo orientado a objetos pueden manifestarse como una barrera muy real para la adopción de esta tecnología. El uso de cualquier tecnología tan novedosa como esta requiere la capitalización de las herramientas de desarrollo del software. Además, si una organización de desarrollo está utilizando un lenguaje de programación orientada a objetos por primera vez, en general no tendrá una base establecida de software específico de la aplicación para reutilizar. En resumen, tienen que partir desde cero o al menos pensar como conectar sus aplicaciones orientadas a objetos con otras no orientadas a objetos ya existentes. Por último, un primer intento de usar desarrollo orientado a objetos seguramente fallará sin el entrenamiento apropiado. Un lenguaje de programación orientado a objeto no es " sólo otro lenguaje de programación " que puede aprenderse en un curso de tres días o leyendo un libro. Como se ha puesto de relieve, lleva un tiempo desarrollar la mentalidad adecuada para el diseño orientado a objetos, y esta nueva forma de pensar deben abrazarla tanto los desarrolladores como sus gestores.
Lenguajes Orientados a Objetos.
Ha surgido una gran variedad de lenguajes orientados a objetos, a continuación veremos brevemente algunos de ellos:
Lenguaje C++
El C++, se diseño como un sucesor del lenguaje C, y no todas las innovaciones que se introdujeron tienen que ver con la programación orientada a objetos. Así, algunos de los cambios fueron las funciones en línea, los prototipos de funciones, los modificadores const y volatile, los argumentos optativos y por omisión sobre funciones, la palabra clave void, la entrada y salida basada en listas infinitas y las especificaciones de ligadura.
El manual de consulta obligatorio para el lenguaje es el libro escrito por el creador de C++, Bjarne Strostrup. Lamentablemente, como es común con los lenguajes de programación, el lenguaje evolucionó una vez que comenzó a usar el sistema un grupo grande de programadores y de esta manera quedó algo atrasado el libro original.
Hay docenas de guías de instrucción de C++. Entre las más populares están las de Lippman, Wiener, Hansen, Chirlian, Eckel...
Objective-C
La descripción más accesible de los principios de Objective-C es el libro del creador del lenguaje, Brad Cox (1986). Lamentablemente, como es el caso del texto análogo de C++, el lenguaje ha cambiado mucho desde la publicación del libro original. Una cantidad de información un tanto más actual se da en el Webster, que es una introducción general al entorno de programación NeXT. Existe información adicional disponible en línea dentro del sistema NeXT. Este lenguaje permite el acceso directo del usuario a los mecanismos subyacentes de mensajes, lo cual, a veces puede ser útil para optimizar secciones de código que se usan de forma intensiva. Sin embargo los detalles de la implantación son demasiado específicos.
Smalltalk
La descripción definitiva de Smalltalk-80, el sistema estándar de Smalltalk, es el libro de Goldberg y Robson. Se le conoce familiarmente como el libro azul, y es parte de una serie de libros sobre este lenguaje. El libro azul cubre tanto el lenguaje como la parte de descripción de implantación. Entre los demás libros de la serie hay uno sobre el entorno de programación interactivo (Goldberg 83), uno acerca de la historia de los diferentes aspectos de implantación original de Smalltalk (Krasner 83), y una versión condensada del libro azul que trata solo el lenguaje (Goldberg 89).
Otros libros interesantes sobre el lenguaje son el de Kaehler y Patterson, el de Budd, el de Wiener...
Object Pascal
Este lenguaje fue desarrollado por Apple Computer con la asesoría del diseñador de Pascal, Niklaus Wirth; se basó parcialmente en una ampliación anterior de Pascal, desarrollada por Apple, llamada Classical. El lenguaje se define en un informe de Apple (Tesler 85).
El sistema QuickPascal de MICROSOFT es una implantación del sistema Object Pascal. El lenguaje QuickPascal se describe en (Shammas 90).
Una aplicación amplia de Object-Pascal se presenta en (Schmucker 86), que también describe Classical y diversos lenguajes orientados a objetos.
Turbo Pascal
Es una versión orientada a objetos de Pascal. El manual de consulta es Turbo 88 aunque existe una gran cantidad de ellos. Todos los textos tienen un inconveniente y es que primero presentan la programación Pascal, y más tarde introducen las extensiones orientada a objetos como tan solo una adición, o una ocurrencia tardía; de esta manera se podría hacer creer al lector que las extensiones orientadas a objetos son tan solo una adición para programar en modo convencional en lugar de una técnica que requiere un completo replanteamiento del proceso de diseño.
A pesar de las similitudes en nombre y sintaxis, Turbo Pascal es muy diferente a Object Pascal. Turbo Pascal toma ideas de C++ como la de los constructores y la distinción entre métodos estáticos y virtuales.
Otros Lenguajes
La mayoría de los conceptos asociados con la programación orientada a objetos se desarrollaron primero en el lenguaje de programación Simula. Por desgracia, en EE UU, este lenguaje fue visto nada más que como una extensión del Algol orientada en forma específica hacia la simulación, y por ello se le prestó relativamente poca atención.
Posteriormente fueron surgiendo otros como Eiffel diseñado específicamente con principios modernos de ingeniería del software y con características como capacidad para agregar afirmaciones, que se revisan en tiempo de ejecución, a clases y métodos individuales. Ha sido utilizado en muchos proyectos de software comercial.
Otro lenguaje orientado a objetos es el Actor, basado en el Pascal.
Pero sobre todo la tendencia ha sido versiones de los lenguajes ya existentes, ya sea el LOGO, LISP... aplicando los diferentes conceptos que caracterizan el diseño de objetos.
Más recientemente y con el auge de las comunicaciones vía Internet, a tomado una importancia relevante, JAVA.
Selección de un Lenguaje Orientado a Objetos
Dada la gran cantidad de lenguajes orientados a objetos existentes, es fácil que el programador no realice una correcta elección de la que más le conviene. Esta exposición supone un breve índice de puntos a tener en cuenta para dicha elección.
1. Familiaridad: Este punto se refiere a la elección de un lenguaje orientado a objetos cuya versión convencional conozcamos. No siempre es fácil pasar de una a la otra, esto hay que tenerlo en cuenta.
2. Plataformas: No todos los lenguajes se ejecutan en todas las plataformas Hardware aunque este inconveniente cada vez es menor dada la tendencia del mercado hacia el PC.
3. Importancia del tiempo de programación en relación con el tiempo de ejecución: Hay lenguajes como el C++, orientados hacia una optima ejecución y otros como el Smalltalk buscan la facilidad para el desarrollo de los programas.
4. Ubicuidad: Los lenguajes populares, tendrán más cantidad de manuales, herramientas... lo cual supone una ventaja.
5. Acceso a código existente: La existencia de bibliotecas puede acortar considerablemente el tiempo de desarrollo de una aplicación.
6. Entornos de programación: La disponibilidad de editores, depuradores y otras herramientas simplifica la creación de nuevas aplicaciones.
7. Características de entrega: En los lenguajes interpretados el entorno de programación se necesita junto con el programa ejecutable, por ejemplo el SMALLTALK, no así otros lenguajes como C++ que generan un archivo convencional ejecutable en binario.
Capítulo II.
Objeto
Las personas tienen una idea clara de lo que es un objeto: conceptos adquiridos que nos permiten sentir y razonar acerca de las cosas del mundo. Un objeto podría ser real o abstracto, por ejemplo una organización, una factura, una figura en un dibujador, una pantalla de usuario, un avión, un vuelo de avión, etc.
En el análisis y diseño orientados a objetos (OO), interesa el comportamiento del objeto. Si se construye software, los módulos de software OO se basan en los tipos de objetos. El software que implanta el objeto contiene estructuras de datos y operaciones que expresan dicho comportamiento. Las operaciones se codifican como métodos. La representación en software OO del objeto es entonces una colección de tipos de datos y objetos.
Entonces, dentro del software orientado a objeto, un objeto es cualquier cosa, real o abstracta, acerca de la cual almacenamos datos y los métodos que controlan dichos datos.
Un objeto puede estar compuesto por otros objetos. Estos últimos a su vez también pueden estar compuestos por otros objetos. Esta intrincada estructura es la que permite construir objetos muy complejos.
Tipo de Objeto
Los conceptos que poseemos se aplican a tipos determinados de objetos. Por ejemplo, empleado se aplica a los objetos que son personas empleadas por alguna organización. Algunas instancias de empleado podrían ser Juan Pérez, José Martínez, etc. En el análisis orientado a objetos, estos conceptos se llaman tipos de objetos; las instancias se llaman objetos.
Así, un tipo de objeto es una categoría de objeto, mientras que un objeto es una instancia de un tipo de objeto.
En el mundo de las bases de datos existen los tipos de entidad, como cliente o empleado. Existen muchas instancias de cada tipo de entidad (como Juan Pérez o José Martínez para el tipo de entidad empleado). Del mismo modo, en OO se define tipos de objetos e instancias de tipo de objeto.
Sin embargo, el término objeto tiene diferencias fundamentales con el término entidad, ya que la entidad sólo se refiere a los datos, mientras que objeto se refiere a los datos y a los métodos mediante los cuales se controlan a los propios datos. En OO, la estructura de datos y los métodos de cada tipo de objeto se manejan juntos. No se puede tener acceso o control de la estructura de datos excepto mediante los métodos que forman parte del tipo de objeto.
Métodos
Los métodos especifican la forma en que se controlan los datos de un objeto. Los métodos en un tipo de objeto sólo hacen referencia a la estructura de datos de ese tipo de objeto. No deben tener acceso directo a las estructuras de datos de otros objetos. Para utilizar la estructura de datos de otro objeto, deben enviar un mensaje a éste. El tipo de objeto empaca juntos los tipos de datos y su comportamiento.
Un objeto entonces es una cosa cuyas propiedades están representadas por tipos de datos y su comportamiento por métodos.
Un método asociado con el tipo de objeto factura podría ser aquel que calcule el total de la factura. Otro podría transmitir la factura a un cliente. Otro podría verificar de manera periódica si la factura ha sido pagada y, en caso contrario, añadir cierta tasa de interés.
Encapsulado
El empaque conjunto de datos y métodos se llama encapsulado. El objeto esconde sus datos de los demás objetos y permite el acceso a los datos mediante sus propios métodos. Esto recibe el nombre de ocultamiento de información. El encapsulamiento evita la corrupción de los datos de un objeto. Si todos los programas pudieran tener acceso a los datos de cualquier forma que quisieran los usuarios, los datos se podrían corromper o utilizar de mala manera. El encapsulado protege los datos del uso arbitrario y no pretendido.
El encapsulado oculta los detalles de su implantación interna a los usuarios de un objeto. Los usuarios se dan cuenta de las operaciones que puede solicitar del objeto, pero desconocen los detalles de cómo se lleva a cabo la operación. Todos los detalles específicos de los datos del objeto y la codificación de sus operaciones están fuera del alcance del usuario.
Así, encapsulado es el resultado (o acto) de ocultar los detalles de implantación de un objeto respecto de su usuario.
El encapsulado, al separar el comportamiento del objeto de su implantación, permite la modificación de ésta sin que se tengan que modificar las aplicaciones que lo utilizan.
Mensajes
Para que un objeto haga algo, le enviamos una solicitud. Esta hace que se produzca una operación. La operación ejecuta el método apropiado y, de manera opcional, produce una respuesta. El mensaje que constituye la solicitud contiene el nombre del objeto, el nombre de una operación y, a veces, un grupo de parámetros.
La programación orientada a objetos es una forma de diseño modular en la que con frecuencia el mundo se piensa en términos de objetos, operaciones, métodos y mensajes que se transfieren entre tales objetos. Un mensaje es una solicitud para que se lleve a cabo la operación indicada y se produzca el resultado.
Los objetos pueden ser muy complejos, puesto que pueden contener muchos subobjetos, éstos a su vez pueden contener otros, etc. La persona que utilice el objeto no tiene que conocer su complejidad interna, sino la forma de comunicarse con él y la forma en que responde.
Clase
El término clase se refiere a la implantación en software de un tipo de objeto.
El tipo de objeto es una noción de concepto. Especifica una familia de objetos sin estipular la forma en que se implanten. Los tipos de objetos se especifican durante el análisis OO.
Así, una clase es una implantación de un tipo de objeto. Especifica una estructura de datos y los métodos operativos permisibles que se aplican a cada uno de sus objetos.
Herencia
Un tipo de objeto de alto nivel puede especializarse en tipos de objeto de bajo nivel. Un tipo de objeto puede tener subtipos. Por ejemplo, el tipo de objeto persona puede tener subtipos estudiante y empleado. A su vez, el tipo de objeto estudiante puede tener como subtipo estudiante de pregrado y estudiante de postgrado, mientras que empleado puede tener como subtipo a académico y administrativo. Existe de este modo una jerarquía de tipos, subtipos, subsubtipos, etc.
Una clase implanta el tipo de objeto. Una subclase hereda propiedades de su clase padre; una sub-subclase hereda propiedades de las subclases; etc. Una subclase puede heredar la estructura de datos y los métodos, o algunos de los métodos, de su superclase. También tiene sus métodos e incluso tipos de datos propios.
Capítulo III.
El análisis de la estructura de objetos (AEO) define las categorías de los objetos que percibimos y las formas en que los asociamos.
Objetos y Tipos de Objetos.
En el análisis se trata de identificar los tipos de objeto más que los objetos individuales en un sistema. Los tipos de objetos se definen sobre la base de la comprensión del analista de nuestro mundo. Un objeto puede categorizarse de variadas formas.
Representación para Tipo de Objeto (Persona).
Asociaciones de Objetos.
Es importante modelar la forma como los objetos se asocian entre sí. Además es necesario identificar el significado de la asociación y la cantidad de objetos con los que un objeto dado puede y debe asociarse (cardinalidad).
Representación para
Jerarquías de Generalización.
Una de las vías de sentido común por las que el hombre organiza su volumen de conocimiento es el de las jerarquías, de lo más general a lo más específico.
Representación de una Jerarquía de generalización, para el tipo de objeto Persona.
En las jerarquías se habla de subtipo o especialización de un supertipo o generalización. En el caso anterior, persona es el supertipo para Empleado y Estudiante, que son sus subtipos. Por otra parte, Empleado es el supertipo para los subtipos Ejecutivo y Vendedor. Los subtipos (niveles inferiores de la jerarquía) heredan las características de sus supertipos, además, cada instancia de un tipo de objeto lo es también de sus supertipos.
Jerarquías Compuestas.
Un objeto se denomina complejo si está formado por otros. Las jerarquías Compuestas permiten realizar agregaciones de objetos.
Representación de una Jerarquía Compuesta.
Un objeto del tipo edificio se compone de a lo menos un objeto del tipo piso. A su vez un objeto del tipo piso se compone de a lo menos un objeto del tipo pasillo, podría tener varios (o ninguno) objetos del tipo baño y oficina.
Diagramas de relación entre los objetos.
Los tipos de objetos están relacionados con otros tipos de objeto. Por ejemplo, un empleado trabaja en una sucursal, o un cliente realiza un pedido de varios productos.
Diagrama de Relación entre objetos.
Un objeto del tipo cliente puede ordenar muchos objetos del tipo pedidos, y un objeto del tipo pedido es ordenado por un y sólo un objeto del tipo cliente. Un objeto del tipo producto está en muchos o ningún objeto del tipo pedido, mientras que un objeto del tipo pedido tiene al menos un objeto del tipo producto.
Esquemas de Objetos.
La comprensión de un modelo suele ser más sencilla si los tipos de objetos y relaciones se presentan mediante un diagrama de relación entre objetos; los supertipos y subtipos se presentan en un diagrama de jerarquías de generalización y las estructuras compuestas en un diagrama compuesto. Sin embargo, para los usuarios más sofisticados puede ser útil presentarlo todo en un mismo diagrama, el que se denomina esquema de objetos.
Ejercicios.
1. Diseñe la estructura de un sistema que maneje la información de productos en una librería, que vende libros técnicos y novelas.
Las novelas se clasifican como de ciencia ficción, romance, misterio, juveniles y policiales. Los libros técnicos se clasifican como de ingeniería, ciencias naturales o ciencias sociales.
Cada libro tiene un título, uno o más autores, una editorial, un año de edición y un formato (tapas duras o edición económica). Los libros técnicos tienen además un código ISBN y capítulos, los que tratan una o más materias.
La librería obtiene los libros por medio de proveedores que representan a una o más editoriales. De cada libro se tiene un stock (que puede ser cero). Al venderse un libro, el stock se actualiza. Si un cliente requiere un libro cuyo stock es cero, se puede realizar un encargo por parte del cliente. Esto significa que se pide el libro a un proveedor de la editorial del libro.
2. El jefe de una organización de desarrollo de software desea administrar el desarrollo de los proyectos.
Cada proyecto de desarrollo de software está a cargo de un jefe de proyecto, el cual lidera y coordina al equipo de proyecto, conformado por un grupo de análisis y diseño, un grupo de construcción y un representante de los usuarios que solicitó el software.
Cada proyecto contempla el desarrollo de una o más software (aplicaciones) que se componen a su vez de elementos de software (aplicaciones módulo). Cada elemento de software tiene un nombre, un responsable del análisis y diseño (miembro de ese grupo), un responsable de la construcción (miembro del grupo de construcción), una fecha de actualización (la última) y un plan de test (a desarrollar por el equipo de SQA ).
Un plan de test es una declaración narrativa de las pruebas a aplicar al elemento de software para aprobarlo o no. El equipo SQA pertenece a la organización, pero debe ser independiente del equipo de desarrollo del software que contiene al elemento a evaluar.
Se desea poder manipular esta información y generar reportes de todos los proyectos en desarrollo.
Capítulo IV
En el análisis del comportamiento de objetos (ACO) realizamos esquemas de eventos que muestran eventos, la secuencia en que ocurren y cómo los eventos cambian el estado de los objetos.
Estados de un Objeto.
Un objeto puede existir en varios estados. Por ejemplo, un objeto reservación aérea puede ser una instancia de alguno de los siguientes tipos de objeto:
· Reservación solicitada,
· Reservación en lista de espera,
· Reservación confirmada,
· Reservación cancelada,
· Reservación satisfecha,
· Reservación archivada.
Tales tipos de objetos suelen percibirse como estados posibles del ciclo vital de un objeto. Sin embargo, un objeto puede tener una gran variedad de perspectivas de ciclos vitales. Por ejemplo, el mismo objeto reservación aérea también puede tener los siguientes estados relacionados con el pago:
· Reservación no liquidada,
· Reservación con un pago de depósito,
· Reservación totalmente pagada,
· Reservación reembolsada.
Así, el estado de un objeto es la colección de asociaciones que tiene un objeto.
Eventos.
El mundo está lleno de eventos: una coneja tiene conejitos, llega el pesado del vecino en forma inesperada, un cliente solicita un préstamo, el servidor se cae, se termina la tarea, etc.
En el análisis orientado a objetos el mundo se describe en términos de los objetos y sus estados, así como los eventos que modifican esos estados.
Un evento produce un cambio en el estado de un objeto. Los eventos sirven como indicadores de los instantes en que ocurren los cambios de estado.
Para saber de los cambios y reaccionar adecuadamente ante ellos, debemos entender y modelar los eventos.
Tipos de Eventos
El analista no necesita conocer cada evento que ocurra en una organización: sólo los tipos de eventos.
Por ejemplo, el tipo de evento reservación en lista de espera confirmada es la colección de eventos donde un objeto cambia de una reservación en lista de espera a una reservación confirmada.
Los tipos de eventos indican los cambios sencillos en el estado de un objeto; por ejemplo, cuando se deposita dinero en una cuenta bancaria o se actualiza el sueldo de un trabajador. Básicamente, los tipos de eventos describen las siguientes formas de cambios de estado:
· Un objeto se crea.
· Un objeto se termina.
· Un objeto se clasifica como una instancia de un tipo de objeto.
· Un objeto se desclasifica como una instancia de un tipo de objeto.
· Un objeto cambia de clasificación.
· Un atributo de un objeto se cambia.
Los objetos pueden asociar un objeto con otro. Por ejemplo, en la mayoría de las organizaciones, cuando un objeto se clasifica como empleado, debe estar asociado con un departamento. Un evento clasificará al objeto como empleado. Otro evento creará una asociación entre el objeto empleado y un objeto Departamento (las asociaciones son objetos como los demás).
Algunos eventos requieren que antes ocurran otros. Por ejemplo, antes de cerrar un departamento, todos los empleados deben ser asignados a otra parte, las oficinas que ocupaban deben tener otro uso, etc.
Algunas veces, un evento puede provocar la reacción encadena de otros eventos. Por ejemplo, el cambio de circuito a las conexiones de un avión, puede exigir cambios a varios otros objetos.
Una operación hace que los eventos ocurran. Dibujamos la operación como un cuadro con esquinas redondeadas, puesto que los eventos indican los puntos en el tiempo en que se da el cambio de estado de un objeto. Los tipos de eventos se representan como triángulos negros llenos, generalmente unidos a la caja de operación.
Según el área que se modele, puede ocurrir más de un evento al terminar una operación, y cada uno de estos puede activar operaciones independientes.
El Ciclo Vital de un Objeto
La mayoría de los objetos tienen un ciclo vital en el que una sucesión de eventos pueden ocurrirle y cada uno de éstos modifica su estado.
En este análisis, se dibuja un diagrama que muestre el ciclo vital de un objeto, incluyendo los estados posibles de los objetos, además de los cambios de estado permisibles. Este se denomina diagrama de reja.
Diagrama de reja que muestra los estados posibles de un objeto reservación aérea. Las líneas horizontales representan estados y las verticales muestran las transiciones entre estados.
Interacciones entre Tipos de Objetos
La mayoría de los procesos requieren la interacción de varios objetos.
En esta otra figura, se desarrolla el diagrama anterior para mostrar las operaciones necesarias.
Operaciones.
En el análisis OO, una operación se refiere a una unidad de procesamiento que puede ser solicitada. El procedimiento se implanta mediante un método. El método es la especificación de cómo llevar a cabo la operación. En el ámbito de programa, el método es el código que implanta la operación.
Las operaciones se invocan. Una operación invocada es una instancia de una operación. Una operación puede o no cambiar el estado de un objeto, si lo cambiara ocurriría un evento.
Fuentes Externas de Eventos
Los eventos son cambios de estado que un sistema debe conocer y reaccionar ante ellos de algún modo. Muchas de las operaciones que producen estos eventos son externas al sistema.
Reglas de Activación
Cuando ocurre un evento, lo normal es que el cambio de estado active el llamado a una o más operaciones. Por ejemplo, si se retiran bienes de un almacén y la cantidad baja de cierto nivel, ello puede activar una operación para volver a realizar un pedido.
Las reglas de activación definen la relación entre la causa y el efecto. Siempre que ocurra un evento de cierto tipo, la regla de activación invoca a una operación ya definida.
Un tipo de evento puede tener varias reglas de activación, cada una de las cuales invoca a su operación en paralelo. Las operaciones paralelas pueden producir diferentes cambios de estado en forma simultánea.
Condiciones de Control
Una operación puede ser invocada por una o varias reglas de activación. Sin embargo, antes de invocar de hecho a la operación se puede verificar una condición de control. Si el re4sultado de evaluación de la condición es verdadera se invoca su operación, en otro caso no.
Las condiciones de control también pueden actuar como puntos de sincronización para el procesamiento en paralelo, pues garantizan que un conjunto de eventos esté completo antes de proceder con una operación.
Subtipos y Supertipos de Eventos.
Los eventos pueden dividirse en subtipos mediante diagramas independientes; o bien, es posible expresar la misma información en un diagrama ampliado.
La operación revisar tarea produce dos eventos: tarea aceptada o tarea rechazada. Sólo se puede dar uno de estos tipos de evento al revisar una tarea.
Aquí tarea revisada es un supertipo de tarea aceptada y tarea rechazada, que son los subtipos. Siempre se entiende que existe una relación de exclusividad entre los subtipos.
Las particiones de eventos no son operaciones independientes que coordinan las condiciones de bifurcación para las formas de activación ajenas, sino que indican los objetivos y distintos subobjetivos de las operaciones a las que están asociadas.
Capítulo V
En el diseño de la estructura y comportamiento de objetos se identifican los componentes siguientes:
· Clases que se implantarán. Los tipos de objetos en el AEO serán la guía en esta decisión.
· Estructuras de Datos que utilizará cada clase. Se puede hacer un diagrama para representar la estructura de datos.
· Operaciones que ofrecerá cada clase y cuáles serán sus métodos. Se enumeran las operaciones y se especifican los métodos.
· Forma de Implantación de la herencia de clases y efecto sobre las especificaciones de los datos y operaciones.
· Identificación de variantes de clases ("igual que, excepto...").
Clase.
En el análisis de estructura de objetos, se identificaron tipos de objetos; en el diseño de estructura de objetos nos centramos en la implantación de esos tipos de objetos.
Clase es la implantación de un tipo de objeto. Especifica la estructura de datos y los métodos operativos permitidos que se aplican a cada uno de sus objetos.
La clase especifica la estructura de datos de cada uno de sus objetos y las operaciones que se utilizan para tener acceso a los objetos. La especificación de cómo se llevan a cabo las funciones de una clase se llama método. Los objetos se pueden utilizar exclusivamente con métodos específicos.
Una instancia de una clase, almacena sus datos dentro de él. Se tiene acceso a los datos y se les modifica sólo mediante operaciones permisibles. Esta restricción al acceso se debe al encapsulado. El encapsulado protege los datos del uso arbitrario o no permitido. El acceso o la actualización directa de los datos de un objeto por parte del usuario violaría el encapsulado.
Los usuarios observan el "comportamiento" del objeto en términos de las operaciones que se pueden aplicar a los objetos, así como los resultados de tales operaciones. Estas operaciones forman la interfaz del objeto con sus usuarios.
Diferencia entre Operación y Método.
Las operaciones son procesos que se pueden solicitar como unidades. Los métodos son especificaciones del procedimiento de una operación dentro de una clase. Es decir, la operación es el tipo de servicio solicitado y el método es su código de programación.
Por ejemplo una operación asociada con la clase pedido podría ser aquella que calcule el total del pedido. El método especificaría la forma de calcular el total. Para esto, el método podría obtener el precio de cada artículo del pedido al enviar una solicitud a los objetos artículo asociados. A su vez, cada objeto artículo regresaría su precio al método pedido mediante un método de la clase artículo.
Los métodos de una clase controlan solamente a los objetos de esa clase. No pueden tener acceso directo a las estructuras de datos de un objeto en una clase distinta. Para utilizar las estructuras de datos en una clase diferente, deben enviar una solicitud a ese objeto.
Herencia de Clase.
La generalización es una noción conceptual. La herencia de clase (que sólo se conoce como herencia) es una implantación de la generalización. La generalización establece que las propiedades de un tipo se aplican a sus subtipos.
La herencia de clase hace que la estructura de datos y operaciones sean disponibles para su reutilización por parte de sus subclases. La herencia de las operaciones de una superclase permite que las clases compartan código. La herencia de la estructura de datos permite la reutilización de la estructura.
Herencia Múltiple.
En la herencia múltiple, una clase puede heredar estructuras de datos y operaciones de más de una superclase.
Por ejemplo supóngase que existe un tipo de objeto cuenta, que tiene como subtipos a los tipos de objetos cuenta de cliente y cuenta vencida. A su vez, cuenta de cliente tiene como a subtipo a cuenta de cliente vencida y cuenta vencida también tiene como subtipo a cuenta de cliente vencida.
Selección del Método.
Cuando se envía una solicitud a un objeto, el software selecciona los métodos por utilizar. El método no se almacena en el objeto, pues esto causaría una réplica múltiple y pérdida de espacio. En vez de esto, el método se asocia con la clase. El método puede no estar en la clase de la que el objeto es una instancia, sino en una superclase.
En ese caso, el mecanismo de selección buscará la operación en su superclase y en todas las superclases de la jerarquía hasta que lo encuentre, nivel por nivel. Si la encuentra, selecciona la operación. Si la operación no se encuentra en ningún nivel de la superclase, se considera inválida la fuente de la solicitud.
De esta forma, los usuarios sólo deben especificar lo que se debe hacer, dejando que sea el mecanismo de selección el que determine la forma de localizar la operación y la ejecute. El mecanismo de selección deja en manos de la aplicación OO el problema de localizar la operación y la ejecute.
Polimorfismo.
Uno de los objetivos principales de las técnicas OO es utilizar otra vez el código. Sin embargo, algunas de las operaciones requieren adaptación para resolver necesidades particulares.
Esta necesidad, se da generalmente entre superclases y subclases, donde una subclase es una especialización de su superclase, y puede requerir alcanzar los mismos objetivos, pero con distintos mecanismos. Por ejemplo, una superclase rectángulo podría tener una operación área cuyo objetivo es calcular el área del rectángulo, definida como la multiplicación de los largos de dos lados contiguos. A su vez, la clase cuadrado es una subclase de rectángulo que también tiene una operación área cuyo objetivo es calcular el área del cuadrado, pero que está definida especialmente para los objetos del tipo cuadrado como la multiplicación del largo de uno de sus lados por si mismo.
El fenómeno recién descrito se conoce como polimorfismo, y se aplica a una operación que adopta varias formas de implantación según el tipo de objeto, pero cumple siempre el mismo objetivo.
Una de las ventajas del polimorfismo es que se puede hacer una solicitud de una operación sin conocer el método que debe ser llamado. Estos detalles de la implantación quedan ocultos para el usuario; la responsabilidad descansa en el mecanismo de selección de la implantación OO.
Notación.
Para representar una clase, sus atributos y sus métodos:
Para representar una instancia de una clase:
Objeto es una instancia de
Capítulo V
Documentación del Análisis.
Diagramas a Incluir.
1. Diagrama de Jerarquías de Generalización.
2. Diagrama de Jerarquías Compuestas.
3. Diagrama de Relación de Objetos [los diagramas 1,2 y 3 pueden integrarse en uno: Esquema de Objetos].
4. Ciclo Vital. (por Tipo de Objeto)
5. Diagrama de Interacción entre objetos.
6. Diagrama de Operaciones y eventos.
Documentación Asociada a los Diagramas.
1. Documentación Tipo de Objeto
Nombre:
Supertipos:
Subtipos:
Descripción:
Compuesto por:
Operaciones:
2. Documentación Operaciones.
Nombre:
Descripción:
Solicitud:
Algoritmo:
Documentación Del Diseño
Diagramas a Incluir.
1. Diagrama de Jerarquías de Generalización
2. Diagrama de Jerarquías Compuestas.
3. Diagrama de Relación de Objetos [estos diagramas pueden integrarse en uno: Esquema de Objetos, además de utilizar la notación extendida para el diseño].
Documentación asociada a los diagramas.
1. Documentación de Clases
Nombre: Superclases:
Subclases:
Descripción:
Atributos:
Métodos:
2. Documentación Métodos.
Nombre:
Descripción:
Parámetros:
Algoritmo:
3. Documentación Objetos
Nombre:
Tipo:
Descripción:
Valor Atributos:
4. Documentación Atributos
Nombre:
Componente de : (clase)
Tipo:
Restricción:
Capítulo VI.
Todos aquellos que quieran dedicarse a
1. El Método OOD (Object Oriented Desing)
Este método fue definido por G. Booch a principios de los años 80 y ha conocido varias versiones sucesivas. Desde el punto de vista de las aplicaciones industriales, es probablemente uno de los métodos precursores de la aproximación orientada a objetos. Fue definido para el Departamento de Defensa estadounidense (DOD) para racionalizar el desarrollo de las aplicaciones en ADA. Posteriormente ha sido ampliado para el lenguaje C++. Por lo tanto, se trata de un método de desarrollo (especificación técnica e implementación) y no de diseño (análisis de las necesidades y especificación formal). Con posterioridad ha inspirado numerosos métodos, algunos de los cuales son extensiones directas, como HOOD.
La idea principal de OOD es sugerir a los programadores la utilización de los paquetes de ADA, no para poner en ellos cualquier procedimiento o definición de tipo, sino para implementar clases en el sentido de la aproximación orientada a objetos. De este modo, cualquier objeto del sistema se representa como un paquete. Lo esencial del método está dedicado a la elaboración del modelo estático (describir los objetos del sistema); el modelo dinámico (cambios de estado de los objetos frente a ciertos eventos) solamente se aborda muy parcialmente y el modelo funcional (describe los procesos de transformación de los usuarios) no se tiene en cuenta. OOD recomienda sin embargo el análisis de las funciones según el método SADT .
Los Modelos del Método.
OOD se centra en la definición del modelo estático y completa esta definición con algunos diagramas de estados para representar el aspecto dinámico. Revisaremos seguidamente los conceptos de estos distintos modelos, centrándonos en ciertos conceptos específicos.
Herramientas de Modelización Estática.
Estas herramientas están constituidas por un conjunto de diagramas que permiten describir los datos en el ámbito lógico y como físico. Estos diagramas constituyen una de las formas de la notación de base de OOD; la otra forma es una especificación textual constituida por un conjunto de bloques de definiciones para rellenar.
Diagramas de Nivel Lógico
En el ámbito lógico se proponen dos tipos de diagramas: los diagramas de clases y los diagramas de objetos (o de instancias). Los principales conceptos siguientes constituyen los elementos de estos diagramas:
l Objeto: además de su definición por sus atributos, sus operaciones y su identificador, un objeto posee además un estado o un conjunto de estados que controlan su evolución en el tiempo.
l Asociaciones: además de las asociaciones de herencia, de instanciación y de metaclases, el modelo estático comporta una relación que expresa un mensaje enviado por un objeto a otro. Esta relación se denomina relación de utilización (un objeto utiliza los servicios de otro objeto).
l Objeto cliente: es un objeto que utiliza los recursos de otro objeto.
l Protocolo de un objeto: es la lista de operaciones que un objeto puede efectuar sobre los demás objetos (conjunto de relaciones de utilización partiendo de dicho objeto).
l Comportamiento de un objeto: es el protocolo del objeto más la lista de operaciones que los demás objetos pueden efectuar sobre él (lista de los servicios que solicita más los que ofrece).
l Función de un objeto: un objeto puede ser cliente o actor (o activo) cuando opera sobre otros objetos (les solicita servicios). Puede ser servidor(o pasivo) cuando es utilizado por los demás ( les ofrece servicios). Puede ser agente cuando es a la vez cliente y servidor.
l Concurrencia entre objetos: un objeto puede tener un comportamiento secuencial (se dice que es un objeto secuencial ) o concurrente (objeto concurrente). Un objeto secuencial realiza una solicitud de servicio a otro objeto y espera el resultado. Un objeto concurrente realiza una solicitud de servicio y sigue con su trabajo hasta la llegada del resultado, que tendrá en cuenta seguidamente. Un objeto secuencial solamente efectúa un servicio a la vez. Un objeto concurrente puede rendir varios servicios simultáneamente.
l Objeto persistente: OOD menciona la persistencia de los objetos sin enunciar la naturaleza del sistema que gestionará dicha persistencia. En realidad, como el método viene muy marcado por el lenguaje ADA, que no gestiona la persistencia, esta última no se toma en cuenta realmente en el ámbito lógico o físico.
Un diagrama de clases describe las jerarquías de clases de objetos (relaciones de herencia) con un cierto número de vinculaciones entre estas clases: vinculación de utilización, de instanciación, de metaclases y otras vinculaciones de usuario. La relación de uso define los mensajes que los objetos pueden enviarse unos a otros. Las clases de objetos se representan por medio de pequeñas nubes de trazo punteado, y los objetos en trazo seguido; las relaciones entre clases se representan por medio de líneas de diferentes motivos según la semántica de la relación.
Esta última asociación es la única construcción admitida para representar la comunicación entre objetos. Asimismo, la agregación y las otras asociaciones binarias se representan por medio de envíos de mensajes. La asociación use posee cardinalidades de mismo tipo que una asociación binaria clásica. Los puntos negros en el extremo de los arcos representan la cardinalidad N (varios); los puntos blancos representan la cardinalidad 0 y la ausencia de punto representa la cardinalidad 1.
La notación textual correspondiente a este diagrama de clases permite definir para cada clase: los tipos que la caracterizan (atributos), las operaciones asociadas, la encapsulación (partes visibles e invisibles de cada clase de objetos), sus superclases, sus metaclases y otras informaciones del sistema como la concurrencia, la persistencia y la máquina de estados finitos que controla los estados sucesivos de los objetos.
Un diagrama de objetos describe, salvo pocos detalles, las mismas informaciones que el diagrama de clases, pero en el ámbito de las instancias. Puede resultar sorprendente, para los usuarios de bases de datos, definir diagramas de objetos en el ámbito lógico cuando los objetos no son conocidos en general más que cuando se utiliza la base. Esto demuestra solamente que la dimensión de bases de datos y la gestión de grandes volúmenes de información no se tienen en cuenta y que el método está más bien orientado hacia la programación de aplicaciones que comportan muy pocas ocurrencias de objetos.
Cuando los diagramas de clases son voluminosos, OOD propone utilizar el concepto de categoría para simplificar la visualización de estos diagramas. Una categoría es un conjunto de clases agrupadas por tema. Es un tipo de vista que se define a partir de las clases de base de otras vistas. Cada categoría corresponde pues a un diagrama de clases o a un diagrama de otras categorías.
Diagramas de Nivel Físico
Los diagramas siguientes describen las implementaciones de los diagramas lógicos. El diagrama de módulos implementa el diagrama de clases. El diagrama de procesos implementa el diagrama de objetos. Un proceso es una ejecución particular de un módulo, y como tal corresponde a una implementación de una instancia de clase de objetos.
La implementación física se propone fundamentalmente en los entornos de ADA y C++. Pero también se han aportado otros entornos como ejemplo, tales como Object Pascal, Smaltalk o Common Lisp Object System (CLOS).
El Modelo Dinámico.
En rigor, no se puede hablar de modelo dinámico, Se pone básicamente el acento en el análisis estático. Los principales resultados que se esperan del método son los diagramas lógicos y físicos precedentes. Sin embargo, se sugieren dos diagramas complementarios para representar el aspecto dinámico: un diagrama de estados / transiciones y un diagrama de tiempo.
El diagrama de estados / transiciones se realiza para cada objeto cuyo ciclo de vida interese al programador. Es una descripción complementaria del diagrama de objetos y del diagrama de clases (cuando el ciclo de vida de un objeto es representativo de los ciclos de vida del conjunto de los objetos de la clase). En cada arista de un diagrama de estados, se especifica el evento que ha desencadenado la transición y la operación que ha realizado la transformación.
El Sistema del Método
OOD traza una neta distinción entre las herramientas de descripción proporcionadas y el método de desarrollo a seguir. Este método se basa en el ciclo de desarrollo en cascada. El método no cubre la etapa de análisis, aunque la representa en el esquema. OOD recomienda referirse a los métodos de análisis clásicos como SADT: La etapa de diseño se sitúa en el nivel lógico y utiliza los diagramas citados en la sección anterior. En esta etapa se preconizan un método incremental basado en refinamientos sucesivos y una cierta modularidad de las especificaciones. La etapa de evolución ( no sé si se traduce así) concierne a la codificación, las pruebas y la integración. Las técnicas asociadas a estas actividades no están formalizadas, se muestran a través de ejemplos. La etapa de modificación corresponde al mantenimiento y a los cambios que puedan darse en el momento de la evolución del sistema.
La etapa de diseño es la más importante, y a ella dedica OOD un lugar preferente en el método de construcción del modelo lógico (conjunto de los diagramas de nivel lógico y notaciones textuales correspondientes). El método propuesto sigue el sentido común, y aconseja dirigir el estudio de diseño lógico según las etapas siguientes:
1. Identificación de las clases y objetos (esto supone que los objetos no son numerosos; en caso contrario no son enumerables).
2. Identificación de la semántica de las clases y objetos (es decir, su comportamiento y su ciclo de vida).
3. Identificación de las asociaciones entre clases y objetos.
4. Implementación de las clases y objetos (fase de paso al nivel físico y codificación).
Este proceso debe aplicarse de forma recurrente utilizando alternativamente una aproximación descendente (para descomponer mejor los objetos) y una aproximación ascendente (para reutilizar mejor los objetos ya definidos).
Balance de OOD
OOD es uno de los métodos orientados a objetos más antiguos, y se han realizado un importante número de aplicaciones de acuerdo con este método. Existe literatura abundante referida a él. Sin duda, ha contribuido a racionalizar el desarrollo de las aplicaciones en ADA y en C++, y el cúmulo de experiencia adquirida por este método es indudablemente lo más importante.
Sin embargo, OOD tiene numerosas lagunas que las otras Metodologías se han cargado de llenar. Entre sus lagunas se pueden citar las siguientes. La aproximación orientada a objetos se considera como una herramienta de presentación de objetos complejos; OOD no proporciona ninguna información sobre la manera de componer los objetos (agregación, construcción de tipos compuestos, etc.). La noción de objeto compuesto se cita, pero no se propone ninguna abstracción para representarla. En el ámbito de los atributos que caracterizan a una clase, no se facilita ninguna información en cuanto a su naturaleza y a la complejidad de sus atributos. La representación gráfica no se cuenta entre las más amigables; se desmarca totalmente de las convenciones simbólicas más habituales, lo que no contribuye en absoluto a obtener una legibilidad rápida de sus esquemas. El paso del nivel lógico al nivel físico no está claramente formalizado en función del entorno anfitrión. Los sistemas de bases de datos, que son las herramientas más habituales para gestionar la persistencia y almacenar los datos, no se toman en consideración. A pesar de estas observaciones, OOD sigue siendo una referencia en el ámbito de los métodos orientados a objetos.
Clasificación Orientada A Objetos.
Por el concepto de clasificación entendemos el hecho de ordenar el conocimiento, normalmente buscando similitud entre las ‘cosas’ a clasificar. Relacionado con
Podemos decir que la finalidad del DOO es la identificación de clases y objetos. Esta identificación suele darse a partir de dos actividades:
Descubrimiento de clases y objetos. En ella nos dedicamos a reconocer abstracciones clave y mecanismos que constituyen el vocabulario del problema.
Invención, sobre todo de clases. En ella nos centramos en el diseño de clases, no existentes todavía, junto con los mecanismos que regulan la colaboración entre objetos o instancias de las mismas.
La clasificación, además de darnos la identificación de clases y objetos, nos va a ayudar a la hora de construir módulos o de dividir en módulos el código de nuestra aplicación.
El análisis orientado a objetos trata de modelar el mundo real identificando clases y objetos que forman el vocabulario del dominio del problema. Una vez se han identificado las clases que forman parte de un problema, es en el diseño orientado a objetos donde inventamos las abstracciones y mecanismos que proporcionan el comportamiento del modelo.
Cómo se identifican las clases y objetos de un problema, varía según el autor consultado. En nuestro caso vamos a proponer tres posibles clasificaciones, las cuales se encuentran en las siguientes tablas. Básicamente, cada autor propone una serie de conceptos generales y el analista trata de encajar los elementos que él observa en el problema, bajo uno de esos conceptos.
Cosas tangibles. | Coches, sensores,.. |
Roles. | Madre, profesor, medico,. |
Eventos | Andar, comer, jugar,.. |
Interacciones. | Prestar, comprar, interrumpir... |
Tabla 1. Clasificación 1ª.
Gente. | Personas que desarrollan una función. |
Lugares. | Áreas dispuestas para las personas o cosas. |
Cosas. | Grupos de objetos tangibles. |
Organizaciones. | Colecciones organizadas de personas. |
Conceptos. | Principios o ideas no tangibles. |
Eventos. | Cosas que ocurren a alguien o a algo. |
Tabla 2. Clasificación 2ª.
Estructura. | Relaciones ‘clase de’ y ‘parte de’ |
Otros sistemas. | Sistemas externos con los que interactúa el nuestro. |
Eventos recordados | Un evento histórico que debe ser recordado. |
Roles interpretados | Los distintos papeles que interpreta el usuario al trabajar con la aplicación. |
Lugares. | Sitios físicos, tales como oficinas y demás sitios importantes en la aplicación. |
Unidades de organización. | Grupos a los que pertenecen los usuarios. |
Tabla 3. Clasificación 3ª.
Resumen de
El método de Booch se basa en la necesidad de disponer de varias ‘vistas’ para capturar todos los detalles de un sistema software más o menos complejo. Es interesante que para comprender completamente un sistema conozcamos :
La estructura y la función de los objetos que lo componen.
· La estructura de las clases que lo integran.
· Los mecanismos de herencia empleados en él.
· El comportamiento individual de los objetos.
· El comportamiento del sistema visto como un todo.
En la metodología de Booch tenemos diversos tipos de diagramas, cada uno dedicado a representar un aspecto concreto del sistema que pretendamos construir. A su vez estos diagramas se dividen en dos grandes categorías: los que representan aspectos estáticos del sistema y los que representan aspectos dinámicos del mismo. Entre los primeros están los siguientes :
· Diagramas de clase. En ellos se representan las clases que existen y las relaciones que existen entre ellas. Las relaciones que existen entre las clases son: Asociación, Tiene, Herencia, Utiliza y Metaclase.
· Diagramas de objetos. En ellos se representan los mecanismos empleados para regular la colaboración entre los distintos objetos.
· Diagramas de módulos. En ellos se indica donde se debería de declarar cada clase y cada objeto utilizado.
· Diagramas de procesos. Estos diagramas se emplean para indicar a qué procesador se debería asociar un proceso y dado un procesador, cuál debería ser la estrategia de planificación de los procesos asociados a él.
Entre los segundos, están los Diagramas de Transición entre Estados, de los cuales se puede tener uno para cada clase y en ellos se representa el comportamiento de un objeto mediante una sucesión ordenada, en el tiempo, de eventos.
Una representación gráfica de estos diagramas se encuentra en el libro Object Oriented Analysis and Design with Applications 2ª. Edición.
Booch propone los siguientes pasos para el DOO:
· Definir el problema.
· Identificar clases y sus relaciones.
· Identificar objetos y sus atributos.
· Identificar operaciones o métodos que pueden aplicarse a los objetos.
· Establecer interfaces para mostrar las relaciones entre los objetos y los métodos.
· Decidir los aspectos del diseño de los objetos en detalle para su posterior implementación.
2. Metodología OMT.
Object Modeling Tecnique (Técnica de Modelización de Objetos) es una metodología de Ingeniería del Software, también conocida como el Método OMT de Rumbaugh, que cubre todas las fases del ciclo de vida de un producto software: análisis, diseño, implementación, verificación y mantenimiento. OMT modeliza un sistema desde tres puntos de vista diferentes, relacionados entre sí. OMT se apoya en tres modelos: Modelo de Objetos, Modelo Dinámico y Modelo Funcional.
El Modelo de Objetos representa al aspecto estructural, estático de un sistema: es decir, describe la estructura de los objetos del sistema en términos de su identidad, atributos, operaciones y relaciones (asociativas, de agregación y de herencia); el modelo se representa mediante un diagrama de objetos.
El Modelo Dinámico describe los aspectos del sistema relacionados con el tiempo y el secuenciamiento de operaciones, en términos de eventos y estados de los objetos; el modelo se representa gráficamente mediante diagramas de estado que muestran la secuencia de eventos, cambios de estado y operaciones permitidas para una clase.
El Modelo Funcional describe las transformaciones que sufren las informaciones del sistema; se representan mediante Diagramas de Flujo de Datos (DFDs) que describen qué hace el sistema, sin tener en cuenta quién o cuándo se realizan esas acciones.
Estos tres modelos van evolucionando a medida que avanza el proceso de desarrollo a través de las siguientes cuatro fases : análisis, diseño del sistema, diseño de los objetos, implementación. Veremos a continuación, brevemente, la fase de análisis.
Fase de Análisis en OMT.
Los modelos obtenidos tras esta fase representaran una vista externa del sistema, indicando qué es lo que dicho sistema hace.
El Modelo de Objetos es el primero que se crea y constituye el marco esencial para la construcción de los otros dos modelos. Para la obtención de este modelo se identificarán las clases principales que forman parte del sistema, sus asociaciones con otras clases y sus atributos que corresponderán respectivamente a nombres, verbos ( o frases verbales) y adjetivos ( o frases posesivas) de las especificaciones iniciales o del dominio de la aplicación. A continuación se organizan las clases, capturando la información y el comportamiento común en superclases. Se crean así jerarquías de herencia.
Para construir el Modelo Dinámico, el analista desarrolla diagramas de traza de eventos describiendo escenarios, diagramas de flujo de eventos y diagramas de estado para las clases con comportamiento dinámico relevante.
Corresponden a funciones o procesos en el Modelo Funcional las operaciones de los diagramas de estado que los objetos realizan como consecuencia de ciertos eventos. Los DFDs de este modelo detallarán las operaciones del Modelo Dinámico. Las entidades externas y los almacenes corresponden a objetos del Modelo de Objetos. Sin embargo, a diferencia de un objeto entidad externa (actor), un almacén no genera ninguna operación por sí solo, sino que se limita a responder a peticiones de acceso o almacenamiento. Los procesos del Modelo Funcional corresponden a operaciones en el Modelo de Objetos (etapa de adición de operaciones); cada proceso se implementa como un método en algún objeto.
El proceso de análisis de un sistema es un proceso iterativo, por lo que los modelos finales de esta etapa se obtengan, posiblemente, tras varias iteraciones de los pasos anteriores.
Capítulo VII.
1. ¿Cuál es la filosofía de POO?
Considera a un programa como una colección de agentes autónomos llamados objetos que realizan tareas específicas e interactúan.
2. ¿Cuál es la diferencia entre clase y objeto?
De forma resumida, una clase es un conjunto de datos y operaciones realizables por esos datos. Es algo conceptual.
El objeto es algo físico , es decir , es un espacio de almacenamiento que se reserva para dar soporte a la clase.
Los objetos de una misma clase tienen, por tanto, propiedades similares. A los objetos también se les denomina instancias de clase.
3. Errores más comunes en el diseño:
a) Clases que hacen modificaciones directas a otras clases: Ello implica la violación de la encapsulación. La encapsulación es una barrera conceptual que básicamente impide operaciones no deseables sobre los datos.
b) Clases con demasiadas responsabilidades: Es decir, con demasiadas operaciones y datos.
c) Clases sin responsabilidad: Pocas operaciones y datos.
d) Clases con responsabilidades que no se usan: No es conveniente implementar necesidades futuras ya que luego no se suelen utilizar.
e) Uso inadecuado de la herencia: Cuando las relaciones entre clase y superclase no son es-un.
f) Funcionalidad repetida: Se repite el código en varias clases.
g) Responsabilidades desconectadas: Falla cuando una clase tiene una serie de funciones que no están conectadas por datos.
4. ¿ Qué sucede si a una clase hija se le añade una función con el mismo nombre que otra perteneciente a una de sus clases paternas?
El concepto de herencia supone que la clase hija o subclase posee todas las funciones de las superclases o clases paternas más otras añadidas exclusivas de la subclase. Se considera trivialmente que las funciones o métodos nuevos constituyen un conjunto disjunto con respecto a las funciones de las superclases.
Pero la realidad implica que pueden existir funciones añadidas con el mismo nombre que las heredadas. Se nos plantea el problema de saber cuál es la función a la que accedemos cuando invocamos ésta. Entonces se realiza un proceso de búsqueda entre las funciones, examinándose primero las propias de la clase y posteriormente las heredadas. Ello supone que la función a la que vamos a acceder es la particular de la clase , puesto que es la primera que encontramos. Para ejecutar la función de la clase paterna, debemos especificarlo.
Como caso práctico, en el lenguaje Visual C++ , cuando hay una función coincidente como acabamos de explicar y queremos ejecutar la de la clase paterna, tendremos que añadir el nombre de la clase paterna más un par de dos puntos (: :)
Ejemplo: CView : : OnPaint
Esto , como veremos se llama refinamiento.
5. ¿Por qué se pretende anular un método o función heredada?
Hay dos propósitos que anulan una función heredada:
a. reemplazo
b. refinamiento.
6. ¿Qué es el reemplazo?
Un reemplazo de método sustituye totalmente el método de clase durante la ejecución, es decir, el código en la clase paterna nunca será ejecutado cuando se manipulan los ejemplares de una clase hija.
7. Reemplazo en C++ :
El compilador de C++ puede hacer el reemplazo de dos formas:
a. declarando la función virtual
b. declarando la función normalmente
Los resultados son diferentes.
El modificador virtual es opcional. Si no se proporcionara, el método o función seguiría reemplazando a la función paterna, pero se alteraría el enlace del método con el mensaje. Esto es, el enlace de una llamada a un método no virtual se lleva a cabo en tiempo de compilación, basándose en el tipo (estático) declarado del receptor y no en tiempo de ejecución. Por lo tanto, las variables de la clase hija, se ejecutarían sin considerar a la clase real del valor contenido en la variable.
Los métodos virtuales suponen un enlace dinámico. Este enlace se establece en tiempo de ejecución.
8. ¿Qué es el refinamiento?
El refinamiento incluye como parte de su comportamiento la ejecución del método heredado de la clase paterna, aparte del adicional, es decir, se preserva y se aumenta el comportamiento del padre. Así, resulta útil que haya algún mecanismo, desde dentro de algún método anulado que invoque el mismo método en la superclase. En este caso decimos que el método refina el de la clase paterna.
9. Refinamiento en C++ :
C++ usa la técnica de nombres calificados para dar acceso a métodos de las clases paternas de métodos anulados. Un nombre calificado se escribe como nombre de clase seguido por un par de dos puntos y el nombre de un procedimiento. El nombre calificado elimina el mecanismo virtual de paso de mensajes y asegura que el método se tome de la clase nombrada.
10. ¿ Qué es un mensaje?
Un mensaje es una acción a ser realizada por un objeto. puede ser un identificador, una palabra clave o un símbolo.
En C++, los mensajes están representados por los prototipos o declaraciones de las funciones.
Una expresión común en POO, es enviar un mensaje a un objeto.
En C++, existen dos métodos de enviar mensajes:
a) Invocar una función perteneciente a una clase empleando para ello un objeto.
b) Ejecutar la función a través de un puntero a un objeto.
// Consideramos ya definida una clase llamada “Clase”
// El operador de C++ new asigna dinámicamente memoria.
Clase objeto;
Clase *p_objeto=new Clase;
objeto.mensaje1();
p_objeto->mensaje1();
11. ¿Qué es un método?
Existe un método para cada mensaje soportado por un objeto de una clase determinada.
El método define cómo deberá responder un objeto ante un mensaje determinado.
En C++, los métodos son las definiciones de las funciones pertenecientes a una clase.
La combinación de prototipo / definición de una función se conoce como miembro de una clase.
El conjunto de métodos de la clase se denomina interfaz de la clase.
Resumiendo los objetos son instancias de una clase que responden a mensajes de acuerdo a métodos pertenecientes al interfaz de la clase.
12. ¿Cuáles son las principales propiedades de un lenguaje POO?
a. Abstracción de datos:
Es el procedimiento por el cual se combinan las estructuras de datos y las operaciones aplicables a estas formando un nuevo tipo de dato.
b. Encapsulación:
Consiste en establecer medidas de protección para que los datos de una clase no puedan ser accedidos más que por el interfaz de la clase(modificador private). Por tanto un objeto es una encapsulación de una abstracción.
c. Herencia:
Mecanismo mediante el cual una clase recibe propiedades de otras clases. Esto nos evita duplicar código.
Puede existir cualquier número de derivaciones. La clase de más alta jerarquía se llama clase base. Las subclases se denominan clases derivadas.
Cada clase derivada puede tener varias clases base (Herencia múltiple).
Además C++ añade la posibilidad de evitar que una clase derivada almacene múltiples copias de una clase base provenientes de diferentes caminos de la cadena de herencia, declarando la clase base como virtual (no confundir con funciones virtuales).
Hay que distinguir las relaciones entre clases de jerarquía y de pertenencia.
d. Polimorfismo:
Es una propiedad que permite emplear interfaces idénticos pero con diferentes implementaciones.
En concreto C++ proporciona los siguientes mecanismos de polimorfismo:
· Sobrecarga de funciones:
int suma(int, int);
float suma(float, float);
a=suma(3,5);
b=suma(3.1f,
· Sobrecarga de operadores:
El ejemplo típico es sobrecargar los operadores aritméticos para poder operar con número complejos.
class Complejo {...
public:
Complejo & operator + (Complejo&,Complejo&);
}; //se consigue empleando la palabra operator
· Funciones virtuales:
Mediante una función virtual se envía un mismo mensaje a diferentes instancias de clases que pertenecen a una misma jerarquía de derivación. La respuesta a este mensaje será distinta para cada clase de jerarquía. Por lo tanto, los datos de cada clase deben enlazarse dinámicamente, en tiempo de ejecución, no en tiempo de compilación.
En C++ las funciones virtuales se declaran con el modificador virtual.
class ventana{
...
public:
virtual void pinta();
};
13. ¿Constituye cada rol una clase distinta?
Este termino típico del lenguaje C++.
Shlaer y Mellor exponen que uno de los trucos para encontrar objetos en la fase de análisis consiste en buscar roles desempeñados por personas u organizaciones (doctor , cliente , empleado...). Según esto los roles son clases y por tanto tendríamos en este caso las clases doctor , cliente , empleado.
Intentemos una primera codificación en la que a cada rol se le asocia una clase independiente:
class cliente {
public:
char * nombre();
void nombre(char*);
Date FechaDeAlta();
private:
char *nombre;
char *apellidos;
Date *fechaAlta;
};
class proveedor {
// sería similar a la clase cliente
};
Es fácil observar que el resultado es ineficaz puesto que los datos de una y otra clase son prácticamente iguales. Necesitamos que estos dos roles posean una porción común que vamos a denominar Persona . En este momento quizá Ud. piense que hay que derivar. Pero la derivación no es la panacea , aunque como primero solución venida a nuestras pequeñas mentes vamos a utilizarla en este momento.
La pregunta es que tipo de derivación adoptar: privada , pública o protegida.
Como se trata de una relación ES-UN parece que puede ser una derivación pública.
** nos ahorraremos los detalles engorrosos de los contenidos de las clases.
class Persona {//clase base...};
class PersonaFisica : public Persona{...};
La conclusión pudiera ser que los roles se asocian a objetos pero que es conveniente que estos no sean una clase base en muchas ocasiones por afinidad entre unos y otros.
14. ¿Qué quiere decir que los roles sean dinámicos?
Puede ocurrir , por ejemplo , que el rol de una enfermera se convierta en el rol paciente , es decir evidentemente los roles son dinámicos.
Según Grady Booch , “el rol de un objeto denota la selección de un conjunto de comportamientos que están bien definidos en un punto concreto del tiempo”. Esto quiere decir que un objeto puede representar diferentes roles a lo largo de su vida.
El carácter dinámico de los roles no encaja con la disposición estática de la herencia en C++. Esto quiere decir que un objeto no puede cambiar de clase.
Necesitaríamos algo como esto:
class PersonaFisica : public Persona {
public:
PersonaFisica(PersonaFisica*pPF);
nombre=pPF->nombre...
PersonaFisica personaFisica() {
return PersonaFisica(this);
}
};
class Medico : public PersonaFisica
{
public:
Medico( const PersonaFisica& );
...
};
class Paciente : public PersonaFisica
{
public:
Paciente( const PersonaFisica& );
...
};
// Aquí tenemos un objeto de tipo Medico:
Medico cardiólogo;
// Poco después el médico enferma:
Paciente paciente ( cardiólogo. PersonaFisica());
Este ejemplo consiste en replicar la porción PersonaFisica en cada uno de los objetos roles. Pero si no es una copia lo que necesitamos sino que paciente y médico sean la misma persona la herencia parece innecesaria.
14. ¿Qué es el patrón de roles intercambiables?
Peter Coad estableció que el problema del rol se enmarca en un patrón estructural genérico que denomina Patrón de roles intercambiables y que en definitiva consiste en que existe un objeto que actúa de interprete de rol y que se relaciona con un sólo objeto a la vez de una clase derivada de rol, que a su vez es una clase abstracta base de una jerarquía similar a la expuesta. Coad establece la siguiente configuración mínima:
class Interprete {
private:
Rol *rol;
...
};
class Rol {
private:
Time *momentoDeComienzo;
Time *momentoDeFin;
...
};
De la clase Rol derivarían clases representando roles específicos (Médico, Político...). Como vemos los papeles han cambiado: ahora se operará únicamente con interpretes y estos contendrán la información sobre que rol asumen en cada momento.
El enfoque de Coad presenta la ventaja de su efectividad comunicativa y dos evidentes dificultades: por un lado impide la concurrencia temporal de roles y por otro existe una ambigüedad en cuanto a la implementación de la funcionalidad de los roles.
15. ¿Existe una solución alternativa a Coad?
Existe lo que se denomina el Patrón de Estados cuyo cometido básico es permitir a un objeto modificar su comportamiento cuando quiera que su estado interno cambie. Su implementación en C++ puede ser la siguiente:
class Sujeto {
public:
setRol (Rol *unRol) {
rol=unRol;
}
unMensajeCualquiera() {
rol->Maneja (this);
}
private:
Rol *rol;
};
class Rol {
public:
virtual Rol * maneja (sujeto*);
};
class RolConcreto : public Rol {
public:
virtual RolConcreto *maneja(sujeto *);
};
16. ¿Qué es y cómo se realiza el paso de mensajes en C++?
Es el proceso de solicitar a un objeto una acción específica. También se puede nombrar como invocación a una función miembro.
La notación describe al receptor seguido de un punto y la función miembro con sus argumentos encerrados entre paréntesis. Aún cuando la función no tenga argumentos siempre son necesarios un par de paréntesis para distinguir la invocación de una función miembro de datos miembro.
Un ejemplo de esto puede ser , siendo Hola una función miembro de la clase ClaseEjemplo y habiendo sido declarado un objeto de esta clase llamado x:
x.Hola(); **La función Hola no tiene argumentos**
Un miembro que se declara (la declaración es algo diferente al invocación) de manera que devuelva un valor de tipo void , en realidad no devuelve nada , es decir , se usa como una procedure del lenguaje C. Si devolviera algo equivaldría a una function del mismo lenguaje.
En C++ hay una pseudovariable llamada this. Esta apunta , no es el valor , al receptor , el objeto de la clase que invoca la función miembro. Así la indirección -> invoca funciones miembros del receptor. Recordemos que -> se utilizaba cuando el objeto es un puntero . Si no lo es usamos el punto.
Un ejemplo de esto con la anterior función Hola , suponiendo que devuelve un dato de tipo entero pudiera ser:
int ClaseEjemplo::Hola() { return this->OtraFuncion() }
this es el objeto actual que en este caso es x.
OtraFuncion es cualquier función miembro de x.
Por lo tanto return this es también un paso de mensaje , es decir , una invocación.
17. ¿Qué es la creación e iniciación de los objetos?
Basándonos en el lenguaje C++ , la iniciación se realiza a través de los constructores. Un constructor tiene el mismo nombre que su clase.
El constructor se invoca siempre que se crea un objeto de la clase asociada. Esto sucede típicamente cuando se declara una variable. Por medio de los constructores el programador puede asegurarse de que se asignen valores sólo durante el proceso de creación.
El mecanismo de construcción se hace más potente cuando se combina con la capacidad de sobrecargar funciones de C++. Se dice que una función está sobrecargada cuando hay dos o más cuerpos de función conocidos por el mismo nombre. En C++ se rompe la ambigüedad de las funciones sobrecargadas por medio de las diferencias de las listas de parámetros o argumentos. Podemos usar esta característica para proporcionar más de un estilo de iniciación. Por ejemplo , a veces querríamos iniciar un número complejo dando únicamente la parte real y otras dando un valor real y un imaginario. Estas formas sobrecargadas se pueden usar en las declaraciones.
Vamos a ilustrar todo esto con un ejemplo:
class Complejo
{
public:
int real;
int imag;
// Definimos los constructores que van a inicializar la clase.
// Sabemos que son constructores porque tienen el mismo nombre que la clase
Complejo (int pr);
Complejo (int pr, int pi);
...
} ;
// Vamos a definir los constructores .Están sobrecargados
Complejo::Complejo(int pr)
{
real = pr;
imag=0;
}
Complejo::Complejo(int pr , int pi)
{
real = pr;
imag=pi;
}
// Estas son las dos posibles formas de construir la clase
// La primera crea un número real y la segunda un número complejo
Complejo num(3);
Complejo num(3,5);
// Podemos añadir una función a la clase para visualizar el número complejo.
// Esta sería la definición
void VisualizaNumero()
{
if (imag)
cout<< “el número no tiene parte imaginaria y es: ”<< real;
else
cout<< “el número tiene parte imaginaria y es: ”<< real <<“ + “ <<imag <<“j”;
}
Existe una función que libera la memoria asignada a un objeto. Estamos hablando del destructor. La función destructora no tiene argumentos y tiene el nombre de la clase precedida por ~ (ALT-126).
Raramente se invoca debido a que la memoria se libera automáticamente al salir del bloque donde esta declarado el objeto o con el operador delete si se ha asignado memoria mediante el operador delete.
Se muestra el ejemplo de un destructor de la clase Complejo:
Complejo::~Complejo()
{ cout<<“liberando complejo”;}
La utilidad del destructor es añadir funcionalidad adicional a la liberación de memoria.
18 ¿Qué es el puntero this?
Antes de entrar propiamente con el tema , que ya tocamos levemente anteriormente , vamos a explicar unas cuantas cosas.
Cada objeto dispone de una copia privada de los datos que componen la clase. Pero los métodos de la clase son compartidos por todos los objetos de la clase. Es decir, internamente las funciones de la clase no están almacenadas en los objetos de la clase.
Por tanto , será necesario un mecanismo que permita particularizar en cada momento los datos manipulados en las funciones de la clase con la copia privada de cada uno de los objetos.
Este mecanismo es el puntero this que apunta al objeto completo desde el cual fue invocado.
Un ejemplo es el siguiente:
class string {
private:
char *str;
public:
void imprime(){
// la instrucción que viene a continuación escribirá el dato str que corresponda
// al objeto actual, es decir accede a la copia privada de los datos correspondiente
// a dicho objeto
puts(this->str);
};
main()
{
string s,t;
s.imprime();
t.imprime();
}
this se utiliza generalmente para:
a) Pasar el objeto o un puntero a él a otra función.
b) Devolver el objeto (paso por referencia) o un puntero a él como retorno de una función.
19 ¿Cuál es la forma en SmallTalk de resolver este problema de la aritmética de tipo mixto?
Existe una técnica llamada Generalidad Coercitiva.
Esta técnica fue usada por el sistema SmallTalk-80 , así como por el sistema Little SmallTalk. Nosotros describiremos el último de los enfoques.
En este esquema se asigna un índice de generalidad a cada tipo de número. El índice de generalidad proporciona un ordenamiento lineal del grado de abstracción del número. De esta manera las fracciones son más generales que los enteros, los valores de punto flotante más generales que las fracciones, etc.
Podemos determinar el índice de generalidad de cualquier número pasando el mensaje generality al número. Se presume que dos número son compatibles si tienen el mismo índice de generalidad. Si no, el número con el índice de generalidad más bajo es modificado para ser compatible con el número con el índice de generalidad más alto.
Véase el siguiente cuadro con algunos índices:
Índice de generalidad | Tipo de dato |
7 | Float |
5 | Fraction |
4 | InfinitePrecisionInteger |
2 | Integer |
Consideremos primero la suma de un entero con otro entero; por ejemplo , la suma de los números 7 y 12. El siguiente programa muestra varios métodos de la clase integer. Cuando el mensaje + se pasa al objeto 7 , éste invocará el método que se muestra a continuación:
isInteger
“ ¿soy un entero? ”
true
+ unValor
“realiza suma de enteros”
(unValor isInteger)
ifTrue: [ <60 self unValor >]
ifFalse:[ self coerceAdd: unValor ]
generality
“devuelve mi número de generalidad”
“usado en aritmética de clases mixtas”
2
asFloat
“conviérteme en un real de punto flotante”
< 51 self >
El método anterior prueba si el argumento es un entero al pasar el mensaje isInteger al valor del argumento. Puesto que 12 también es un entero, encontrará el método isInteger mostrado anteriormente , que devolverá el valor constante verdadero y así la operación primitiva 60 se realizará en los dos valores.
Ahora consideremos la suma de un entero y un valor no entero; digamos la suma de 7 y el valor de punto flotante 3,14159. Como antes , ya que el receptor es un entero, se ejecutará el método de suma anterior. Sin embargo, esta vez , debido a que el argumento no es un entero el mensaje isInteger no encontrará el método reseñado antes en la clase Integer. En su lugar, se ejecutará el método de la clase Number, que pasamos a mostrar:
isInteger
“¿soy un entero?”
false
isFloat
“¿soy un flotante?”
false
coerceAdd: unValor
“Fuerza argumentos e intenta la suma de nuevo”
(self maxgen: unvalor) + (unValor maxgen: self)
maxgen: unValor
“ convierte el número con generalidad más baja ”
“ para que sea compatible con el otro “
(self generality > unValor generality)
ifTrue: [ self ]
ifFalse: [ unValor coerce: self ]
Esta vez se devuelve la constante false (falso) y se ejecuta la rama de falso del enunciado “si” en el método de la suma de la clase integer. el enunciado contenido en ese bloque pasa el argumento junto con el mensaje coerceAdd (suma forzada) que se encuentra en la clase Number. Este método, que se muestra convierte a uno o a otro de los argumentos hasta que son compatibles entre si cuando intenta la operación otra vez.
Para llevar a cabo la conversión, la rutina maxgen (generalidad máxima) compara los valores de generalidad de los dos argumentos y, si es necesario, pasa el mensaje coerce (fuerza) y el otro argumento al valor con generalidad mayor. puesto que el valor de punto flotante tiene generalidad más alta , se le pedirá que modifique al entero.
Por último mostramos a continuación el método coerce, método aritmético de la clase float:
isFloat
“ ¿soy un flotante? “
true
+ unValor
“realiza la suma de flotantes”
unValor isFloat
ifTrue: [ < 110 self unValor >]
ifFalse: [ self coerceAdd: unValor ]
generality
“devuelve mi número de generalidad”
“usado en aritmética de clases mixtas”
7
coerce: unValor
“convierte el argumento en un número de punto flotante”
unValor asFloat
El método logra la conversión al pasar al entero el mensaje asFloat. El método asFloat invoca otra operación primitiva para convertir el entero en un valor de punto flotante, que da un valor de a 7.0 . Una vez que se logra la conversión, se intenta de nuevo la suma con dos valores de punto flotante. Esta vez tiene éxito y se produce el resultado esperado (el valor de punto flotante 10.14159).
Hemos descrito el caso para entero más flotante. Vd. deberá verificar que también produzca el resultado correcto el caso simétrico de un número de punto flotante al que se pase une entero como argumento.
20 ¿En que consiste la técnica de Despacho Doble?
Efectivamente, además de la técnica anterior, generalidad coercitiva, existe esta otra denominada despacho doble. Fue presentada en 1986 y consiste en el siguiente código:
(MÉTODO ARITMÉTICO PARA FLOAT)
+ unValor
“realiza la suma de flotantes”
unValor addToFloat: self
addToFloat: unValor
“los tipos concuerdan, puedes realizar suma”
< 110 unValor self >
addToInteger: unValor
“convertir e intentar de nuevo”
(unValor asFloat) + self
(MÉTODO ARITMÉTICO PARA INTEGER)
+ unValor
“realiza la suma de enteros”
unValor addToInteger: self
addToInteger: unValor
“los tipos concuerdan, puedes realizar suma”
<60 unValor self>
addToFloat: unValor
“convertir, entonces sumar”
unValor + (self asFloat)
En términos sencillos, usamos el mecanismo de sobrecarga implícito en el paso de mensajes convirtiendo cada argumento, a su vez, en un receptor de un mensaje y codificando los tipos del resto de los argumentos en un selector de mensajes. De esta manera cuando un valor de punto flotante recibe el mensaje +, invierte los argumentos, pasando el mensaje AddToFloat (suma a flotante) al argumento que recibió.
Por otro lado , cada tipo de objeto que pueda ser sumado a un número de punto flotante debe saber como manejar dicho mensaje.
Como antes, se debe verificar que el caso simétrico también produzca el resultado correcto.
21. Interfaz e implantación, POO en Visual C++:
Imagina que divides el mundo en dos esferas.
Por una parte está el mundo tal y como lo ve el usuario. A esto lo llamaremos interfaz.
Por otra, la parte interior a la que llamamos implantación.
Al usuario solo se le permite acceso a lo que está descrito en el interfaz.
La implantación describe como se logra la responsabilidad prometida en el interfaz.
Esto se ve muy claro en Visual C++, donde cada clase está definida físicamente por dos archivos, uno con extensión .h que es el interfaz y otro con extensión .cpp que es el archivo de implantación o implementación.
1.- Ya sabemos que la herencia implica que una clase(subclase) pueda utilizar los datos y operaciones de otra (superclase).Ello supone eliminar redundancias de código. La cuestión es cómo definir las clases y subclases.
Para ello se utilizan las relaciones A es-un B y A tiene-un B(A y B son clases). Cuando se cumple la primera relación se puede definir A como una subclase y B como una superclase.
Si se cumple la segunda sería incorrecto definir herencia. Lo mejor podría ser definir B como atributo o parte de la clase A.
El ejercicio consiste en definir las relaciones es-un o tiene-un, lo cual nos proporcionaría en el caso de implementarlas la clave para definir como subclases, superclases o atributos según lo expuesto anteriormente:
CASA - TECHO
CONSERJE - EMPLEADO
RATÓN DIGITAL - DISPOSITIVO DE ENTRADA
MENÚ - VENTANA
CONJUNTO - COLECCIÓN
2.- Dados dos trozos de código de C++, ¿Cuál establece una relación jerárquica y cuál de pertenencia?
a. class CLASE_A
{...};
class CLASE_B : public CLASS_A
{...};
b. class CLASE_A
{...};
class CLASE_B
{
private:
CLASE_A obj;
...
};
3.- Utilizando la herramienta de Diseño OO de la biblioteca del. Simular en el computador el llamado ‘Juego de la vida’. Este juego consiste en dada una distribución inicial de población en un tablero de MxN casillas, en el que cada casilla representa a un ser vivo, estos seres vivos puedan moverse y evolucionar. Los seres vivos evolucionan, a través de las generaciones según las siguientes reglas :
Soledad, el numero de vecinos que le rodean es cero.
Hambre, el numero de vecinos que le rodean es superior a 3.
Vejez, un ser vivo puede vivir 10 generaciones como máximo.
Catástrofe, durante el desarrollo de las distintas generaciones y de forma aleatoria, se podrá producir una catástrofe que acabe con la vida de uno o varios seres vivos.
Deben de diseñar las clases y objetos que encuentren en el enunciado. Después del diseño, deberán generar código aquellos que utilicen las dos primeras herramientas.
I. UML
I.1 Introducción
II. NOTACIÓN BÁSICA UML
II.1 Modelos
II.2 Elementos Comunes a Todos los Diagramas
II.2.1 Notas
II.2.2 Dependencias
II.3 Diagramas de Estructura Estática
II.3.1 Clases
II.3.2 Objetos
II.3.3 Asociaciones
II.3.3.1 Nombre de
II.3.3.2 Multiplicidad
II.3.3.3 Roles
II.3.3.4 Agregación
II.3.3.5 Clases Asociación
II.3.3.6 Asociaciones N-Arias
II.3.3.7 Navegabilidad
II.3.4 Herencia
II.3.5 Elementos Derivados
II.4 Diagrama de Casos de Uso
II.4.1 Elementos
II.4.1.1 Actores
II.4.1.2 Casos de Uso
II.4.1.3 Relaciones entre Casos de Uso
II.5 Diagramas de Interacción
II.5.1 Diagrama de Secuencia
II.5.2 Diagrama de Colaboración
II.6 Diagrama de Estados
III NOTACIÓN AVANZADA UML
III.1 Modelado Dinámico
III.1.1 Diagramas De Actividades
III.1.2 Contenido del diagrama de actividades
III.1.2.1 Estados de actividad y estados de acción
III.1.2.2 Transiciones
III.1.2.3 Bifurcaciones
III.1.2.4 División y unión
III.1.2.5 Calles
III.2 Modelado Físico De Un Sistema OO
III.2.1 Componentes
III.2.1.1 Interfaces
III.2.1.2 Tipos de componentes
III.2.1.3 Organización de componentes
III.2.1.4 Estereotipos de componentes
III.2.2 Despliegue
III.2.2.1 Nodos
III.2.2.2 Nodos y componentes
III.2.3 Diagramas de Componentes
III.2.3.1 Algunos conceptos
III.2.3.2 Usos más comunes
III.2.4 Diagramas de Despliegue
III.2.4.1 Técnicas más comunes de modelado
III.2.5 Arquitectura del Sistema
III.2.5.1 Arquitectura de tres niveles
III.2.5.2 Arquitectura de tres niveles orientadas a objetos
III.2.5.3 Arquitectura MULTI-nivel
III.2.5.4 Paquetes
III.2.5.5 Identificación de Paquetes
IV DESARROLLO ORIENTADO A OBJETOS
IV.1 Proceso de Desarrollo
IV.1.1 Visión General
IV.2 Fase de Planificación y Especificación de Requisitos
IV.2.1 Actividades
IV.2.2 Requisitos
IV.2.3 Casos de Uso
IV.2.3.1 Casos de Uso de Alto Nivel
IV.2.3.2 Casos de Uso Expandidos
IV.2.3.3 Identificación de Casos de Uso
IV.2.3.4 Identificación de los Límites del Sistema
IV.2.3.5 Tipos de Casos de Uso
IV.2.3.6 Consejos Relativos a Casos de Uso
IV.2.4 Construcción del Modelo de Casos de Uso
IV.2.5 Planificación de Casos de Uso según Ciclos de Desarrollo
IV.2.5.1 Caso de Uso Inicialización
IV.3 Fase de Construcción: Diseño de Alto Nivel
IV.3.1 Actividades
IV.3.2 Modelo Conceptual
IV.3.2.1 Identificación de Conceptos
IV.3.2.2 Creación del Modelo Conceptual
IV.3.2.3 Identificación de Asociaciones
IV.3.2.4 Identificación de Atributos
IV.3.3 Glosario
IV.3.4 Diagramas de Secuencia del Sistema
IV.3.4.1 Construcción de un Diagrama de Secuencia del Sistema
IV.3.5 Contratos de Operaciones
IV.3.5.1 Construcción de un Contrato
IV.3.5.2 Post-condiciones
IV.3.6 Diagramas de Estados
IV.4 Fase de Construcción: Diseño de Bajo Nivel
IV.4.1 Actividades
IV.4.2 Casos de Uso Reales
IV.4.3 Diagramas de Interacción
IV.4.3.1 Creación de Diagramas de Interacción
IV.4.4 Diagrama de Clases de Diseño
IV.4.4.1 Relaciones de Dependencia para Representar Visibilidad entre Clases
IV.4.4.2 Construcción de un Diagrama de Clases de Diseño
IV.4.4.3 Navegabilidad
IV.4.4.4 Visibilidad de Atributos y Métodos
IV.4.5 Otros Aspectos en el Diseño del Sistema
IV.5 Fases de Implementación y Pruebas
I.1 Introducción
UML (Unified Modeling Language) es un lenguaje que permite modelar, construir y documentar los elementos que forman un sistema software orientado a objetos. Se ha convertido en el estándar de facto de la industria, debido a que ha sido impulsado por los autores de los tres métodos más usados de orientación a objetos: Grady Booch, Ivar Jacobson y Jim Rumbaugh. Estos autores fueron contratados por la empresa Rational Software Co. para crear una notación unificada en la que basar la construcción de sus herramientas CASE. En el proceso de creación de UML han participado, no obstante, otras empresas de gran peso en la industria como Microsoft, Hewlett-Packard, Oracle o IBM, así como grupos de analistas y desarrolladores.
Esta notación ha sido ampliamente aceptada debido al prestigio de sus creadores y debido a que incorpora las principales ventajas de cada uno de los métodos particulares en los que se basa (principalmente Booch, OMT y OOSE). UML ha puesto fin a las llamadas “guerras de métodos” que se han mantenido a lo largo de los 90, en las que los principales métodos sacaban nuevas versiones que incorporaban las técnicas de los demás. Con UML se fusiona la notación de estas técnicas para formar una herramienta compartida entre todos los ingenieros software que trabajan en el desarrollo orientado a objetos.
Uno de los objetivos principales de la creación de UML era posibilitar el intercambio de modelos entre las distintas herramientas CASE orientadas a objetos del mercado. Para ello era necesario definir una notación y semántica común. En
En la parte II de este texto se expone la notación y semántica básica de UML, en la parte III se presentan conceptos avanzados de la notación UML, mientras que en la parte IV se presenta el método de desarrollo orientado a objetos de Larman, que se sirve de los modelos de UML que se han visto anteriormente.
El Lenguaje de Modelamiento Unificado (UML - Unified Modeling Language) es un lenguaje gráfico para visualizar, especificar y documentar cada una de las partes que comprende el desarrollo de software. UML entrega una forma de modelar cosas conceptuales como lo son procesos de negocio y funciones de sistema, además de cosas concretas como lo son escribir clases en un lenguaje determinado, esquemas de base de datos y componentes de software reusables.
II.1 Modelos
Un modelo representa a un sistema software desde una perspectiva específica. Al igual que la planta y el alzado de una figura en dibujo técnico nos muestran la misma figura vista desde distintos ángulos, cada modelo nos permite fijarnos en un aspecto distinto del sistema.
Los modelos de UML que se tratan en esta parte son los siguientes:
• Diagrama de Estructura Estática.
• Diagrama de Casos de Uso.
• Diagrama de Secuencia.
• Diagrama de Colaboración.
• Diagrama de Estados.
II.2 Elementos Comunes a Todos los Diagramas
II.2.1 Notas
Una nota sirve para añadir cualquier tipo de comentario a un diagrama o a un elemento de un diagrama. Es un modo de indicar información en un formato libre, cuando la notación del diagrama en cuestión no nos permite expresar dicha información de manera adecuada. Una nota se representa como un rectángulo con una esquina doblada con texto en su interior. Puede aparecer en un diagrama tanto sola como unida a un elemento por medio de una línea discontinua. Puede contener restricciones, comentarios, el cuerpo de un procedimiento, etc.
II.2.2 Dependencias
La relación de dependencia entre dos elementos de un diagrama significa que un cambio en el elemento destino puede implicar un cambio en el elemento origen (por tanto, si cambia el elemento destino habría que revisar el elemento origen). Una dependencia se representa por medio de una línea de trazo discontinuo entre los dos elementos con una flecha en su extremo. El elemento dependiente es el origen de la flecha y el elemento del que depende es el destino (junto a él está la flecha).
II.3 Diagramas de Estructura Estatica
Los Diagramas de Estructura Estática de UML se van a utilizar para representar tanto Modelos Conceptuales (ver sección IV.3.2) como Diagramas de Clases de Diseño (ver sección IV.4.4). Ambos usos son distintos conceptualmente, mientras los primeros modelan elementos del dominio los segundos presentan los elementos de la solución software. Ambos tipos de diagramas comparten una parte de la notación para los elementos que los forman (clases y objetos) y las relaciones que existen entre los mismos (asociaciones). Sin embargo, hay otros elementos de notación que serán exclusivos de uno u otro tipo de diagrama.
II.3.1 Clases
Una clase se representa mediante una caja subdividida en tres partes: En la superior se muestra el nombre de la clase, en la media los atributos y en la inferior las operaciones. Una clase puede representarse de forma esquemática, con los atributos y operaciones suprimidos, siendo entonces tan solo un rectángulo con el nombre de la clase. En
II.3.2 Objetos
Un objeto se representa de la misma forma que una clase. En el compartimento superior aparecen el nombre del objeto junto con el nombre de la clase subrayados, según la siguiente sintaxis: nombre_del_objeto: nombre_de_la_clase Puede representarse un objeto sin un nombre específico, entonces sólo aparece el nombre de la clase.
II.3.3 Asociaciones
Las asociaciones entre dos clases se representan mediante una línea que las une. La línea puede tener una serie de elementos gráficos que expresan características particulares de la asociación. A continuación se verán los más importantes de entre dichos elementos gráficos.
II.3.3.1 Nombre de
El nombre de la asociación es opcional y se muestra como un texto que está próximo a la línea. Se puede añadir un pequeño triángulo negro sólido que indique la dirección en la cual leer el nombre de la asociación. En el ejemplo de
Los nombres de las asociaciones normalmente se incluyen en los modelos para aumentar la legibilidad. Sin embargo, en ocasiones pueden hacer demasiado abundante la información que se presenta, con el consiguiente riesgo de saturación. En ese caso se puede suprimir el nombre de las asociaciones consideradas como suficientemente conocidas. En las asociaciones de tipo agregación y de herencia no se suele poner el nombre.
II.3.3.2 Multiplicidad
La multiplicidad es una restricción que se pone a una asociación, que limita el número de instancias de una clase que pueden tener esa asociación con una instancia de la otra clase. Puede expresarse de las siguientes formas:
• Con un número fijo: 1.
• Con un intervalo de valores: 2..5.
• Con un rango en el cual uno de los extremos es un asterisco. Significa que es un intervalo abierto. Por ejemplo, 2..* significa 2 o más.
• Con una combinación de elementos como los anteriores separados por comas: 1, 3..5, 7, 15..*.
• Con un asterisco: * . En este caso indica que puede tomar cualquier valor (cero o más).
II.3.3.3 Roles
Para indicar el papel que juega una clase en una asociación se puede especificar un nombre de rol.
Se representa en el extremo de la asociación junto a la clase que desempeña dicho rol.
II.3.3.4 Agregación
El símbolo de agregación es un diamante colocado en el extremo en el que está la clase que representa el “todo”.
II.3.3.5 Clases Asociación
Cuando una asociación tiene propiedades propias se representa como una clase unida a la línea de la asociación por medio de una línea a trazos. Tanto la línea como el rectángulo de clase representan el mismo elemento conceptual: la asociación. Por tanto ambos tienen el mismo nombre, el de la asociación. Cuando la clase asociación sólo tiene atributos el nombre suele ponerse sobre la línea (como ocurre en el ejemplo de
II.3.3.6 Asociaciones N-Arias
En el caso de una asociación en la que participan más de dos clases, las clases se unen con una línea a un diamante central. Si se muestra multiplicidad en un rol, representa el número potencial de tuplas de instancias en la asociación cuando el resto de los N-1 valores están fijos. En
II.3.3.7 Navegabilidad
En un extremo de una asociación se puede indicar la navegabilidad mediante una flecha. Significa que es posible "navegar" desde el objeto de la clase origen hasta el objeto de la clase destino. Se trata de un concepto de diseño, que indica que un objeto de la clase origen conoce al (los) objeto(s) de la clase destino, y por tanto puede llamar a alguna de sus operaciones.
II.3.4 Herencia
La relación de herencia se representa mediante un triángulo en el extremo de la relación que corresponde a la clase más general o clase “padre”.
Si se tiene una relación de herencia con varias clases subordinadas, pero en un diagrama concreto no se quieren poner todas, esto se representa mediante puntos suspensivos. En el ejemplo de
II.3.5 Elementos Derivados
Un elemento derivado es aquel cuyo valor se puede calcular a partir de otros elementos presentes en el modelo, pero que se incluye en el modelo por motivos de claridad o como decisión de diseño. Se representa con una barra “/” precediendo al nombre del elemento derivado.
II.4 Diagrama de Casos de Uso
Un Diagrama de Casos de Uso muestra la relación entre los actores y los casos de uso del sistema. Representa la funcionalidad que ofrece el sistema en lo que se refiere a su interacción externa. En el diagrama de casos de uso se representa también el sistema como una caja rectangular con el nombre en su interior. Los casos de uso están en el interior de la caja del sistema, y los actores fuera, y cada actor está unido a los casos de uso en los que participa mediante una línea. En
II.4.1 Elementos
Los elementos que pueden aparecer en un Diagrama de Casos de Uso son: actores, casos de uso y relaciones entre casos de uso.
II.4.1.1 Actores
Un actor es algo con comportamiento, como una persona (identificada por un rol), un sistema informatizado u organización, y que realiza algún tipo de interacción con el sistema.. Se representa mediante una figura humana dibujada con palotes. Esta representación sirve tanto para actores que son personas como para otro tipo de actores.
II.4.1.2 Casos de Uso
Un caso de uso es una descripción de la secuencia de interacciones que se producen entre un actor y el sistema, cuando el actor usa el sistema para llevar a cabo una tarea específica. Expresa una unidad coherente de funcionalidad, y se representa en el Diagrama de Casos de Uso mediante una elipse con el nombre del caso de uso en su interior. El nombre del caso de uso debe reflejar la tarea específica que el actor desea llevar a cabo usando el sistema.
II.4.1.3 Relaciones entre Casos de Uso
Un caso de uso, en principio, debería describir una tarea que tiene un sentido completo para el usuario. Sin embargo, hay ocasiones en las que es útil describir una interacción con un alcance menor como caso de uso. La razón para utilizar estos casos de uso no completos en algunos casos, es mejorar la comunicación en el equipo de desarrollo, el manejo de la documentación de casos de uso. Para el caso de que queramos utilizar estos casos de uso más pequeños, las relaciones entre estos y los casos de uso ordinarios pueden ser de los siguientes tres tipos: • Incluye (<>): Un caso de uso base incorpora explícitamente a otro caso de uso en un lugar especificado en dicho caso base. Se suele utilizar para encapsular un comportamiento parcial común a varios casos de uso. En
Figura 16 - Ejemplo de Relación <> • Extiende (<>): Cuando un caso de uso base tiene ciertos puntos (puntos de extensión) en los cuales, dependiendo de ciertos criterios, se va a realizar una interacción adicional. El caso de uso que extiende describe un comportamiento opcional del sistema (a diferencia de la relación incluye que se da siempre que se realiza la interacción descrita) En
Figura 17 - Ejemplo de Relación <>
Ambos tipos de relación se representan como una dependencia etiquetada con el estereotipo correspondiente (<> o <>), de tal forma que la flecha indique el sentido en el que debe leerse la etiqueta. Junto a la etiqueta <> se puede detallar el/los puntos de extensión del caso de uso base en los que se aplica la extensión. • Generalización ( ): Cuando un caso de uso definido de forma abstracta se particulariza por medio de otro caso de uso más específico. Se representa por una línea continua entre los dos casos de uso, con el triángulo que simboliza generalización en UML (usado también para denotar la herencia entre clases) pegado al extremo del caso de uso más general. Al igual que en la herencia entre clases, el caso de uso hijo hereda las asociaciones y características del caso de uso padre. El caso de uso padre se trata de un caso de uso abstracto, que no está definido completamente. Este tipo de relación se utiliza mucho menos que las dos anteriores.
II.5 Diagramas de Interaccion
En los diagramas de interacción se muestra un patrón de interacción entre objetos. Hay dos tipos de diagrama de interacción, ambos basados en la misma información, pero cada uno enfatizando un aspecto particular: Diagramas de Secuencia y Diagramas de Colaboración.
II.5.1 Diagrama de Secuencia
Un diagrama de Secuencia muestra una interacción ordenada según la secuencia temporal de eventos. En particular, muestra los objetos participantes en la interacción y los mensajes que intercambian ordenados según su secuencia en el tiempo. El eje vertical representa el tiempo, y en el eje horizontal se colocan los objetos y actores participantes en la interacción, sin un orden prefijado. Cada objeto o actor tiene una línea vertical, y los mensajes se representan mediante flechas entre los distintos objetos. El tiempo fluye de arriba abajo. Se pueden colocar etiquetas (como restricciones de tiempo, descripciones de acciones, etc.) bien en el margen izquierdo o bien junto a las transiciones o activaciones a las que se refieren.
Figura 18 Diagrama de Secuencia
II.5.2 Diagrama de Colaboración
Un Diagrama de Colaboración muestra una interacción organizada basándose en los objetos que toman parte en la interacción y los enlaces entre los mismos (en cuanto a la interacción se refiere). A diferencia de los Diagramas de Secuencia, los Diagramas de Colaboración muestran las relaciones entre los roles de los objetos. La secuencia de los mensajes y los flujos de ejecución concurrentes deben determinarse explícitamente mediante números de secuencia.
En cuanto a la representación, un Diagrama de Colaboración muestra a una serie de objetos con los enlaces entre los mismos, y con los mensajes que se intercambian dichos objetos. Los mensajes son flechas que van junto al enlace por el que “circulan”, y con el nombre del mensaje y los parámetros (si los tiene) entre paréntesis. Cada mensaje lleva un número de secuencia que denota cuál es el mensaje que le precede, excepto el mensaje que inicia el diagrama, que no lleva número de secuencia. Se pueden indicar alternativas con condiciones entre corchetes (por ejemplo 3 [condición_de_test] : nombre_de_método() ), tal y como aparece en el ejemplo de
II.6 Diagramas de Estado
Un Diagrama de Estados muestra la secuencia de estados por los que pasa bien un caso de uso, bien un objeto a lo largo de su vida, o bien todo el sistema. En él se indican qué eventos hacen que se pase de un estado a otro y cuáles son las respuestas y acciones que genera.
En cuanto a la representación, un diagrama de estados es un grafo cuyos nodos son estados y cuyos arcos dirigidos son transiciones etiquetadas con los nombres de los eventos.
Un estado se representa como una caja redondeada con el nombre del estado en su interior. Una transición se representa como una flecha desde el estado origen al estado destino.
La caja de un estado puede tener 1 o 2 compartimentos. En el primer compartimento aparece el nombre del estado. El segundo compartimento es opcional, y en él pueden aparecer acciones de entrada, de salida y acciones internas.
Una acción de entrada aparece en la forma entrada/acción_asociada donde acción_asociada es el nombre de la acción que se realiza al entrar en ese estado. Cada vez que se entra al estado por medio de una transición la acción de entrada se ejecuta.
Una acción de salida aparece en la forma salida/acción_asociada. Cada vez que se sale del estado por una transición de salida la acción de salida se ejecuta.
Una acción interna es una acción que se ejecuta cuando se recibe un determinado evento en ese estado, pero que no causa una transición a otro estado. Se indica en la forma nombre_de_evento/acción_asociada.
Un diagrama de estados puede representar ciclos continuos o bien una vida finita, en la que hay un estado inicial de creación y un estado final de destrucción (finalización del caso de uso o destrucción del objeto). El estado inicial se muestra como un círculo sólido y el estado final como un círculo sólido rodeado de otro círculo. En realidad, los estados inicial y final son pseudoestados, pues un objeto no puede “estar” en esos estados, pero nos sirven para saber cuáles son las transiciones inicial y final(es).
III.1 Modelado Dinámico
III.1.1 Diagramas De Actividades
Vamos a recordar los diferentes modelos que sirven para representar el aspecto dinámico de un sistema:
• Diagramas de secuencia
• Diagramas de colaboración
• Diagramas de estados
• Diagramas de casos de uso
• Diagramas de actividades
En este capítulo nos centraremos en los diagramas de actividades que sirven fundamentalmente para modelar el flujo de control entre actividades. La idea es generar una especie de diagrama Pert, en el que se puede ver el flujo de actividades que tienen lugar a lo largo del tiempo, así como las tareas concurrentes que pueden realizarse a la vez. El diagrama de actividades sirve para representar el sistema desde otra perspectiva, y de este modo complementa a los anteriores diagramas vistos. Gráficamente un diagrama de actividades será un conjunto de arcos y nodos. Desde un punto de vista conceptual, el diagrama de actividades muestra cómo fluye el control de unas clases a otras con la finalidad de culminar con un flujo de control total que se corresponde con la consecución de un proceso más complejo. Por este motivo, en un diagrama de actividades aparecerán acciones y actividades correspondientes a distintas clases. Colaborando todas ellas para conseguir un mismo fin. Ejemplo: Hacer un pedido.
III.1.2 Contenido del diagrama de actividades
Básicamente un diagrama de actividades contiene:
• Estados de actividad
• Estados de acción
• Transiciones
• Objetos
III.1.2.1 Estados de actividad y estados de acción
La representación de ambos es un rectángulo con las puntas redondeadas, en cuyo interior se representa bien una actividad o bien una acción. La forma de expresar tanto una actividad como una acción, no queda impuesta por UML, se podría utilizar lenguaje natural, una especificación formal de expresiones, un metalenguaje, etc. La idea central es la siguiente: “Un estado que represente una acción es atómico, lo que significa que su ejecución se puede considerar instantánea y no puede ser interrumpida” En
Figura 21 Estados de Acción
En cambio un estado de actividad, sí puede descomponerse en más sub-actividades representadas a través de otros diagramas de actividades. Además estos estados sí pueden ser interrumpidos y tardan un cierto tiempo en completarse. En los estados de actividad podemos encontrar otros elementos adicionales como son: acciones de entrada (entry) y de salida (exit) del estado en cuestión, así como definición de submáquinas, como podemos ver en
Figura 22 Estado de Actividad
III.1.2.2 Transiciones
Las transiciones reflejan el paso de un estado a otro, bien sea de actividad o de acción. Esta transición se produce como resultado de la finalización del estado del que parte el arco dirigido que marca la transición. Como todo flujo de control debe empezar y terminar en algún momento, podemos indicar esto utilizando dos disparadores de inicio y fin tal y como queda reflejado en el ejemplo de
Figura 23 Transiciones sin disparadores
III.1.2.3 Bifurcaciones
Un flujo de control no tiene porqué ser siempre secuencial, puede presentar caminos alternativos. Para poder representar dichos caminos alternativos o bifurcación se utilizará como símbolo el rombo. Dicha bifurcación tendrá una transición de entrada y dos o más de salida. En cada transición de salida se colocará una expresión booleana que será evaluada una vez al llegar a la bifurcación, las guardas de la bifurcación han de ser excluyentes y contemplar todos los casos ya que de otro modo la ejecución del flujo de control quedaría interrumpida. Para poder cubrir todas las posibilidades se puede utilizar la palabra ELSE, para indicar una transición obligada a un determinado estado cuando el resto de guardas han fallado. En
Figura 24 Bifurcación
III.1.2.4 División y unión
No sólo existe el flujo secuencial y la bifurcación, también hay algunos casos en los que se requieren tareas concurrentes. UML representa gráficamente el proceso de división, que representa la concurrencia, y el momento de la unión de nuevo al flujo de control secuencial, por una línea horizontal ancha. En
Figura 25 División y unión
III.1.2.5 Calles
Cuando se modelan flujos de trabajo de organizaciones, es especialmente útil dividir los estados de actividades en grupos, cada grupo tiene un nombre concreto y se denominan calles. Cada calle representa a la parte de la organización responsable de las actividades que aparecen en esa calle. Gráficamente quedaría como se muestra en
Figura 26 Calles
Modelado Físico De Un Sistema OO
III.2.1 Componentes
Los componentes pertenecen al mundo físico, es decir, representan un bloque de construcción al modelar aspectos físicos de un sistema.
Una característica básica de un componente es que:
“debe definir una abstracción precisa con una interfaz bien definida, y permitiendo reemplazar fácilmente los componentes más viejos con otros más nuevos y compatibles.”
En UML todos los elementos físicos se modelan como componentes. UML proporciona una representación gráfica para estos como se puede ver en
Figura 27 Representación de un componente
Cada componente debe tener un nombre que lo distinga de los demás. Al igual que las clases los componentes pueden enriquecerse con compartimentos adicionales que muestran sus detalles, como se puede ver en
Figura 28 Representación extendida de un componente
Vamos a ver con más detalle cuáles son los parecidos y las diferencias entre los componentes y las clases.
PARECIDOS
Ambos tienen nombre
Ambos pueden realizar un conjunto de interfaces.
Pueden participar en relaciones de dependencia, generalización y asociación.
Ambos pueden anidarse
Ambos pueden tener instancias
Ambos pueden participar en interacciones
DIFERENCIAS
Las Clases Los Componentes
Representan abstracciones lógicas Representan elementos físicos
Es decir los componentes pueden estar en nodos y las clases no
Pueden tener atributos y operacionesdirectamente accesibles. Sólo tienen operaciones y estas son alcanzables a través de la interfaz del componente.
III.2.1.1 Interfaces
Tanto los servicios propio de una clase como los de un componente, se especifican a través de una Interfaz. Por ejemplo, todas las facilidades más conocidas de los sistemas operativos, basados en componentes (COM+, CORBA, etc.), utilizan las interfaces como lazo de unión entre unos componentes y otros. La relación entre un componente y sus interfaces se puede representar de dos maneras diferentes, de forma icónica como se indica en
Figura 29 Componentes e interfaces, formato icónico
Figura 30 Componentes e interfaces, formato extendido
III.2.1.2 Tipos de componentes
Existen básicamente tres tipos de componentes:
? Componentes de despliegue: componentes necesarios y suficientes para formar un sistema ejecutable, como pueden ser las bibliotecas dinámicas (DLLs) y ejecutables (EXEs).
? Componentes producto del trabajo: estos componentes son básicamente productos que quedan al final del proceso de desarrollo. Consisten en cosas como archivos de código fuente y de datos a partir de los cuales se crean los componentes de despliegue.
? Componentes de ejecución: son componentes que se crean como consecuencia de un sistema en ejecución. Es el caso de un objeto COM+ que se instancia a partir de una DLL.
III.2.1.3 Organización de componentes
Los componentes se pueden agrupar en paquetes de la misma forma que se organizan las clases. Además se pueden especificar entre ellos relaciones de dependencia, generalización, asociación (incluyendo agregación), y realización.
III.2.1.4 Estereotipos de componentes
UML define cinco estereotipos estándar que se aplican a los componentes:
executable Componente que se puede ejecutar en un nodo.
library Biblioteca de objetos estática o dinámica.
table Componentes que representa una tabla de una base de datos.
file Componente que representa un documento que contiene código fuente o datos.
document Componente que representa un documento.
UML no especifica iconos predefinidos para estos estereotipos.
III.2.2 Despliegue
III.2.2.1 Nodos
Al igual que los componentes los nodos pertenecen al mundo material. Vamos a definir un nodo como un elemento físico, que existe en tiempo de ejecución y representa un recurso computacional que generalmente tiene alguna memoria y, a menudo, capacidad de procesamiento. Los nodos sirven para modelar la topología del hardware sobre el que se ejecuta el sistema. Un nodo representa normalmente un procesador o un dispositivo sobre el que se pueden desplegar los componentes. Un nodo debe tener un nombre asignado que lo distinga del resto de nodos. Además los nodos se representan gráficamente como se indica en
Figura 31 Nodos
III.2.2.2 Nodos y componentes
En muchos aspectos los nodos y los componentes tienen características parecidas. Vamos a ver con más detalle cuales son los parecidos y las diferencias entre los componentes y los nodos.
PARECIDOS
Ambos tienen nombre
Pueden participar en relaciones de dependencia, generalización y asociación.
Ambos pueden anidarse
Ambos pueden tener instancias
Ambos pueden participar en interacciones
DIFERENCIAS
Los Nodos Los Componentes
Son los elementos donde se ejecutan los componentes. Son los elementos que participan en la ejecución de un sistema.
Representan el despliegue físico de los componentes. Representan el empaquetamiento físico de los elementos lógicos.
La relación entre un nodo y los componentes que despliega se pueden representar mediante una relación de dependencia como se indica en
Los nodos se pueden agrupar en paquetes igual que los las clases y los componentes.
Los tipos de relación más común entre nodos es la asociación. Una asociación entre nodos viene a representar una conexión física entre nodos como se puede ver en
Figura 32 Relación entre nodos y componentes
Figura 33 Conexiones entre nodos
Existen dos tipos de diagramas que sirven para modelar los aspectos físicos de un sistema orientado a objetos:
• Diagramas de Componentes
• Diagramas de Despliegue
Seguidamente veremos para qué sirve cada uno de ellos y cual es su representación gráfica.
III.2.3 Diagramas de Componentes
Un diagrama de componentes muestra la organización y las dependencias entre un conjunto de componentes. Para todo sistema OO se han de construir una serie de diagramas que modelan tanto la parte estática (diagrama de clases), como dinámica (diagramas de secuencia, colaboración, estados y de actividades), pero llegado el momento todo esto se debe materializar en un sistema implementado que utilizará partes ya implementadas de otros sistemas, todo esto es lo que pretendemos modelar con los diagramas de componentes.
III.2.3.1 Algunos conceptos
Un diagrama de componentes muestra un conjunto de componentes y sus relaciones de manera gráfica a través del uso de nodos y arcos entre estos.
Normalmente los diagramas de componentes contienen:
• Componentes
• Interfaces
• Relaciones de dependencia, generalización, asociaciones y realización.
• Paquetes o subsistemas
• Instancias de algunas clases
Visto de otro modo un diagrama de componentes puede ser un tipo especial de diagrama de clases que se centra en los componentes físicos del sistema.
III.2.3.2 Usos más comunes
a) Modelado de Código Fuente
Los diagramas de componentes se pueden utilizar para modelar la gestión de la configuración de los archivos de código fuente, tomando como productos de trabajo precisamente estos ficheros. Esto resulta bastante útil por ejemplo cuando se han implementado unas partes con Java otras con C, etc. El resultado de esta implementación pueden ser multitud de ficheros ejecutables con características particulares, de manera que la mejor forma de controlarlos es estableciendo gestión de configuración.
Para poder llevar a cabo esta gestión con éxito será necesario definir los estereotipos de ficheros que se quieren tener bajo control así como las relaciones entre dichos tipos de ficheros.
Para modelar el código fuente de un sistema:
• Hay que identificar el conjunto de archivos de código fuente de interés y modelarlos como componentes estereotipados como archivos.
• Si el sistema es muy grande es necesario utilizar los paquetes para agrupar los archivos de código fuente.
• Es necesario identificar la versión del componente.
b) Modelado de una versión ejecutable y bibliotecas.
La utilización de los componentes para modelar versiones ejecutables se centra en la definición de todos los elementos que componen lo que se conoce como versión ejecutable, es decir la documentación, los ficheros que se entregan etc.
Para modelar una versión ejecutable es preciso:
• Identificar el conjunto de componentes que se pretende modelar.
• Identificar el estereotipo de cada componente del conjunto seleccionado.
• Para cada componente de este conjunto hay que considerar las relaciones con los vecinos. Esto implica definir las interfaces importadas por ciertos componentes y las exportadas por otros.
c) Modelado de una base de datos física
Para modelar una base de datos física es necesario:
• Identificar las clases del modelo que representan el esquema lógico de la base de datos.
• Seleccionar una estrategia para hacer corresponder las clases con tablas. Así como la distribución física de la/s base/s de datos.
• Para poder visualizar, especificar, construir y documentar dicha correspondencia es necesario crear un diagrama de componentes que tenga componentes estereotipados como tablas.
• Donde sea posible es aconsejable utilizar herramientas que ayuden a transformar diseño lógico en físico.
III.2.4 Diagramas de Despliegue
III.2.4.1 Técnicas más comunes de modelado
a) Modelado de un sistema empotrado
El desarrollo de un sistema empotrado es más que el desarrollo de un sistema software. Hay que manejar el mundo físico. Los diagramas de despliegue son útiles para facilitar la comunicación entre los ingenieros de hardware y los de software.
Para modelar un sistema empotrado es necesario:
• Identificar los dispositivos y nodos propios del sistema.
• Proporcionar señales visuales, sobre todo para los dispositivos poco usuales.
• Modelar las relaciones entre esos procesadores y dispositivos en un diagrama de despliegue.
• Si es necesario hay que detallar cualquier dispositivo inteligente, modelando su estructura en un diagrama de despliegue más pormenorizado.
b) Modelado de un sistema cliente servidor
La división entre cliente y servidor en un sistema es complicada ya que implica tomar algunas decisiones sobre dónde colocar físicamente sus componentes software, qué cantidad de software debe residir en el cliente, etc.
Para modelar un sistema cliente/servidor hay que hace lo siguiente:
• Identificar los nodos que representan los procesadores cliente y servidor del sistema.
• Destacar los dispositivos relacionados con el comportamiento del sistema.
• Proporcionar señales visuales para esos procesadores y dispositivos a través de estereotipos.
• Modelar la tipología de esos nodos mediante un diagrama de despliegue.
III.2.5 Arquitectura del Sistema
III.2.5.1 Arquitectura de tres niveles
La llamada “Arquitectura en Tres Niveles”, es la más común en sistemas de información que además de tener una interfaz de usuario contemplan la persistencia de los datos.
Una descripción de los tres niveles sería la siguiente:
Nivel 1: Presentación – ventanas, informes, etc.
Nivel 2: Lógica de
Nivel 3: Almacenamiento – mecanismo de almacenamiento.
III.2.5.2 Arquitectura de tres niveles orientadas a objetos
a) Descomposición del nivel de lógica de la aplicación
En el diseño orientado a objetos, el nivel de lógica de la aplicación se descompone en sub-niveles que son los siguientes:
Objetos del Dominio: son clases que representan objetos del dominio. Por ejemplo en un problema de ventas, una “Venta” sería un objeto del dominio.
Servicios: se hace referencia a funciones de interacción con la base de datos, informes, comunicaciones, seguridad, etc.
III.2.5.3 Arquitectura MULTI-nivel
La arquitectura de tres niveles puede pasar a llamarse de Múltiples Niveles si tenemos en cuenta el hecho de que todos los niveles de la arquitectura de tres niveles se pueden descomponer cada uno de ellos cada vez más.
Por ejemplo el nivel de Servicios, se puede descomponer en servicios de alto y de bajo nivel, identificando como de alto nivel los servicios de generación de informes y como de bajo nivel los de manejo de ficheros de entrada y salida.
El motivo que lleva a descomponer la arquitectura del sistema en diferentes niveles es múltiple:
• Separación de la lógica de la aplicación en componentes separados que sean más fácilmente reutilizables.
• Distribución de niveles en diferentes nodos físicos de computación.
• Reparto de recursos humanos en diferentes niveles de la arquitectura.
III.2.5.4 Paquetes
La forma que tiene UML de agrupar elementos en subsistemas es a través del uso de Paquetes, pudiéndose anidar los paquetes formando jerarquías de paquetes. De hecho un sistema que no tenga necesidad de ser descompuesto en subsistemas se puede considerar como con un único paquete que lo abarca todo.
Gráficamente un paquete viene representado como se indica en
Figura 34 Representación de un paquete en UML
En
Figura 35 Arquitectura de un sistema utilizando paquetes
III.2.5.5 Identificación de Paquetes
Vamos a definir una serie de reglas que nos pueden ser de utilidad a la hora de agrupar los diferentes elementos en paquetes.
• Conviene agrupar elementos que proporcionen un mismo servicio.
• Los elementos que se agrupen en un mismo paquete han de presentar un alto grado de cohesión, es decir deben estar muy relacionados.
• Los elementos que estén en diferentes paquetes deben tener poca relación, es decir deben colaborar lo menos posible.
IV.1 Proceso de Desarrollo
Cuando se va a construir un sistema software es necesario conocer un lenguaje de programación, pero con eso no basta. Si se quiere que el sistema sea robusto y mantenible es necesario que el problema sea analizado y la solución sea cuidadosamente diseñada. Se debe seguir un proceso robusto, que incluya las actividades principales. Si se sigue un proceso de desarrollo que se ocupa de plantear cómo se realiza el análisis y el diseño, y cómo se relacionan los productos de ambos, entonces la construcción de sistemas software va a poder ser planificable y repetible, y la probabilidad de obtener un sistema de mejor calidad al final del proceso aumenta considerablemente, especialmente cuando se trata de un equipo de desarrollo formado por varias personas.
Para este curso se va a seguir el método de desarrollo orientado a objetos que propone Craig Larman [Larman99]. Este proceso no fija una metodología estricta, sino que define una serie de actividades que pueden realizarse en cada fase, las cuales deben adaptarse según las condiciones del proyecto que se esté llevando a cabo. Se ha escogido seguir este proceso debido a que aplica los últimos avances en Ingeniería del Software, y a que adopta un enfoque eminentemente práctico, aportando soluciones a las principales dudas y/o problemas con los que se enfrenta el desarrollador. Su mayor aportación consiste en atar los cabos sueltos que anteriores métodos dejan.
La notación que se usa para los distintos modelos, tal y como se ha dicho anteriormente, es la proporcionada por UML, que se ha convertido en el estándar de facto en cuanto a notación orientada a objetos. El uso de UML permite integrar con mayor facilidad en el equipo de desarrollo a nuevos miembros y compartir con otros equipos la documentación, pues es de esperar que cualquier desarrollador versado en orientación a objetos conozca y use UML (o se esté planteando su uso).
Se va a abarcar todo el ciclo de vida, empezando por los requisitos y acabando en el sistema funcionando, proporcionando así una visión completa y coherente de la producción de sistemas software. El enfoque que toma es el de un ciclo de vida iterativo incremental, el cual permite una gran flexibilidad a la hora de adaptarlo a un proyecto y a un equipo de desarrollo específicos. El ciclo de vida está dirigido por casos de uso, es decir, por la funcionalidad que ofrece el sistema a los futuros usuarios del mismo. Así no se pierde de vista la motivación principal que debería estar en cualquier proceso de construcción de software: el resolver una necesidad del usuario/cliente.
IV.1.1 Visión General
El proceso a seguir para realizar desarrollo orientado a objetos es complejo, debido a la complejidad que nos vamos a encontrar al intentar desarrollar cualquier sistema software de tamaño medio-alto. El proceso está formado por una serie de actividades y subactividades, cuya realización se va repitiendo en el tiempo aplicadas a distintos elementos.
En este apartado se va a presentar una visión general para poder tener una idea del proceso a alto nivel, y más adelante se verán los pasos que componen cada fase.
Las tres fases al nivel más alto son las siguientes:
• Planificación y Especificación de Requisitos: Planificación, definición de requisitos, construcción de prototipos, etc.
• Construcción: La construcción del sistema. Las fases dentro de esta etapa son las siguientes:
- Diseño de Alto Nivel: Se analiza el problema a resolver desde la perspectiva de los usuarios y de las entidades externas que van a solicitar servicios al sistema.
- Diseño de Bajo Nivel: El sistema se especifica en detalle, describiendo cómo va a funcionar internamente para satisfacer lo especificado en el Diseño de Alto Nivel.
- Implementación: Se lleva lo especificado en el Diseño de Bajo Nivel a un lenguaje de programación.
- Pruebas: Se llevan a cabo una serie de pruebas para corroborar que el software funciona correctamente y que satisface lo especificado en la etapa de Planificación y Especificación de Requisitos.
• Instalación: La puesta en marcha del sistema en el entorno previsto de uso.
De ellas, la fase de Construir es la que va a consumir la mayor parte del esfuerzo y del tiempo en un proyecto de desarrollo. Para llevarla a cabo se va adoptar un enfoque iterativo, tomando en cada iteración un subconjunto de los requisitos (agrupados según casos de uso) y llevándolo a través del diseño de alto y bajo nivel hasta la implementación y pruebas, tal y como se muestra en
Figura 36 Desarrollo Iterativo en
Fase de Planificación y Especificación de Requisitos
Esta fase se corresponde con
IV.2.1 Actividades
Las actividades de esta fase son las siguientes:
• Definir el Plan-Borrador.
• Crear el Informe de Investigación Preliminar.
• Definir los Requisitos.
• Registrar Términos en el Glosario. (continuado en posteriores fases)
• Implementar un Prototipo. (opcional)
• Definir Casos de Uso (de alto nivel y esenciales).
• Definir el Modelo Conceptual-Borrador. (puede retrasarse hasta una fase posterior)
• Definir
• Refinar el Plan.
El orden no es estricto, lo normal es que las distintas actividades se solapen en el tiempo. Esto sucede también en las actividades de las fases de diseño, que se verán más adelante.
De estas actividades no se va a entrar en las que corresponden al campo de la planificación de proyectos software, como las correspondientes a creación de planes e informes preliminares.
IV.2.2 Requisitos
El formato del documento de Especificación de Requisitos no está definido en UML, pero se ha incluido este punto para resaltar que la actividad de definición de requisitos es un paso clave en la creación de cualquier producto software. Para entender y describir los requisitos la técnica de casos de uso constituye una valiosa ayuda.
IV.2.3 Casos de Uso
Un Caso de Uso es un documento narrativo que describe a los actores utilizando un sistema para satisfacer un objetivo. Es una historia o una forma particular de usar un sistema. Los casos de uso son requisitos, en particular requisitos funcionales.
Nótese que UML no define un formato para describir un caso de uso. Tan sólo define la manera de representar la relación entre actores y casos de uso en un diagrama: El Diagrama de Casos de Uso, definido en la página 9. Sin embargo, un caso de uso individual no es un diagrama, es un documento de texto. En la siguiente sección se define el formato textual para la descripción de un caso de uso que se va a utilizar en este documento..
Un escenario es un camino concreto a través del caso de uso, una secuencia específica de acciones e interacciones entre los actores y el sistema. Más adelante se verá la representación de los escenarios correspondientes a un caso de uso por medio de Diagramas de Secuencia.
En un primer momento interesa abordar un caso de uso desde un nivel de abstracción alto, utilizando el formato de alto nivel. Cuando se quiere describir un caso de uso con más detalle se usa el formato expandido.
IV.2.3.1 Casos de Uso de Alto Nivel
El siguiente Caso de Uso de Alto Nivel describe el proceso de sacar dinero cuando se está usando un cajero automático:
- Caso de Uso: Realizar Reintegro
- Actores: Cliente
- Tipo: primario
- Descripción: Un Cliente llega al cajero automático, introduce la tarjeta, se identifica y solicita realizar una operación de reintegro por una cantidad específica. El cajero le da el dinero solicitado tras comprobar que la operación puede realizarse. El Cliente coge el dinero y la tarjeta y se va.
En un caso de uso descrito a alto nivel la descripción es muy general, normalmente se condensa en dos o tres frases. Es útil para comprender el ámbito y el grado de complejidad del sistema.
IV.2.3.2 Casos de Uso Expandidos
Los casos de uso que se consideren los más importantes y que se considere que son los que más influencian al resto, se describen a un nivel más detallado: en el formato expandido.
La principal diferencia con un caso de uso de alto nivel está en que incluye un apartado de Curso Típico de Eventos, pero también incluye otros apartados como se ve en el siguiente ejemplo:
- Caso de Uso: Realizar Reintegro
- Actores: Cliente (iniciador)
- Propósito: Realizar una operación de reintegro de una cuenta del banco
- Visión General: Un Cliente llega al cajero automático, introduce la tarjeta, se identifica y solicita realizar una operación de reintegro por una cantidad específica. El cajero le da el dinero solicitado tras comprobar que la operación puede realizarse. El Cliente coge el dinero y la tarjeta y se va.
- Tipo: primario y esencial
- Referencias: Funciones: R1.3, R1.7
- Curso Típico de Eventos:
Acción del Actor Respuesta del Sistema
1. Este caso de uso empieza cuando un Cliente introduce una tarjeta en el cajero.
2. Pide la clave de identificación.
3. Introduce la clave.
4. Presenta las opciones de operaciones disponibles.
5. Selecciona la operación de Reintegro.
6. Pide la cantidad a retirar.
7. Introduce la cantidad requerida.
8. Procesa la petición y da el dinero solicitado. Devuelve la tarjeta y genera un recibo.
9. Recoge la tarjeta.
10. Recoge el recibo.
11. Recoge el dinero y se va.
Cursos Alternativos:
• Línea 4: La clave es incorrecta. Se indica el error y se cancela la operación.
• Línea 8: La cantidad solicitada supera el saldo. Se indica el error y se cancela la operación.
El significado de cada apartado de este formato es como sigue:
- Caso de Uso: Nombre del Caso de Uso
- Actores: Lista de actores (agentes externos), indicando quién inicia el caso de uso. Los actores son normalmente roles que un ser humano desempeña, pero puede ser cualquier tipo de sistema.
- Propósito: Intención del caso de uso.
- Visión General: Repetición del caso de uso de alto nivel, o un resumen similar.
- Tipo: 1. primario, secundario u opcional (descritos más adelante).
2. esencial o real (descritos más adelante). - Referencias: Casos de uso relacionados y funciones del sistema que aparecen en los requisitos.
- Curso Típico de Eventos: Descripción de la interacción entre los actores y el sistema mediante las acciones numeradas de cada uno. Describe la secuencia más común de eventos, cuando todo va bien y el proceso se completa satisfactoriamente. En caso de haber alternativas con grado similar de probabilidad se pueden añadir secciones adicionales a la sección principal, como se verá más adelante.
- Cursos Alternativos: Puntos en los que puede surgir una alternativa, junto con la descripción de la excepción.
IV.2.3.3 Identificación de Casos de Uso
La identificación de casos de uso requiere un conocimiento medio acerca de los requisitos, y se basa en la revisión de los documentos de requisitos existentes, y en el uso de la técnica de brainstorming entre los miembros del equipo de desarrollo.
Como guía para la identificación inicial de casos de uso hay dos métodos:
a) Basado en Actores
1. Identificar los actores relacionados con el sistema y/o la organización.
2. Para cada actor, identificar los procesos que inicia o en los que participa.
b) Basado en Eventos
1. Identificar los eventos externos a los que el sistema va a tener que responder.
2. Relacionar los eventos con actores y casos de uso.
Ejemplos de casos de uso:
• Pedir un producto.
• Matricularse en un curso de la facultad.
• Comprobar la ortografía de un documento en un procesador de textos.
• Comprar un libro en una tienda de libros en Internet
IV.2.3.4 Identificación de los Límites del Sistema
En la descripción de un caso de uso se hace referencia en todo momento al “sistema”. Para que los casos de uso tengan un significado completo es necesario que el sistema esté definido con precisión.
Al definir los límites del sistema se establece una diferenciación entre lo que es interno y lo que es externo al sistema. El entorno exterior se representa mediante los actores.
Ejemplos de sistemas son:
• El hardware y software de un sistema informático.
• Un departamento de una organización.
• Una organización entera.
Si no se está haciendo reingeniería del proceso de negocio lo más normal es escoger como sistema el primero de los ejemplos: el hardware y el software del sistema que se quiere construir.
IV.2.3.5 Tipos de Casos de Uso
a) Según Importancia
Para establecer una primera aproximación a la priorización de casos de uso que identifiquemos los vamos a distinguir entre:
• Primarios: Representan los procesos principales, los más comunes, como Realizar Reintegro en el caso del cajero automático.
• Secundarios: Representan casos de uso menores, que van a necesitarse raramente, tales como Añadir Nueva Operación.
• Opcionales: Representan procesos que pueden no ser abordados en el presente proyecto.
b) Según el Grado de Compromiso con el Diseño
En las descripciones que se han visto anteriormente no se han hecho apenas compromisos con la solución, se han descrito los casos de uso a un nivel abstracto, independiente de la tecnología y de la implementación. Un caso de uso definido a nivel abstracto se denomina esencial. Los casos de uso definidos a alto nivel son siempre esenciales por naturaleza, debido a su brevedad y abstracción.
Por el contrario, un caso de uso real describe concretamente el proceso en términos del diseño real, de la solución específica que se va a llevar a cabo. Se ajusta a un tipo de interfaz específica, y se baja a detalles como pantallas y objetos en las mismas.
Como ejemplo de una parte de un Caso de Uso Real para el caso del reintegro en un cajero automático tenemos la siguiente descripción del Curso Típico de Eventos:
Acción del Actor Respuesta del Sistema
1. Este caso de uso empieza cuando un Cliente introduce una tarjeta en la ranura para tarjetas. 2. Pide el PIN (Personal Identification Number).
3. Introduce el PIN a través del teclado numérico. 4. Presenta las opciones de operaciones disponibles.
5. etc. 6. etc.
En principio, los casos de uso reales deberían ser creados en la fase de Diseño de Bajo Nivel y no antes. Sin embargo, en algunos proyectos se plantea la definición de interfaces en fases tempranas del ciclo de desarrollo, en base a que son parte del contrato. En este caso se pueden definir algunos o todos los casos de uso reales, a pesar de que suponen tomar decisiones de diseño muy pronto en el ciclo de vida.
No hay una diferencia estricta entre un Caso de Uso Esencial y uno Real, el grado de compromiso con el diseño es un continuo, y una descripción específica de un caso de uso estará situada en algún punto de la línea entre Casos de Uso Esenciales y Reales, normalmente más cercano a un extremo que al otro, pero es raro encontrar Casos de Uso Esenciales o Reales puros.
IV.2.3.6 Consejos Relativos a Casos de Uso
a) Nombre
El nombre de un Caso de Uso debería ser un verbo, para enfatizar que se trata de un proceso, por ejemplo: Comprar Artículos o Realizar Pedido.
b) Alternativas equiprobables
Cuando se tiene una alternativa que ocurre de manera relativamente ocasional, se indica en el apartado Cursos Alternativos. Pero cuando se tienen distintas opciones, todas ellas consideradas normales se puede completar el Curso Típico de Eventos con secciones adicionales.
Así, si en un determinado número de línea hay una bifurcación se pueden poner opciones que dirigen el caso de uso a una sección que se detalla al final del Curso Típico de Eventos, en la siguiente forma:
- Curso Típico de Eventos:
- Sección: Principal
Acción del Actor Respuesta del Sistema
1. Este caso de uso empieza cuando Actor llega al sistema.
2. Pide la operación a realizar.
3. Escoge la operación A.
4. Presenta las opciones de pago.
5. Selecciona el tipo de pago:
a. Si se paga al contado ver sección Pago al Contado.
b. Si se paga con tarjeta ver sección Pago con Tarjeta.
6. Genera recibo.
7. Recoge el recibo y se va.
Cursos Alternativos:
• Líneas 3 y 5: Selecciona Cancelar. Se cancela la operación.
- Sección: Pago al Contado
Acción del Actor Respuesta del Sistema
1. Mete los billetes correspondientes
2. Coge los billetes y sigue pidiendo dinero hasta que la cantidad está satisfecha
3. Devuelve el cambio.
Cursos Alternativos:
• Línea 3: No hay cambio suficiente. Se cancela la operación.
- Sección: Pago con Tarjeta
...
IV.2.4 Construcción del Modelo de Casos de Uso
Para construir el Modelo de Casos de Uso en la fase de Planificación y Especificación de Requisitos se siguen los siguientes pasos:
1. Después de listar las funciones del sistema, se definen los límites del sistema y se identifican los actores y los casos de uso.
2. Se escriben todos los casos de uso en el formato de alto nivel. Se categorizan como primarios, secundarios u opcionales.
3. Se dibuja el Diagrama de Casos de Uso.
4. Se detallan relaciones entre casos de uso, en caso de ser necesarias, y se ilustran tales relaciones en el Diagrama de Casos de Uso.
5. Los casos de uso más críticos, importantes y que conllevan un mayor riesgo, se describen en el formato expandido esencial. Se deja la definición en formato expandido esencial del resto de casos de uso para cuando sean tratados en posteriores ciclos de desarrollo, para no tratar toda la complejidad del problema de una sola vez.
6. Se crean casos de uso reales sólo cuando:
• Descripciones más detalladas ayudan significativamente a incrementar la comprensión del problema.
• El cliente pide que los procesos se describan de esta forma.
7. Ordenar según prioridad los casos de uso (este paso se va a ver a continuación).
IV.2.5 Planificación de Casos de Uso según Ciclos de Desarrollo
La decisión de qué partes del sistema abordar en cada ciclo de desarrollo se va a tomar basándose en los casos de uso. Esto es, a cada ciclo de desarrollo se le va a asignar la implementación de uno o más casos de uso, o versiones simplificadas de casos de uso. Se asigna una versión simplificada cuando el caso de uso completo es demasiado complejo para ser tratado en un solo ciclo (ver Figura 37).
Para tomar la decisión de qué casos de uso se van a tratar primero es necesario ordenarlos según prioridad. Las características de un caso de uso específico que van a hacer que un caso de uso tenga una prioridad alta son las siguientes:
a. Impacto significativo en el diseño de la arquitectura. Por ejemplo, si aporta muchas clases al modelo del dominio o requiere persistencia en los datos.
b. Se obtiene una mejor comprensión del diseño con un nivel de esfuerzo relativamente bajo.
c. Incluye funciones complejas, críticas en el tiempo o de nivel elevado de riesgo.
d. Implica bien un trabajo de investigación significante, o bien el uso de una tecnología nueva o arriesgada.
e. Representa un proceso de gran importancia en la línea de negocio.
f. Supone directamente un aumento de beneficios o una disminución de costes.
Para realizar la clasificación se puede asignar a cada caso de uso una valoración numérica de cada uno de estos puntos, para conseguir una puntuación total aplicando pesos a cada apartado. En la siguiente tabla se muestra un ejemplo de tal tipo de clasificación:
Peso 3 2 4 1 3 4 Suma
Caso de Uso a b c d e f
Realizar reintegro 5 4 1 0 5 2 50
...
IV.2.5.1 Caso de Uso Inicialización
Prácticamente todos los sistemas van a tener un caso de uso Inicialización. Aunque puede ser que no tenga una prioridad alta en la clasificación realizada según el punto anterior, normalmente va a interesar que sea desarrollado desde el principio. Inicialmente se desarrolla una versión simplificada, que se va completando en cada ciclo de desarrollo para satisfacer las necesidades de inicialización de los casos de uso que se tratan en dicho ciclo. Así se tiene un sistema en cada ciclo de desarrollo que puede funcionar.
IV.3 Fase de Construcción: Diseño de Alto Nivel
En la fase de Diseño de Alto Nivel de un ciclo de desarrollo se investiga sobre el problema, sobre los conceptos relacionados con el subconjunto de casos de uso que se esté tratando. Se intenta llegar a una buena comprensión del problema por parte del equipo de desarrollo, sin entrar en cómo va a ser la solución en cuanto a detalles de implementación.
Cuando el ciclo de desarrollo no es el primero, antes de la fase de Diseño de Alto Nivel hay una serie de actividades de planificación. Estas actividades consisten en actualizar los modelos que se tengan según lo que se haya implementado, pues siempre se producen desviaciones entre lo que se ha analizado y diseñado y lo que finalmente se construye. Una vez se tienen los modelos acordes con lo implementado se empieza el nuevo ciclo de desarrollo con la fase de Diseño de Alto Nivel.
En esta fase se trabaja con los modelos de Diseño de Alto Nivel construidos en la fase anterior, ampliándolos con los conceptos correspondientes a los casos de uso que se traten en el ciclo de desarrollo actual.
IV.3.1 Actividades
Las actividades de la fase de Diseño de Alto Nivel son las siguientes:
1. Definir Casos de Uso Esenciales en formato expandido. (si no están definidos )
2. Refinar los Diagramas de Casos de Uso.
3. Refinar el Modelo Conceptual.
4. Refinar el Glosario. (continuado en posteriores fases)
5. Definir los Diagramas de Secuencia del Sistema.
6. Definir Contratos de Operación.
7. Definir Diagramas de Estados. (opcional)
IV.3.2 Modelo Conceptual
Una parte de la investigación sobre el dominio del problema consiste en identificar los conceptos que lo conforman. Para representar estos conceptos se va a usar un Diagrama de Estructura Estática de UML, al que se va a llamar Modelo Conceptual.
En el Modelo Conceptual se tiene una representación de conceptos del mundo real, no de componentes software.
El objetivo de la creación de un Modelo Conceptual es aumentar la comprensión del problema. Por tanto, a la hora de incluir conceptos en el modelo, es mejor crear un modelo con muchos conceptos que quedarse corto y olvidar algún concepto importante.
IV.3.2.1 Identificación de Conceptos
Para identificar conceptos hay que basarse en el documento de Especificación de Requisitos y en el conocimiento general acerca del dominio del problema.
En
Otro consejo para identificar conceptos consiste en buscar sustantivos en los documentos de requisitos o, más concretamente, en la descripción de los casos de uso. No es un método infalible, pero puede servir de guía para empezar.
Para poner nombre a los conceptos se puede usar la analogía con el cartógrafo, resumida en los siguientes tres puntos:
• Usar los nombres existentes en el territorio: Hay que usar el vocabulario del dominio para nombrar conceptos y atributos.
• Excluir características irrelevantes: Al igual que el cartógrafo elimina características no relevantes según la finalidad del mapa (por ejemplo datos de población en un mapa de carreteras), un Modelo Conceptual puede excluir conceptos en el dominio que no son pertinentes en base a los requisitos.
• No añadir cosas que no están ahí: Si algo no pertenece al dominio del problema no se añade al modelo.
IV.3.2.2 Creación del Modelo Conceptual
Para crear el Modelo Conceptual se siguen los siguientes pasos:
1. Hacer una lista de conceptos candidato usando
2. Representarlos en un diagrama.
3. Añadir las asociaciones necesarias para ilustrar las relaciones entre conceptos que es necesario conocer.
4. Añadir los atributos necesarios para contener toda la información que se necesite conocer de cada concepto.
IV.3.2.3 Identificación de Asociaciones
Una asociación es una relación entre conceptos que indica una conexión con sentido y que es de interés en el conjunto de casos de uso que se está tratando.
Se incluyen en el modelo las asociaciones siguientes:
• Asociaciones para las que el conocimiento de la relación necesita mantenerse por un cierto período de tiempo (asociaciones “necesita-conocer”).
• Asociaciones derivadas de
Tabla 1 Lista de Conceptos Típicos
Tipo de Concepto Ejemplos
Objetos físicos o tangibles Avión
Terminal de Caja
Especificaciones, diseños o descripciones de cosas Especificación de Producto
Descripción de Vuelo
Lugares Supermercado
Aeropuerto
Transacciones Venta, Pago
Reserva
Líneas de una transacción Artículo de Venta
Roles de una persona Cajero
Piloto
Contenedores de otras cosas Supermercado, Cesta
Avión
Cosas en un contenedor Artículo
Pasajero
Otros ordenadores o sistemas electromecánicos externos a nuestro sistema Sistema de Autorización de Tarjetas de Crédito
Sistema Controlador de Tráfico Aéreo
Conceptos abstractos Hambre
Organizaciones Departamento de Ventas
Compañía Aérea Toto
Eventos Venta, Robo, Reunión
Vuelo, Accidente, Aterrizaje
Reglas y políticas Política de Devoluciones
Política de Cancelaciones
Catálogos Catálogo de Productos
Catálogo de Piezas
Archivos financieros, de trabajo, de contratos, de asuntos legales Recibo, Contrato de Empleo
Registro de Revisiones
Instrumentos y servicios financieros Línea de Crédito
Stock
Manuales, libros Manual del Empleado
Manual de Reparaciones
Tabla 2 Lista de Asociaciones Típicas
Categoría Ejemplos
A es una parte física de B Ala – Avión
A es una parte lógica de B Artículo en Venta –Venta
A está físicamente contenido en B Artículo – Estantería
Pasajero – Avión
A está lógicamente contenido en B Descripción de Artículo – Catálogo
A es una descripción de B Descripción de Artículo – Artículo
A es un elemento en una transacción o un informe B Trabajo de Reparación – Registro de Reparaciones
A es registrado/archivado/capturado en B Venta – Terminal de Caja
A es un miembro de B Cajero – Supermercado
Piloto – Compañía Aérea
A es una subunidad organizativa de B Sección – Supermercado
Mantenimiento – Compañía Aérea
A usa o gestiona B Cajero – Terminal de Caja
Piloto – Avión
A comunica con B Cliente – Cajero
Empleado de Agencia de Viajes – Pasajero
A está relacionado con una transacción B Cliente – Pago
Pasajero – Billete
A es una transacción relacionada con otra transacción B Pago – Venta
Reserva – Cancelación
A está junto a B Ciudad – Ciudad
A posee B Supermercado – Terminal de Caja
Compañía Aérea – Avión
Una vez identificadas las asociaciones se representan en el Modelo Conceptual con la multiplicidad adecuada.
IV.3.2.4 Identificación de Atributos
Es necesario incorporar al Modelo Conceptual los atributos necesarios para satisfacer las necesidades de información de los casos de uso que se estén desarrollando en ese momento.
Los atributos deben tomar valor en tipos simples (número, texto, etc.), pues los tipos complejos deberían ser modelados como conceptos y ser relacionados mediante asociaciones.
Incluso cuando un valor es de un tipo simple es más conveniente representarlo como concepto en las siguientes ocasiones:
• Se compone de distintas secciones. Por ejemplo: un número de teléfono, el nombre de una persona, etc.
• Tiene operaciones asociadas, tales como validación. Ejemplo: NIF.
• Tiene otros atributos. Por ejemplo un precio de oferta puede tener fecha de fin.
• Es una cantidad con una unidad. Ejemplo: El precio, que puede estar en pesetas o en euros.
Una vez definidos los atributos se tiene ya un Modelo Conceptual. Este modelo no es un modelo definitivo, pues a lo largo del desarrollo se va refinando según se le añaden conceptos que se habían pasado por alto.
IV.3.3 Glosario
En el glosario debe aparecer una descripción textual de cualquier elemento de cualquier modelo, para eliminar toda posible ambigüedad. Se ordena alfabéticamente por término.
Un formato tipo para el glosario es el que se muestra en
Tabla 3 Formato tipo de Glosario
Término Categoría Descripción
Banco concepto Entidad que ofrece servicios financieros a sus clientes
Realizar Reintegro caso de uso El Cliente realiza un reintegro de su cuenta
... ... ...
IV.3.4 Diagramas de Secuencia del Sistema
Además de investigar sobre los conceptos del sistema y su estructura, también es preciso investigar en el Diseño de Alto Nivel sobre el comportamiento del sistema, visto éste como una caja negra. Una parte de la descripción del comportamiento del sistema se realiza mediante los Diagramas de Secuencia del Sistema.
En cada caso de uso se muestra una interacción de actores con el sistema. En esta interacción los actores generan eventos, solicitando al sistema operaciones. Por ejemplo, en el caso de una reserva de un billete de avión, el empleado de la agencia de viajes solicita al sistema de reservas que realice una reserva. El evento que supone esa solicitud inicia una operación en el sistema de reservas.
Los casos de uso representan una interacción genérica. Una instancia de un caso de uso se denomina escenario, y muestra una ejecución real del caso de uso, con las posibles bifurcaciones y alternativas resueltas de forma particular.
Un Diagrama de Secuencia de Sistema se representa usando la notación para diagramas de secuencia de UML (ver página 11). En él se muestra para un escenario particular de un caso de uso los eventos que los actores generan, su orden, y los eventos que se intercambian entre sistemas.
Para cada caso de uso que se esté tratando se realiza un diagrama para el curso típico de eventos, y además se realiza un diagrama para los cursos alternativos de mayor interés. En
Figura 38 Ejemplo de Diagrama de Secuencia del Sistema
IV.3.4.1 Construcción de un Diagrama de Secuencia del Sistema
Para construir un Diagrama de Secuencia del Sistema para el curso típico de eventos de un caso de uso, se siguen los siguientes pasos:
1. Representar el sistema como un objeto con una línea debajo.
2. Identificar los actores que directamente operan con el sistema, y dibujar una línea para cada uno de ellos.
3. Partiendo del texto del curso típico de eventos del caso de uso, identificar los eventos (externos) del sistema que cada actor genera y representarlos en el diagrama.
4. Opcionalmente, incluir el texto del caso de uso en el margen del diagrama.
Los eventos del sistema deberían expresarse en base a la noción de operación que representan, en vez de en base a la interfaz particular. Por ejemplo, se prefiere “finalizarOperación” a “presionadaTeclaEnter”, porque captura la finalidad de la operación sin realizar compromisos en cuanto a la interfaz usada.
IV.3.5 Contratos de Operaciones
Una vez se tienen las Operaciones del Sistema identificadas en los Diagramas de Secuencia, se describe mediante contratos el comportamiento esperado del sistema en cada operación.
Un Contrato es un documento que describe qué es lo que se espera de una operación. Tiene una redacción en estilo declarativo, enfatizando en el qué más que en el cómo. Lo más común es expresar los contratos en forma de pre- y post-condiciones en torno a cambios de estado.
Se puede escribir un contrato para un método individual de una clase software, o para una operación del sistema completa. En este punto se verá únicamente éste último caso.
Un Contrato de Operación del Sistema describe cambios en el estado del sistema cuando una operación del sistema es invocada.
A continuación se ve un ejemplo de Contrato:
Contrato
Nombre: leerTarjeta (número_tarjeta: número)
Responsabilidades: Comprobar que la tarjeta numero_tarjeta es correcta y presentar las opciones disponibles.
Referencias Cruzadas: Funciones del Sistema: R1.2, R1.6, R1.7
Casos de Uso: Reintegro
Notas:
Excepciones: Si la tarjeta es ilegible o no pertenece a los tipos de tarjetas aceptadas, indicar que ha habido un error.
Salida:
Pre-condiciones: No hay una operación activa.
Post-condiciones: • Una nueva Operación se ha creado. (creación de instancia).
•
La descripción de cada apartado de un contrato es como sigue:
Nombre: Nombre de la operación y parámetros.
Responsabilidades: Una descripción informal de las responsabilidades que la operación debe desempeñar.
Referencias Cruzadas: Números de referencia en los requisitos de funciones del sistema, casos de uso, etc.
Notas: Comentarios de diseño, algoritmos, etc.
Excepciones: Casos excepcionales. Situaciones que debemos tener en cuenta que pueden pasar. Se indica también qué se hace cuando ocurre la excepción.
Salida: Salidas que no corresponden a la interfaz de usuario, como mensajes o registros que se envían fuera del sistema. (En la mayor parte de las operaciones del sistema este apartado queda vacío)
Pre-condiciones: Suposiciones acerca del estado del sistema antes de ejecutar la operación.
Post-condiciones: El estado del sistema después de completar la operación.
IV.3.5.1 Construcción de un Contrato
Los pasos a seguir para construir un contrato son los siguientes:
1. Identificar las operaciones del sistema a partir de los Diagramas de Secuencia del Sistema.
2. Para cada operación del sistema construir un contrato.
3. Empezar escribiendo el apartado de Responsabilidades, describiendo informalmente el propósito de la operación. Este es el apartado más importante del contrato.
4. A continuación rellenar el apartado de Post-condiciones, describiendo declarativamente los cambios de estado que sufren los objetos en el Modelo Conceptual. Puede ser que este apartado quede vacío si no cambia el valor de ningún dato de los maneja el sistema (por ejemplo en una operación del sistema que tan solo se encarga de sacar por pantalla algo al usuario).
5. Para describir las post-condiciones, usar las siguientes categorías:
• Creación y borrado de instancias.
• Modificación de atributos.
• Asociaciones formadas y retiradas.
6. Completar el resto de apartados en su caso.
IV.3.5.2 Post-condiciones
Las post-condiciones se basan en el Modelo Conceptual, en los cambios que sufren los elementos del mismo una vez se ha realizado la operación.
Es mejor usar el tiempo pasado o el pretérito perfecto al redactar una post-condición, para enfatizar que se trata de declaraciones sobre un cambio en el estado que ya ha pasado. Por ejemplo es mejor decir “se ha creado un nuevo Cliente” que decir “crear un Cliente”.
Cuando se ha creado un objeto, lo normal es que se haya asociado a algún otro objeto ya existente, porque si no queda aislado del resto del sistema. Por tanto, al escribir las post-condiciones hay que acordarse de añadir asociaciones a los objetos creados. Olvidar incluir estas asociaciones es el fallo más común cometido al escribir las post-condiciones de un contrato.
IV.3.6 Diagramas de Estados
Para modelar el comportamiento del sistema pueden usarse los Diagramas de Estados que define UML (ver página 13).
Se puede aplicar un Diagrama de Estados al comportamiento de los siguientes elementos:
- Una clase software.
- Un concepto.
- Un caso de uso.
En la fase de Diseño de Alto Nivel sólo se haría para los dos últimos tipos de elemento, pues una clase software pertenece al Diagrama de Clases de Diseño.
Puesto que el sistema entero puede ser representado por un concepto, también se puede modelar el comportamiento del sistema completo mediante un Diagrama de Estados.
La utilidad de un Diagrama de Estados en esta fase reside en mostrar la secuencia permitida de eventos externos que pueden ser reconocidos y tratados por el sistema. Por ejemplo, no se puede insertar una tarjeta en un cajero automático si se está en el transcurso de una operación.
Para los casos de uso complejos se puede construir un Diagrama de Estados. El Diagrama de Estados del sistema sería una combinación de los diagramas de todos los casos de uso.
El uso de Diagramas de Estados es opcional. Tan solo los usaremos cuando consideremos que nos ayudan a expresar mejor el comportamiento del elemento descrito.
IV.3 Fase de Construcción: Diseño de Alto Nivel
En la fase de Diseño de Alto Nivel de un ciclo de desarrollo se investiga sobre el problema, sobre los conceptos relacionados con el subconjunto de casos de uso que se esté tratando. Se intenta llegar a una buena comprensión del problema por parte del equipo de desarrollo, sin entrar en cómo va a ser la solución en cuanto a detalles de implementación.
Cuando el ciclo de desarrollo no es el primero, antes de la fase de Diseño de Alto Nivel hay una serie de actividades de planificación. Estas actividades consisten en actualizar los modelos que se tengan según lo que se haya implementado, pues siempre se producen desviaciones entre lo que se ha analizado y diseñado y lo que finalmente se construye. Una vez se tienen los modelos acordes con lo implementado se empieza el nuevo ciclo de desarrollo con la fase de Diseño de Alto Nivel.
En esta fase se trabaja con los modelos de Diseño de Alto Nivel construidos en la fase anterior, ampliándolos con los conceptos correspondientes a los casos de uso que se traten en el ciclo de desarrollo actual.
IV.3.1 Actividades
Las actividades de la fase de Diseño de Alto Nivel son las siguientes:
1. Definir Casos de Uso Esenciales en formato expandido. (si no están definidos )
2. Refinar los Diagramas de Casos de Uso.
3. Refinar el Modelo Conceptual.
4. Refinar el Glosario. (continuado en posteriores fases)
5. Definir los Diagramas de Secuencia del Sistema.
6. Definir Contratos de Operación.
7. Definir Diagramas de Estados. (opcional)
IV.3.2 Modelo Conceptual
Una parte de la investigación sobre el dominio del problema consiste en identificar los conceptos que lo conforman. Para representar estos conceptos se va a usar un Diagrama de Estructura Estática de UML, al que se va a llamar Modelo Conceptual.
En el Modelo Conceptual se tiene una representación de conceptos del mundo real, no de componentes software.
El objetivo de la creación de un Modelo Conceptual es aumentar la comprensión del problema. Por tanto, a la hora de incluir conceptos en el modelo, es mejor crear un modelo con muchos conceptos que quedarse corto y olvidar algún concepto importante.
IV.3.2.1 Identificación de Conceptos
Para identificar conceptos hay que basarse en el documento de Especificación de Requisitos y en el conocimiento general acerca del dominio del problema.
En
Otro consejo para identificar conceptos consiste en buscar sustantivos en los documentos de requisitos o, más concretamente, en la descripción de los casos de uso. No es un método infalible, pero puede servir de guía para empezar.
Para poner nombre a los conceptos se puede usar la analogía con el cartógrafo, resumida en los siguientes tres puntos:
• Usar los nombres existentes en el territorio: Hay que usar el vocabulario del dominio para nombrar conceptos y atributos.
• Excluir características irrelevantes: Al igual que el cartógrafo elimina características no relevantes según la finalidad del mapa (por ejemplo datos de población en un mapa de carreteras), un Modelo Conceptual puede excluir conceptos en el dominio que no son pertinentes en base a los requisitos.
• No añadir cosas que no están ahí: Si algo no pertenece al dominio del problema no se añade al modelo.
IV.3.2.2 Creación del Modelo Conceptual
Para crear el Modelo Conceptual se siguen los siguientes pasos:
1. Hacer una lista de conceptos candidato usando
2. Representarlos en un diagrama.
3. Añadir las asociaciones necesarias para ilustrar las relaciones entre conceptos que es necesario conocer.
4. Añadir los atributos necesarios para contener toda la información que se necesite conocer de cada concepto.
IV.3.2.3 Identificación de Asociaciones
Una asociación es una relación entre conceptos que indica una conexión con sentido y que es de interés en el conjunto de casos de uso que se está tratando.
Se incluyen en el modelo las asociaciones siguientes:
• Asociaciones para las que el conocimiento de la relación necesita mantenerse por un cierto período de tiempo (asociaciones “necesita-conocer”).
• Asociaciones derivadas de
Tabla 1 Lista de Conceptos Típicos
Tipo de Concepto Ejemplos
Objetos físicos o tangibles Avión
Terminal de Caja
Especificaciones, diseños o descripciones de cosas Especificación de Producto
Descripción de Vuelo
Lugares Supermercado
Aeropuerto
Transacciones Venta, Pago
Reserva
Líneas de una transacción Artículo de Venta
Roles de una persona Cajero
Piloto
Contenedores de otras cosas Supermercado, Cesta
Avión
Cosas en un contenedor Artículo
Pasajero
Otros ordenadores o sistemas electromecánicos externos a nuestro sistema Sistema de Autorización de Tarjetas de Crédito
Sistema Controlador de Tráfico Aéreo
Conceptos abstractos Hambre
Organizaciones Departamento de Ventas
Compañía Aérea Toto
Eventos Venta, Robo, Reunión
Vuelo, Accidente, Aterrizaje
Reglas y políticas Política de Devoluciones
Política de Cancelaciones
Catálogos Catálogo de Productos
Catálogo de Piezas
Archivos financieros, de trabajo, de contratos, de asuntos legales Recibo, Contrato de Empleo
Registro de Revisiones
Instrumentos y servicios financieros Línea de Crédito
Stock
Manuales, libros Manual del Empleado
Manual de Reparaciones
Tabla 2 Lista de Asociaciones Típicas
Categoría Ejemplos
A es una parte física de B Ala – Avión
A es una parte lógica de B Artículo en Venta –Venta
A está físicamente contenido en B Artículo – Estantería
Pasajero – Avión
A está lógicamente contenido en B Descripción de Artículo – Catálogo
A es una descripción de B Descripción de Artículo – Artículo
A es un elemento en una transacción o un informe B Trabajo de Reparación – Registro de Reparaciones
A es registrado/archivado/capturado en B Venta – Terminal de Caja
A es un miembro de B Cajero – Supermercado
Piloto – Compañía Aérea
A es una subunidad organizativa de B Sección – Supermercado
Mantenimiento – Compañía Aérea
A usa o gestiona B Cajero – Terminal de Caja
Piloto – Avión
A comunica con B Cliente – Cajero
Empleado de Agencia de Viajes – Pasajero
A está relacionado con una transacción B Cliente – Pago
Pasajero – Billete
A es una transacción relacionada con otra transacción B Pago – Venta
Reserva – Cancelación
A está junto a B Ciudad – Ciudad
A posee B Supermercado – Terminal de Caja
Compañía Aérea – Avión
Una vez identificadas las asociaciones se representan en el Modelo Conceptual con la multiplicidad adecuada.
IV.3.2.4 Identificación de Atributos
Es necesario incorporar al Modelo Conceptual los atributos necesarios para satisfacer las necesidades de información de los casos de uso que se estén desarrollando en ese momento.
Los atributos deben tomar valor en tipos simples (número, texto, etc.), pues los tipos complejos deberían ser modelados como conceptos y ser relacionados mediante asociaciones.
Incluso cuando un valor es de un tipo simple es más conveniente representarlo como concepto en las siguientes ocasiones:
• Se compone de distintas secciones. Por ejemplo: un número de teléfono, el nombre de una persona, etc.
• Tiene operaciones asociadas, tales como validación. Ejemplo: NIF.
• Tiene otros atributos. Por ejemplo un precio de oferta puede tener fecha de fin.
• Es una cantidad con una unidad. Ejemplo: El precio, que puede estar en pesetas o en euros.
Una vez definidos los atributos se tiene ya un Modelo Conceptual. Este modelo no es un modelo definitivo, pues a lo largo del desarrollo se va refinando según se le añaden conceptos que se habían pasado por alto.
IV.3.3 Glosario
En el glosario debe aparecer una descripción textual de cualquier elemento de cualquier modelo, para eliminar toda posible ambigüedad. Se ordena alfabéticamente por término.
Un formato tipo para el glosario es el que se muestra en
Tabla 3 Formato tipo de Glosario
Término Categoría Descripción
Banco concepto Entidad que ofrece servicios financieros a sus clientes
Realizar Reintegro caso de uso El Cliente realiza un reintegro de su cuenta
... ... ...
IV.3.4 Diagramas de Secuencia del Sistema
Además de investigar sobre los conceptos del sistema y su estructura, también es preciso investigar en el Diseño de Alto Nivel sobre el comportamiento del sistema, visto éste como una caja negra. Una parte de la descripción del comportamiento del sistema se realiza mediante los Diagramas de Secuencia del Sistema.
En cada caso de uso se muestra una interacción de actores con el sistema. En esta interacción los actores generan eventos, solicitando al sistema operaciones. Por ejemplo, en el caso de una reserva de un billete de avión, el empleado de la agencia de viajes solicita al sistema de reservas que realice una reserva. El evento que supone esa solicitud inicia una operación en el sistema de reservas.
Los casos de uso representan una interacción genérica. Una instancia de un caso de uso se denomina escenario, y muestra una ejecución real del caso de uso, con las posibles bifurcaciones y alternativas resueltas de forma particular.
Un Diagrama de Secuencia de Sistema se representa usando la notación para diagramas de secuencia de UML (ver página 11). En él se muestra para un escenario particular de un caso de uso los eventos que los actores generan, su orden, y los eventos que se intercambian entre sistemas.
Para cada caso de uso que se esté tratando se realiza un diagrama para el curso típico de eventos, y además se realiza un diagrama para los cursos alternativos de mayor interés. En
Figura 38 Ejemplo de Diagrama de Secuencia del Sistema
IV.3.4.1 Construcción de un Diagrama de Secuencia del Sistema
Para construir un Diagrama de Secuencia del Sistema para el curso típico de eventos de un caso de uso, se siguen los siguientes pasos:
1. Representar el sistema como un objeto con una línea debajo.
2. Identificar los actores que directamente operan con el sistema, y dibujar una línea para cada uno de ellos.
3. Partiendo del texto del curso típico de eventos del caso de uso, identificar los eventos (externos) del sistema que cada actor genera y representarlos en el diagrama.
4. Opcionalmente, incluir el texto del caso de uso en el margen del diagrama.
Los eventos del sistema deberían expresarse en base a la noción de operación que representan, en vez de en base a la interfaz particular. Por ejemplo, se prefiere “finalizarOperación” a “presionadaTeclaEnter”, porque captura la finalidad de la operación sin realizar compromisos en cuanto a la interfaz usada.
IV.3.5 Contratos de Operaciones
Una vez se tienen las Operaciones del Sistema identificadas en los Diagramas de Secuencia, se describe mediante contratos el comportamiento esperado del sistema en cada operación.
Un Contrato es un documento que describe qué es lo que se espera de una operación. Tiene una redacción en estilo declarativo, enfatizando en el qué más que en el cómo. Lo más común es expresar los contratos en forma de pre- y post-condiciones en torno a cambios de estado.
Se puede escribir un contrato para un método individual de una clase software, o para una operación del sistema completa. En este punto se verá únicamente éste último caso.
Un Contrato de Operación del Sistema describe cambios en el estado del sistema cuando una operación del sistema es invocada.
A continuación se ve un ejemplo de Contrato:
Contrato
Nombre: leerTarjeta (número_tarjeta: número)
Responsabilidades: Comprobar que la tarjeta numero_tarjeta es correcta y presentar las opciones disponibles.
Referencias Cruzadas: Funciones del Sistema: R1.2, R1.6, R1.7
Casos de Uso: Reintegro
Notas:
Excepciones: Si la tarjeta es ilegible o no pertenece a los tipos de tarjetas aceptadas, indicar que ha habido un error.
Salida:
Pre-condiciones: No hay una operación activa.
Post-condiciones: • Una nueva Operación se ha creado. (creación de instancia).
•
La descripción de cada apartado de un contrato es como sigue:
Nombre: Nombre de la operación y parámetros.
Responsabilidades: Una descripción informal de las responsabilidades que la operación debe desempeñar.
Referencias Cruzadas: Números de referencia en los requisitos de funciones del sistema, casos de uso, etc.
Notas: Comentarios de diseño, algoritmos, etc.
Excepciones: Casos excepcionales. Situaciones que debemos tener en cuenta que pueden pasar. Se indica también qué se hace cuando ocurre la excepción.
Salida: Salidas que no corresponden a la interfaz de usuario, como mensajes o registros que se envían fuera del sistema. (En la mayor parte de las operaciones del sistema este apartado queda vacío)
Pre-condiciones: Suposiciones acerca del estado del sistema antes de ejecutar la operación.
Post-condiciones: El estado del sistema después de completar la operación.
IV.3.5.1 Construcción de un Contrato
Los pasos a seguir para construir un contrato son los siguientes:
1. Identificar las operaciones del sistema a partir de los Diagramas de Secuencia del Sistema.
2. Para cada operación del sistema construir un contrato.
3. Empezar escribiendo el apartado de Responsabilidades, describiendo informalmente el propósito de la operación. Este es el apartado más importante del contrato.
4. A continuación rellenar el apartado de Post-condiciones, describiendo declarativamente los cambios de estado que sufren los objetos en el Modelo Conceptual. Puede ser que este apartado quede vacío si no cambia el valor de ningún dato de los maneja el sistema (por ejemplo en una operación del sistema que tan solo se encarga de sacar por pantalla algo al usuario).
5. Para describir las post-condiciones, usar las siguientes categorías:
• Creación y borrado de instancias.
• Modificación de atributos.
• Asociaciones formadas y retiradas.
6. Completar el resto de apartados en su caso.
IV.3.5.2 Post-condiciones
Las post-condiciones se basan en el Modelo Conceptual, en los cambios que sufren los elementos del mismo una vez se ha realizado la operación.
Es mejor usar el tiempo pasado o el pretérito perfecto al redactar una post-condición, para enfatizar que se trata de declaraciones sobre un cambio en el estado que ya ha pasado. Por ejemplo es mejor decir “se ha creado un nuevo Cliente” que decir “crear un Cliente”.
Cuando se ha creado un objeto, lo normal es que se haya asociado a algún otro objeto ya existente, porque si no queda aislado del resto del sistema. Por tanto, al escribir las post-condiciones hay que acordarse de añadir asociaciones a los objetos creados. Olvidar incluir estas asociaciones es el fallo más común cometido al escribir las post-condiciones de un contrato.
IV.3.6 Diagramas de Estados
Para modelar el comportamiento del sistema pueden usarse los Diagramas de Estados que define UML (ver página 13).
Se puede aplicar un Diagrama de Estados al comportamiento de los siguientes elementos:
- Una clase software.
- Un concepto.
- Un caso de uso.
En la fase de Diseño de Alto Nivel sólo se haría para los dos últimos tipos de elemento, pues una clase software pertenece al Diagrama de Clases de Diseño.
Puesto que el sistema entero puede ser representado por un concepto, también se puede modelar el comportamiento del sistema completo mediante un Diagrama de Estados.
La utilidad de un Diagrama de Estados en esta fase reside en mostrar la secuencia permitida de eventos externos que pueden ser reconocidos y tratados por el sistema. Por ejemplo, no se puede insertar una tarjeta en un cajero automático si se está en el transcurso de una operación.
Para los casos de uso complejos se puede construir un Diagrama de Estados. El Diagrama de Estados del sistema sería una combinación de los diagramas de todos los casos de uso.
El uso de Diagramas de Estados es opcional. Tan solo los usaremos cuando consideremos que nos ayudan a expresar mejor el comportamiento del elemento descrito.
Fases de Implementación y Pruebas
Una vez se tiene completo el Diagrama de Clases de Diseño, se pasa a la implementación en el lenguaje de programación elegido.
El programa obtenido se depura y prueba, y ya se tiene una parte del sistema funcionando que se puede probar con los futuros usuarios, e incluso poner en producción si se ha planificado una instalación gradual.
Una vez se tiene una versión estable se pasa al siguiente ciclo de desarrollo para incrementar el sistema con los casos de uso asignados a tal ciclo.
_______________________________________________________________________________
ESTUDIANTE DE INFORMATICA Y SISTEMAS
CONTACTOS 9775011-9954839 AREQUIPA -PERU
_______________________________________________________________________________
para ver si eres tu o no
como te ira con tu novia
mucho mas tarde para vivir en verda
El rey león junta a los animales de la selva y les advierte de su cumpleaños y el que no lleve algo bueno se lo mete por el culo. Al día siguiente llega el pato y le da uvas, y decepcionado se las mete por el culo, y así a todos los animales, llega los changos y dan ciruelas, y se las introduce, pero se ríen, y dice el rey, por que se ríen: por que las hormigas traen una sandía
ALGO PARA TI
Un conferencista muy reconocido comienza su seminario
teniendo muy en alto un billete de 100 dolares.
Él le pregunta a la gente:
"¿Quien quisiera tener este billete?"
Las manos comienzan a levantarse, entonces dice:
"Voy a darle este billete de 100 dólares a alguno de ustedes,
pero antes déjenme hacer algo con él."
El arruga entonces el billete con fuerza y pregunta:
"¿Aún quieren éste billete?"
Las manos continúan levantadas.
"Bueno, de acuerdo, pero ¿que pasaría si hago ésto?"
El bota el billete arrugado al piso y salta con los pies
juntos encima, espichándolo lo más posible y cubriéndolo
con el polvo del piso.
Enseguida pregunta:
"¿Quien quiere todavía éste billete?"
¡Evidentemente las manos continúan levantadas!
"Amigos míos, acaban de aprender una lección...
poco importa lo que yo haga con este billete, siguen
queriédolo porque su valor no ha cambiado,
cuesta todavía 100 dólares."
"Piensen ahora en ustedes, en su vida. Muchas veces
se sentirán arrugados, rechazados, ensuciados
por la gente o por los acontecimientos."
Tendrán la impresión de no valer nada ¡pero en realidad su
valor no habrá cambiado a los ojos de la gente que los ama!
El valor de una persona no depende de lo que uno ha hecho
o no, ustedes podrán todos los días volver a empezar y
lograr sus objetivos porque su valor intrínseco está
siempre intacto.
"El arquero es un modelo para el sabio. Cuando le ha fallado
al blanco, busca la causa en sí mismo."
- Confucio
"Adopta la divisa del reloj de sol: yo no marco sino las
horas asoleadas."
- O.S. Marden
gilbert, hasta la próxima semana.
P.D.: Sólo por hoy elige pensamientos y emociones positivas.
Notarás la diferencia.
Cordialmente ,
Gilbert canaza
TU NO ESTAS SOLO
El joven Demóstenes soñaba con ser un gran orador,
sin embargo este propósito parecía una locura desde
todo punto de vista.
Su trabajo era humilde, y de extenuantes horas a
la intemperie.
No tenía el dinero para pagar a sus maestros,
ni ningún tipo de conocimientos.
Además tenía otra gran limitación: Era tartamudo.
Demóstenes sabía que la persistencia y la
tenacidad hacen milagros y, cultivando estas
virtudes, pudo asistir a los discursos de los
oradores y filósofos más prominentes de la época.
Hasta tuvo la oportunidad de ver al mismísimo Platón
exponer sus teorías.
Ansioso por empezar, no perdió tiempo en preparar
su primer discurso.
Su entusiasmo duro poco: La presentación fue un desastre.
A la tercera frase fue
interrumpido por los gritos de protesta de la audiencia:
- ¿Para qué nos repite diez veces la misma frase?
-dijo un hombre seguido de las carcajadas del público.
- ¡Hable más alto! -exclamó otro-. No se escucha,
¡ponga el aire en sus pulmones y no en su cerebro!
Las burlas acentuaron el nerviosismo y el tartamudeo
de Demóstenes, quien se retiró entre los abucheos sin
siquiera terminar su discurso.
Cualquier otra persona hubiera olvidado sus sueños
para siempre. Fueron muchos los que le aconsejaron -y
muchos otros los que lo humillaron- para que desistiera
de tan absurdo propósito.
En vez de sentirse desanimado, Demóstenes tomaba esas
afirmaciones como un desafió, como un juego que él
quería ganar.
Usaba la frustración para agrandarse, para llenarse
de fuerza, para mirar más lejos. Sabía que los premios
de la vida eran para quienes tenían la paciencia y
persistencia de saber crecer.
- Tengo que trabajar en mi estilo.- se decía a sí
mismo.
Así fue que se embarcó en la aventura de hacer todo
lo necesario para superar las adversas circunstancias
que lo rodeaban.
Se afeitó la cabeza, para así resistir la tentación
de salir a las calles. De este modo, día a día, se aislaba
hasta el amanecer practicando.
En los atardeceres corría por las playas, gritándole
al sol con todas sus fuerzas, para así ejercitar sus
pulmones.
Más entrada la noche, se llenaba la boca con piedras
y se ponía un cuchillo afilado entre los dientes para
forzarse a hablar sin tartamudear.
Al regresar a la casa se paraba durante horas frente
a un espejo para mejorar su postura y sus gestos.
Así pasaron meses y años, antes de que de que
reapareciera de nuevo ante la asamblea defendiendo con
éxito a un fabricante de lámparas, a quien sus ingratos
hijos le querían arrebatar su patrimonio.
En esta ocasión la seguridad, la elocuencia y la
sabiduría de Demóstenes fue ovacionada por el público
hasta el cansancio.
Demóstenes fue posteriormente elegido como embajador de
la ciudad.
Su persistencia convirtió las piedras del camino en las
rocas sobre las cuales levantó sus sueños.
gilbert, tú lo sabes: cuando realmente has sido
persistente y has mantenido tu compromiso,
muchas veces en tu vida, has convertido
en posible lo imposible. Nunca lo olvides.
Antes de despedirme, quiero recordarte, que como miembro
del club positivo, tienes el privilegio de pasar este
regalo a un amigo o cercano, es facil solo
inscribelo ya en :
Un viajero muy cansado se sienta bajo la sombra de un árbol
sin imaginarse que iba a encontrar un árbol mágico, "El Árbol
que convierte en realidad los deseos".
Sentado sobre la tierra dura, el pensaba que sería muy
agradable encontrarse una cama mullida.
Al momento, esta cama apareció al lado suyo.
Asombrado el hombre se instaló y dijo que el colmo de
la dicha sería alcanzado, si una joven viniera y masajeara
sus piernas tullidas.
La joven apareció y lo masajeó de una manera muy
agradable
- Tengo hambre, -dice el hombre,- y comer en este momento
sería con seguridad, una delicia.
Una mesa surgió, cargada con alimentos suculentos.
El hombre se alegra. Come y bebe. Su cabeza se inclina
un poco. Sus párpados, por la acción del vino y la fatiga,
se cierran. Se dejó caer a lo largo de la cama y pensaba
ahora en los maravillosos eventos de este extraordinario
día.
- Voy a dormir una hora o dos -se dice él-. Lo peor sería
que un tigre pasara por aquí mientras duermo.
Un tigre aparece enseguida y lo devora.
Usted tiene en si mismo un Árbol de deseos que espera
sus órdenes.
Pero cuidado, el también puede realizar sus pensamientos
negativos y sus temores. Puede contaminarse de ellos y
bloquearse. Este es el mecanismo de las preocupaciones.
Yo le deseo, de todo corazón, una vida libre de preocupaciones,
de pensamientos negativos y temores,
a la sombra de su propio Árbol de los Deseos!
Y para ayudarlo a que así sea,
como el primer regalo del club positivo,
le ofercemos esta sorpresa
le prometo que la disfrutara
Para todos mis amigotes que siempre les gusta la aventura y la buena vibra
Noticias: Noticias