1. Definición de POO
La orientación a
objetos es un paradigma de programación que facilita la creación de
software de calidad por sus factores que potencian el mantenimiento,
la extensión y la reutilización del software generado bajo este
paradigma. La programación orientada a objetos trata de amoldarse al
modo de pensar del hombre y no al de la máquina. Esto es posible
gracias a la forma racional con la que se manejan las abstracciones
que representan las entidades del dominio del problema, y a
propiedades como la jerarquía o el encapsulamiento.
El elemento básico de
este paradigma no es la función (elemento básico de la programación
estructurada), sino un ente denominado objeto. Un objeto es la
representación de un concepto para un programa, y contiene toda la
información necesaria para abstraer dicho concepto: los datos que
describen su estado y las operaciones que pueden modificar dicho
estado, y determinan las capacidades del objeto.
2. Origen de la POO
Cuando hablamos
de POO, estamos hablando de una nueva forma de pensar acerca del
proceso de descomposición de problemas y de desarrollo de soluciones
de programación. La programación orientada a objetos surge en la
historia como un intento para dominar la complejidad que, de forma
innata, posee el software. Tradicionalmente, la forma de enfrentarse
a esta complejidad ha sido empleando lo que llamamos programación
estructurada, que consiste en descomponer el problema objeto de
resolución en subproblemas y más subproblemas hasta llegar a
acciones muy simples y fáciles de codificar. Se trata de descomponer
el problema en acciones, en verbos. La programación orientada a
objetos es otra forma de descomponer problemas. Este nuevo método de
descomposición es la descomposición en objetos; vamos a fijarnos no
en lo que hay que hacer en el problema, sino en cuál es el escenario
real del mismo, y vamos a intentar simular ese escenario en nuestro
programa.
Los lenguajes de
programación tradicionales no orientados a objetos, como C, Pascal,
BASIC, o Modula-2, basan su funcionamiento en el concepto de
procedimiento o función. Una función es simplemente un conjunto de
instrucciones que operan sobre unos argumentos y producen un
resultado. De este modo, un programa no es más que una sucesión de
llamadas a funciones, ya sean éstas del sistema operativo,
proporcionadas por el propio lenguaje, o desarrolladas por el mismo
usuario. En el caso de los lenguajes orientados a objetos, como es el
caso de C++ y Java, el elemento básico no es la función, sino un
ente denominado precisamente objeto. Un objeto es la representación
en un programa de un concepto, y contiene toda la información
necesaria para abstraerlo: datos que describen sus atributos y
operaciones que pueden realizarse sobre los mismos.
Podemos
describir las siguientas etapas hasta llegar a la POO:
1. Etapa. Lenguajes
Ensambladores. La unidad de programación es la instrucción,
compuesta de un operador y los operandos. El nivel de abstracción
que se aplica es muy bajo.
2. Etapa. Lenguajes de
Programación: Fortran, Algol, Cobol. Los objetos y operaciones del
mundo real se podían modelar mediante datos y estructuras de control
separadamente. En esta etapa el diseño del software se enfoca sobre
la representación del detalle procedimental y en función del
lenguaje elegido. Conceptos como: refinamiento progresivo,
modularidad procedimientos y programación estructurada son conceptos
básicos que se utilizan en esta etapa. Existe mayor abstracción de
datos.
3. Etapa. Se introducen
en esta etapa los conceptos de abstracción y ocultación de la
información.
4. Etapa. A partir de los
años setenta se trabaja sobre una nueva clase de lenguajes de
simulación y sobre la construcción de prototipos tales como
Simula-70 y basado en parte de éste, el Smalltalk. En estos
lenguajes, la abstracción de datos tiene una gran importancia y los
problemas del mundo real se representan mediante objetos de datos a
los cuales se les añade el correspondiente conjunto de operaciones
asociados a ellos. Términos como Abstracción de datos, objeto,
encapsulación entre otros, son conceptos básicos sobre la que se
fundamenta la POO.
3. Caracteristicas
Hay un cierto desacuerdo
sobre exactamente qué características de un método de programación
o lenguaje le definen como “orientado a objetos”, pero hay un
consenso general en que las características siguientes son las más
importantes.
- Abstracción: Cada objeto en el sistema sirve como modelo de un “agente” abstracto que puede realizar trabajo, informar y cambiar su estado, y “comunicarse” con otros objetos en el sistema sin revelar cómo se implementan estas características. Los procesos, las funciones o los métodos pueden también ser abstraídos y cuando lo están, una variedad de técnicas son requeridas para ampliar una abstracción.
- Encapsulamiento: Significa reunir a todos los elementos que pueden considerarse pertenecientes a una misma entidad, al mismo nivel de abstracción. Esto permite aumentar la cohesión de los componentes del sistema. Algunos autores confunden este concepto con el principio de ocultación, principalmente porque se suelen emplear conjuntamente.
- Principio de ocultación: Cada objeto está aislado del exterior, es un módulo natural, y cada tipo de objeto expone una interfaz a otros objetos que especifica cómo pueden interactuar con los objetos de la clase. El aislamiento protege a las propiedades de un objeto contra su modificación por quien no tenga derecho a acceder a ellas, solamente los propios métodos internos del objeto pueden acceder a su estado. Esto asegura que otros objetos no pueden cambiar el estado interno de un objeto de maneras inesperadas, eliminando efectos secundarios e interacciones inesperadas. Algunos lenguajes relajan esto, permitiendo un acceso directo a los datos internos del objeto de una manera controlada y limitando el grado de abstracción. La aplicación entera se reduce a un agregado o rompecabezas de objetos.
- Polimorfismo: comportamientos diferentes, asociados a objetos distintos, pueden compartir el mismo nombre, al llamarlos por ese nombre se utilizará el comportamiento correspondiente al objeto que se esté usando. O dicho de otro modo, las referencias y las colecciones de objetos pueden contener objetos de diferentes tipos, y la invocación de un comportamiento en una referencia producirá el comportamiento correcto para el tipo real del objeto referenciado. Cuando esto ocurre en “tiempo de ejecución”, esta última característica se llama asignación tardía o asignación dinámica. Algunos lenguajes proporcionan medios más estáticos (en “tiempo de compilación”) de polimorfismo, tales como las plantillas y la sobrecarga de operadores de C++.
- Herencia: las clases no están aisladas, sino que se relacionan entre sí, formando una jerarquía de clasificación. Los objetos heredan las propiedades y el comportamiento de todas las clases a las que pertenecen. La herencia organiza y facilita el polimorfismo y el encapsulamiento permitiendo a los objetos ser definidos y creados como tipos especializados de objetos preexistentes. Estos pueden compartir (y extender) su comportamiento sin tener que reimplementar su comportamiento. Esto suele hacerse habitualmente agrupando los objetos en clases y estas en árboles o enrejados que reflejan un comportamiento común. Cuando un objeto hereda de más de una clase se dice que hay herencia múltiple; esta característica no está soportada por algunos lenguajes (como Java).
- Uniformidad: Ya que es la representación de los objetos lleva implica tanto el análisis como el diseño y la codificación de los mismos.
- Comprensión: Tanto los datos que componen los objetos, como los procedimientos que los manipulan, están agrupados en clases, que se corresponden con las estructuras de información que el programa trata.
- Flexibilidad: Al tener relacionados los procedimientos que manipulan los datos con los datos a tratar, cualquier cambio que se realice sobre ellos quedará reflejado automáticamente en cualquier lugar donde estos datos aparezcan.
- Estabilidad: Dado que permite un tratamiento diferenciado de aquellos objetos que permanecen constantes en el tiempo sobre aquellos que cambian con frecuencia permite aislar las partes del programa que permanecen inalterables en el tiempo.
4. Ventajas
- Fomenta la
reutilización y extensión del código.
- Relacionar el sistema
al mundo real.
- Permite crear sistemas
más complejos.
- Facilita la creación
de programas visuales.
- Construcción de
prototipos.
- Agiliza el desarrollo
de software.
- Facilita el trabajo en
equipo.
- Facilita el
mantenimiento del software.
- Lo interesante de la
POO es que proporciona conceptos y herramientas con las cuales se
modela y representa el mundo real tan fielmente como sea posible.
- Los programas son
fáciles de diseñar debido a que los objetos reflejan elementos del
mundo real.
- Las aplicaciones son
más sencillas para los usuarios debido a que los datos innecesarios
están ocultos.
- Los objetos son
unidades autocontenidas.
- La productividad se
incrementa debido a que puede reutilizar el código.
- Los sistemas son
fáciles de mantener y se adaptan a las cambiantes necesidades de
negocios.
- Es más fácil crear
nuevos tipos de objetos a partir de los ya existentes.
- Simplifica los datos
complejos.
- Reduce la complejidad
de la transacción.
- Confiabilidad.
- Robustez.
- Capacidad de
ampliación.
- Permite mostrar la
magnitud de los lenguajes de programacion basada en objetos.
- Crea sistemas mas
flexibles, que en un futuro son modificables.
- Reusabilidad. Cuando
hemos diseñado adecuadamente las clases, se pueden usar en distintas
partes del programa y en numerosos proyectos.
- Mantenibilidad. Debido
a las sencillez para abstraer el problema, los programas orientados a
objetos son más sencillos de leer y comprender, pues nos permiten
ocultar detalles de implementación dejando visibles sólo aquellos
detalles más relevantes.
- Modificabilidad. La
facilidad de añadir, suprimir o modificar nuevos objetos nos permite
hacer modificaciones de una forma muy sencilla.
- Fiabilidad. Al dividir
el problema en partes más pequeñas podemos probarlas de manera
independiente y aislar mucho más fácilmente los posibles errores
que puedan surgir.
5. Conceptos básicos
5.1 Objeto:
Un
objeto no es más que un conjunto de variables (o datos) y métodos
(o funciones) relacionados entre sí. Los objetos en programación se
usan para modelar objetos o entidades del mundo real (el objeto hijo,
madre, o farmacéutica, por ejemplo). Un objeto es, por tanto, la
representación en un programa de un concepto, y contiene toda la
información necesaria para abstraerlo: datos que describen sus
atributos y operaciones que pueden realizarse sobre los mismos.
Podemos definir objeto como el "encapsulamiento de un
conjunto de operaciones (métodos) que pueden ser invocados
externamente, y de un estado que recuerda el efecto de los
servicios".[Piattini et al., 1996]. Un objeto además de un
estado interno, presenta una interfaz para poder interactuar con el
exterior. Es por esto por lo que se dice que en la programación
orientada a objetos "se unen datos y procesos", y no como
en su predecesora, la programación estructurada, en la que estaban
separados en forma de variables y funciones. Un objeto consta de:
- Tiempo de vida: La duración de un objeto en un programa siempre está limitada en el tiempo. La mayoría de los objetos sólo existen durante una parte de la ejecución del programa. Los objetos son creados mediante un mecanismo denominado instanciación, y cuando dejan de existir se dice que son destruidos.
- Estado: Todo objeto posee un estado, definido por sus atributos. Con él se definen las propiedades del objeto, y el estado en que se encuentra en un momento determinado de su existencia.
- Comportamiento: Todo objeto ha de presentar una interfaz, definida por sus métodos, para que el resto de objetos que componen los programas puedan interactuar con él.
El equivalente de un
objeto en el paradigma estructurado sería una variable. Así mismo
la instanciación de objetos equivaldría a la declaración de
variables, y el tiempo de vida de un objeto alámbito de una
variable.
5.2 Clase:
Las clases son
abstracciones que representan a un conjunto de objetos con un
comportamiento e interfaz común. Podemos definir una clase como "un
conjunto de cosas (físicas o abstractas) que tienen el mismo
comportamiento y características. Es la implementación de un tipo
de objeto (considerando los objetos como instancias de las clases)".
[Piattini et al., 1996].
Una clase no es más que
una plantilla para la creación de objetos. Cuando se crea un objeto
(instanciación) se ha de especificar de qué clase es el objeto
instanciado, para que el compilador comprenda las características
del objeto. Las clases presentan el estado de los objetos a los que
representan mediante variables denominadas atributos. Cuando se
instancia un objeto el compilador crea en la memoria dinámica un
espacio para tantas variables como atributos tenga la clase a la que
pertenece el objeto. Los métodos son las funciones mediante las que
las clases representan el comportamiento de los objetos. En dichos
métodos se modifican los valores de los atributos del objeto, y
representan las capacidades del objeto (en muchos textos se les
denomina servicios). Desde el punto de vista de la programación
estructurada, una clase se asemejaría a un módulo, los atributos a
las variables globales de dicho módulo, y los métodos a las
funciones del módulo.
Una clase, es
simplemente una abstracción que hacemos de nuestra experiencia
sensible. El ser humano tiende a agrupar seres o cosas -objetos- con
características similares en grupos -clases-. Así, aun cuando
existen por ejemplo multitud de vasos diferentes, podemos reconocer
un vaso en cuanto lo
vemos, incluso aun cuando
ese modelo concreto de vaso no lo hayamos visto nunca. El concepto de
vaso es una abstracción de nuestra experiencia sensible.
Quizás el ejemplo más
claro para exponer esto lo tengamos en las taxonomías; los biólogos
han dividido a todo ser (vivo o inerte) sobre la tierra en distintas
clases. Las clases son uno de los principales componentes de un
lenguaje de programación, pues en ellas ocurren todos los procesos
lógicos requeridos para un sistema, en si podemos definirlas como
estructuras que representan objetos del mundo real, tomando como
objetos a personas, lugares o cosas, en general las clases poseen
propiedades, comportamientos y relaciones con otras clases del
sistema. Una clase se compone por tres partes fundamentales:
Nombre: Contiene el
Nombre de la Clase.
Atributos: Representan
las propiedades que caracterizan la clase.
Métodos: Representan el
comportamiento u operaciones, la forma como interactúa la clase con
su entorno.
5.3 Método:
Se define como un
conjunto de acciones que un objeto puede realizar para conseguir un
propósito. Los métodos representan la parte viva e interesante de
un objeto y se emplean habitualmente para modificar las propiedades
del objeto. Al modificar cualquiera de las propiedades del objeto se
altera su apariencia y se genera un cambio que el usuario de la
aplicación puede percibir. Estos representan todas aquellas acciones
que puede realizar o se pueden llevar a cabo sobre un objeto de una
clase. Así, por ejemplo, la clase Perro puede tener los métodos
correr, comer, bañar y vacunar, por mencionar algunos de ellos. A
nivel de implementación, estos métodos son segmentos de código
similares a los procedimientos y funciones utilizadas en la
programación modular.
5.4 Atributo:
Los atributos son todas
aquellas características que le asociamos a un tipo de objeto
(clase). Si por ejemplo, queremos definir los atributos de una clase
llamada Perro, podemos especificar que son la raza, la edad, su color
y el nombre del dueño, por mencionar solo algunos de ellos. Los
atributos que asociamos a una clase, dependen en gran medida del uso
que le daremos dentro del sistema que diseñamos actualmente, pero
también pueden ser definidos pensando en futuras implementaciones.
5.5 Mensaje:
Normalmente
un único objeto por sí solo no es muy útil. En general, un objeto
aparece como un componente más de un programa o una aplicación que
contiene otros muchos objetos. Es precisamente haciendo uso de esta
interacción como los programadores consiguen una funcionalidad de
mayor orden y modelar comportamientos mucho más complejos. Una
bicicleta (a partir de ahora particularizaremos) colgada de un gancho
en el garaje no es más que una estructura de aleación de titanio y
un poco de goma. Por sí sola, tu bicicleta (por poner una bicicleta
en concreto) es incapaz de desarrollar ningunaactividad. Tu bicicleta
es realmente útil en tanto que otro objeto (tú) interactúa con
ella (pedalea).
Los
objetos de un programa interactúan y se comunican entre ellos por
medio de mensajes. Cuando un objeto A quiere que otro objeto B
ejecute una de sus funciones miembro (métodos de B), el objeto A
manda un mensaje al objeto B. En ocasiones, el objeto que recibe el
mensaje necesita más información para saber exactamente lo que
tiene que hacer; por ejemplo, cuando se desea cambiar la marcha de
una bicicleta, se debe indicar la marcha a la que se quiere cambiar.
Esta información se pasa junto con el mensaje en forma de parámetro.
Para un mensaje (objeto destinatario, método y parámetros) son
suficiente información para que el objeto que recibe el mensaje
ejecute el método o la función miembro solicitada. Los mensajes
proporcionan dos ventajas importantes:
- El
comportamiento de un objeto está completamente determinado (a
excepción del acceso directo a variables miembro públicas) por sus
métodos, así que los mensajes representan todas las posibles
interacciones que pueden realizarse entre objetos.
-
Los objetos no necesitan formar parte del mismo proceso, ni siquiera
residir en un mismo ordenador para mandarse mensajes entre ellos (y
de esta forma interactuar).
5.6 Encapsulamiento:
En los diagramas, las
variables del objeto se localizan en el centro o núcleo del objeto.
Los métodos rodean y esconden el núcleo del objeto de otros objetos
en el programa. Al empaquetamiento de las variables de un objeto con
la protección de sus métodos se le llama encapsulamiento.
Típicamente, el encapsulamiento es utilizado para esconder detalles
de la puesta en práctica no importantes de otros objetos. Entonces,
los detalles de la puesta en práctica pueden cambiar en cualquier
tiempo sin afectar otras partes del programa. El encapsulamiento de
variables y métodos en un componente de software ordenado es,
todavía, una simple idea poderosa que provee dos principales
beneficios a los desarrolladores de software:
- Modularidad, esto es, el código fuente de un objeto puede ser escrito, así como darle mantenimiento, independientemente del código fuente de otros objetos. Así mismo, un objeto puede ser transferido alrededor del sistema sin alterar su estado y conducta.
- Ocultamiento de la información, es decir, un objeto tiene una "interfaz publica" que otros objetos pueden utilizar para comunicarse con él. Pero el objeto puede mantener información y métodos privados que pueden ser cambiados en cualquier tiempo sin afectar a los otros objetos que dependan de ello.
Los objetos proveen el
beneficio de la modularidad y el ocultamiento de la información. Las
clases proveen el beneficio de la reutilización. Los programadores
de software utilizan la misma clase, y por lo tanto el mismo código,
una y otra vez para crear muchos objetos. En las implantaciones
orientadas a objetos se percibe un objeto como un paquete de datos y
procedimientos que se pueden llevar a cabo con estos datos. Esto
encapsula los datos y los procedimientos. La realidad es diferente:
los atributos se relacionan al objeto o instancia y los métodos a la
clase. ¿Por qué se hace así? Los atributos son variables comunes
en cada objeto de una clase y cada uno de ellos puede tener un valor
asociado, para cada variable, diferente al que tienen para esa misma
variable los demás objetos. Los métodos, por su parte, pertenecen a
la clase y no se almacenan en cada objeto, puesto que sería un
desperdicio almacenar el mismo procedimiento varias veces y ello va
contra el principio de reutilización de código.
5.7 Herencia:
La herencia es uno de
los conceptos más cruciales en la POO. La herencia básicamente
consiste en que una clase puede heredar sus variables y métodos a
varias subclases (la clase que hereda es llamada superclase o clase
padre). Esto significa que una subclase, aparte de los atributos y
métodos propios, tiene incorporados los atributos y métodos
heredados de la superclase. De esta manera se crea una jerarquía de
herencia. Digamos El mecanismo de herencia permite definir nuevas
clases partiendo de otras ya existentes. Las clases que derivan de
otras heredan automáticamente todo su comportamiento, pero además
pueden introducir características particulares propias que las
diferencian.
La
herencia es una herramienta clave para abordar la resolución de un
problema de forma organizada, pues permite definir una relación
jerárquica entre todos los conceptos que se están manejando. Es
posible emplear esta técnica para descomponer un problema de cierta
magnitud en un conjunto de problemas subordinados a él. La
resolución del problema original se consigue cuando se han resuelto
cada uno de los problemas subordinados, que a su vez pueden contener
otros. Por consiguiente, la capacidad de descomponer un problema o
concepto en un conjunto de objetos relacionados entre sí cuyo
comportamiento es fácilmente identificable puede ser
extraordinariamente útil para el desarrollo de programas
informáticos. La herencia proporciona las siguientes ventajas:
Primero:
Las clases
derivadas o subclases proporcionan comportamientos especializados a
partir de los elementos comunes que hereda de la clase base. A través
del mecanismo de herencia los programadores pueden reutilizar el
código de la superclase tantas veces como sea necesario.
Segundo:
Los
programadores pueden implementar las llamadas superclases
abstractas, que definen comportamientos genérico. Las clases
abstractas definen e implementan parcialmente comportamientos, pero
gran parte de estos comportamientos no se definen ni se implementan
totalmente. De esta forma, otros programadores pueden hacer uso de
estas superclases detallando esos comportamientos con subclases
especializadas. El propósito de una clase abstracta es servir de
modelo base para la creación de otras clases derivadas, pero cuya
implantación depende de las características particulares de cada
una de ellas. Un ejemplo de clase abstracta podría ser en nuestro
caso la clase vehículos. Esta clase sería una clase base genérica,
a partir de la cual podríamos ir creando todo tipo de clases
derivadas.
5.8 Polimorfismo:
Por polimorfismo
entendemos aquella cualidad que poseen los objetos para responder de
distinto modo ante el mismo mensaje. Pongamos por ejemplo las clases
hombre, vaca y perro, si a todos les damos la orden -enviamos el
mensaje- Come, cada uno de ellos sabe cómo hacerlo y realizará este
comportamiento a su modo. Veamos otro ejemplo algo más ilustrativo.
Tomemos las clases barco, avión y coche, todas ellas derivadas de la
clase padre vehículo; si les enviamos el mensaje Desplázate, cada
una de ellas sabe cómo hacerlo. Realmente, y para ser exactos, los
mensaje no se envían a las clases, sino a todos o algunos de los
objetos instanciados de las clases. Así, por ejemplo, podemos
decirle a los objetos Juan Sebastián el Cano y Kontiqui, de la clase
barco que se desplacen, con los que el resto de los objetos de esa
clase permanecerán inmóviles.
Del mismo modo, si
tenemos en pantalla cinco recuadros (marcos) y tres textos, podemos
decirle a tres de los recuadros y a dos de los textos que cambien de
color y no decírselo a los demás objetos. Todos estos sabrán cómo
hacerlo porque hemos redefinido para cada uno de ellos su método
Pintarse que bien podría estar en la clase padre Visual (conjunto de
objetos que pueden visualizarse en pantalla). En programación
tradicional, debemos crear un nombre distinto para la acción de
pintarse, si se trata de un texto o de un marco; en OOP el mismo
nombre nos sirve para todas las clases creadas si así lo queremos,
lo que suele ser habitual. El mismo nombre suele usarse para realizar
acciones similares en clases diferentes.
Si enviamos el mensaje
Imprímete a objetos de distintas clases, cada uno se imprimirá como
le
corresponda, ya que todos
saben cómo hacerlo.
El polimorfismo nos
facilita el trabajo, ya que gracias a él, el número de nombres de
métodos que tenemos que recordar disminuye ostensiblemente.
La mayor ventaja la
obtendremos en métodos con igual nombre aplicados a las clases que
se encuentran próximas a la raíz del árbol de clases, ya que estos
métodos afectarán a todas las clases que de ellas se deriven.
6. Lenguajes de POO usados en la
actualidad: recursos y comparaciones
Alguno de los
lenguajes de POO mas utilizados en la actualidad:
Lenguaje C++
El lenguaje de
programación surgió a mediados de los 80 gracias a Bjarne
Stroustrup y fue desarrollado a partir del lenguaje C en los
laboratorios AT&T Bell.
-Es un lenguaje orientado
a objetos aunque también tiene las mismas características que C,
como por ejemplo su eficiencia y el uso de punteros.
-Como es lógico, y
debido a que se creó a partir de C, C++ cuenta con diversas mejoras
y avances respecto de C, lo que le hace un lenguaje más completo y
por ello que los programadores tienden a programar más en este
lenguaje. Un programa en C++ soporta instrucciones escritas en C,
pero un programa escrito en C no nos permite ejecutar instrucciones
de C++, por lo que viéndolo de ésta forma resulta más cómodo
programar en C++.
-Es un lenguaje muy
popular debido a la eficiencia y robustez de sus programas.
-Además de ser un
lenguaje orientado a objetos, también nos permite realizar programas
estructurados, lo cuál nos da libertad a la hora de programar. Nos
da cierta libertad debido a que no es tan estricto a la hora de
escribir código como en C.
-Es un lenguaje
compilado, es decir, compila directamente al código que entienden
los ordenadores por lo que es uno de los lenguajes más rápidos.
-Es portable al gran
número de compiladores que permiten utilizar los programas en
diversos ordenadores con diferentes sistemas operativos.
-Soporta varios
paradigmas de programación. Un paradigma de programación (dicho de
manera informal) es una forma de pensar a la hora de programar, el
más utilizado es el paradigma de programación orientada a objetos.
-Un aspecto importante a
destacar es la amplia cantidad de manuales, libros y código fuente
disponibles sobre C++, lo que nos da ciertas facilidades a la hora de
aprender a programarlo.
Lenguaje Java
Surgió en 1991 gracias
a un grupo de ingenieros de Sun Microsystems como lenguaje de
programación para electrodomésticos. Fue en 1995 cuando Java
comenzó a utilizarse como lenguaje de programación de ordenadores.
Las características más importantes de este lenguaje de
programación son:
-Es un lenguaje orientado
a objetos. Un objeto se compone de atributos (estado del objeto) y
métodos (comportamiento) que actúan sobre esos atributos. Para
comprender lo que es un objeto, voy a mostrarles una analogía del
mundo real: al igual que en el mundo virtual, en el mundo real los
objetos tienen un estado y un comportamiento. Por ejemplo, un coche
es un objeto que tiene una serie de estados o atributos (matrícula,
marca, modelo, color, marchas) y una serie de comportamientos o
métodos (corriendo, parado, aparcando, cambio de marcha). Todos los
objetos tienen un identificador único que los diferencia del resto
de objetos. En el ejemplo anterior el identificador del coche es la
matrícula.
-Modularidad, nos permite
dividir los programas en pequeños módulos denominados clases, para
reducir la complejidad del problema y, en caso de producirse un
fallo, éste solamente afecta al módulo donde se produjo y no a todo
el programa.
-Es robusto, es decir, es
un lenguaje de programación fiable que reacciona adecuadamente ante
situaciones excepcionales.
-Es un lenguaje de
programación portable que nos permite utilizar los programas
desarrollados en java en cualquier ordenador con cualquier sistema
operativo.
-Dinámico, podemos
compilar y ejecutar los programas en tiempo real.
-Seguro, elimina los
accesos ilegales a memoria que realizan los punteros en C.
En definitiva, Java es
uno de los lenguajes más utilizados actualmente ya que podemos
reutilizar el código de los programas y su arquitectura neutral nos
permite utilizarlo en cualquier arquitectura y sistema operativo
independientemente de la máquina en que se realizó el programa. Es
un lenguaje fácil de aprender lo que reduce los tiempos de formación
y aprendizaje de las personas que lo vayan a utilizar. Las
perspectivas de futuro son que prácticamente toda la programación
será orientada a objetos, aspecto con el que ya cuenta Java y
permite acercarnos a la forma de pensar de las personas. Actualmente
Java cuenta con diversos entornos de desarrollo muy buenos como son
Netbeans o Eclipse.
Lenguaje Python
Python apareció en 1991
gracias a Guido Van Rossum. Se dice que es un lenguaje
multiparadigma ya que soporta diversos tipos de paradigmas de
programación como son la orientación a objetos, la programación
imperativa o ,en menor medida, la programación funcional.
Este lenguaje de
programación es soportado por varios sistemas operativos,
característica conocida como portabilidad. En cuanto al código, es
un lenguaje simple y sencillo con instrucciones claras y fácil de
leer. Se utilizan clases y sentencias de control, sin embargo, no
presenta encapsulación. Se pueden escribir instrucciones en código
C para poder ejecutar el código de una manera más rápida , por lo
que Python es compatible con instrucciones de C. También cabe
destacar que es un lenguajeinterpretado por lo que no es necesario
compilar el código antes de ejecutarlo, lo cual reduce los tiempos
de espera. Es un lenguaje tipificado que cuenta con un gran número
de librerías, tipos de datos y funciones que sirven de mucha ayuda
al programador y simplifican su trabajo.
Uno de los aspectos más
importantes es que se trata de un lenguaje libre y gratuito por lo
que se pueden realizar copias del software y modificarlo como se
quiera con tal de mejorarlo. Como consecuencia de ello existen
diversas versiones de Python. Se utiliza con mucha frecuencia gracias
a que es un lenguaje de propósito general que nos permite realizar
desde cualquier tipo de programa hasta desarrollar páginas web.
Lengusje PHP
PHP fue creado en 1995
por Rasmus Lerdorf para el desarrollo de aplicaciones web dinámicas
y se puede incorporar directamente a páginas HTML. PHP es
interpretado y ejecutado en el lado del servidor web y posteriormente
se envía el resultado al navegador. Es un lenguaje "Open
Source", es decir, es software libre al cual pueden acceder
todos los usuarios. PHP fue creado a partir de C, C++, Java, Pearl y
Python por lo que ,a parte de tener unas características propias,
tiene una mezcla de características de los lenguajes citados
anteriormente.
La sintaxis es muy
simple, clara y fácil de aprender ya que no es necesario definir los
tipos de variables y nos permite utilizar el paradigma de la
programación orientada a objetos, así como, la programación
orientada a procedimientos, imperativa y reflexiva. Como consecuencia
de ello, obtenemos un código sencillo, ordenado, estructurado y
fácil de manejar.
Al igual que el resto de
lenguajes citados, es portable y nos permite utilizarlo en cualquier
servidor web de cualquier sistema operativo. Como se ha comentado
anteriormente, PHP fue diseñado para Microsoft y sus sistemas
operativos, por lo que si se quiere utilizar en otros sistemas
operativos que no sean de Microsoft es necesaria una adaptación. Es
un lenguaje robusto y estable que dota de gran seguridad a las
páginas web contra ataques no deseados. Por último destacar su gran
capacidad para conectarse a cualquier base de datos como pueden ser
MySQL, PostgreSQL, Oracle, etc.
7. Herramientas para diagramar en
POO (Diseño y Planificación). Notación UML
Notación UML: En esta
parte se verá cómo se representan gráficamente en UML los
conceptos principales de la orientación a objetos.
7.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.
7.2 Elementos Comunes a
Todos los Diagramas
7.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.
7.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).
7.3 Diagramas de Estructura Estática
Con el nombre de
Diagramas de Estructura Estática se engloba tanto al Modelo
Conceptual de la fase de Análisis como al Diagrama de Clases de la
fase de Diseño. Ambos son distintos conceptualmente, mientras el
primero modela elementos del dominio el segundo presenta los
elementos de la solución software. Sin embargo, ambos comparten la
misma notación para los elementos que los forman (clases y objetos)
y las relaciones que existen entre los mismos (asociaciones).
7.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 (plegada), con los detalles como atributos y operaciones
suprimidos, siendo entonces tan solo un rectángulo con el nombre de
la clase. En la siguiente figura se ve cómo una misma clase puede
representarse a distinto nivel de detalle según interese, y según
la fase en la que se esté. Notación para clases a distintos niveles
de detalle.
7.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.
7.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.
7.3.3.1 Nombre de la
Asociación y Dirección
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 la Figura se puede leer la asociación como
“Director manda sobre Empleado”.
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.
7.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).
7.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.
7.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”.
7.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 la Figura). Por el contrario, cuando la clase asociación
tiene alguna operación o asociación propia, entonces se pone el
nombre en la clase asociación y se puede quitar de la línea.
7.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 la Figura se ha impuesto la restricción de que un jugador
no puede jugar en dos equipos distintos a lo largo de una temporada,
porque la multiplicidad de “Equipo” es 1 en la asociación
ternaria.
7.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.
7.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 la Figura siguiente, sólo
aparecen en el diagrama 3 tipos de departamentos, pero con los puntos
suspensivos se indica que en el modelo completo (el formado por todos
los diagramas) la clase “Departamento” tiene subclases
adicionales, como podrían ser “Recursos Humanos” y “Producción”.
7.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.
7.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.
7.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.
7.4.1.1 Actores
Un actor es una entidad
externa al sistema que realiza algún tipo de interacción con el
mismo. 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 (otros sistemas, sensores, etc.).
7.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.
7.4.1.3 Relaciones entre
Casos de Uso
Entre dos casos de uso
puede haber las siguientes relaciones:
• Extiende: Cuando un
caso de uso especializa a otro extendiendo su funcionalidad.
• Usa: Cuando un caso
de uso utiliza a otro.
Se representan como una
línea que une a los dos casos de uso relacionados, con una flecha en
forma de triángulo y con una etiqueta <<extiende>> o
<<usa>> según sea el tipo de relación.
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 la
Figura se muestra un ejemplo de Diagrama de Casos de Uso para un
cajero automático.
7.5 Diagramas de Interacción
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.
7.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.
7.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 la Figura anterior. También se
puede mostrar el anidamiento de mensajes con números de secuencia
como 2.1, que significa que el mensaje con número de secuencia 2 no
acaba de ejecutarse hasta que no se han ejecutado todos los 2. x .
7.6 Diagrama de Estados
Un Diagrama de Estados
muestra la secuencia de estados por los que pasa un caso de uso o un
objeto a lo largo de su vida, indicando 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
(del caso de uso o 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).
7.7 Fase de Planificación y
Especificación de Requisitos
Esta fase se corresponde
con la Especificación de Requisitos tradicional ampliada con un
Borrador de Modelo Conceptual y con una definición de Casos de Uso
de alto nivel. En esta fase se decidiría si se aborda la
construcción del sistema mediante desarrollo orientado a objetos o
no, por lo que, en principio, es independiente del paradigma empleado
posteriormente.
7.7.1 Actividades
Las actividades de esta fase son las
siguientes:
1. Definir el Plan-Borrador.
2. Crear el Informe de Investigación
Preliminar.
3. Definir los Requisitos.
4. Registrar Términos en el Glosario.
(continuado en posteriores fases)
5. Implementar un Prototipo. (opcional)
6. Definir Casos de Uso (de alto nivel
y esenciales).
7. Definir el Modelo
Conceptual-Borrador. (puede retrasarse hasta una fase posterior)
8. Definir la Arquitectura del
Sistema-Borrador. (puede retrasarse hasta una fase posterior)
9. Refinar el Plan.
El orden propuesto es el
que parece más lógico, y en él los pasos 5 y 7 pueden estar en
posiciones distintas. De todos modos, 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 Análisis y 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. Tan solo se va a ver por encima la
actividad de Definición de Requisitos en cuanto está relacionada
con los Casos de Uso, pues son éstos los que van a servir de punto
de partida en el Análisis Orientado a Objetos.
7.7.2 Requisitos
Un requisito es una
descripción de necesidades o aspiraciones respecto a un producto. El
objetivo principal de la actividad de definición de requisitos
consiste en identificar qué es lo que realmente se necesita,
separar el grano de la paja. Esto se hace en un modo que sirva de
comunicación entre el cliente y el equipo de desarrollo. Es
aconsejable que un documento de Especificación de Requisitos tenga
los siguientes puntos:
− Propósito.
− Ámbito del Sistema, Usuarios.
− Funciones del Sistema.
− Atributos del Sistema.
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 refinar los requisitos y mejorar la comprensión de
los mismos la técnica de casos de uso constituye una valiosa ayuda.
7.7.3 Casos de Uso
Un Caso de Uso es un
documento narrativo que describe la secuencia de eventos de un actor
(un agente externo) que usa un sistema para completar un proceso
[Jacobson92]. Es una historia o una forma particular de usar un
sistema. Los casos de uso no son exactamente requisitos ni
especificaciones funcionales, pero ilustran e implican requisitos en
las historias que cuentan. En un primer momento interesa abordar un
caso de uso desde un nivel de abstracción alto, es lo que se
denomina Caso de Uso de Alto Nivel. A si mismo 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 o casos de uso expandido.
7.7.4 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.
7.7.5 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.
7.7.6 Tipos de Casos de Uso
a) Según Importancia
Para poder priorizar los 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
7.7.7 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
7.7.8 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 relacionan los
casos de uso y se ilustran las relaciones en el Diagrama de Casos de
Uso (<<extiende>> y <<usa>>).
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).
7.7.9 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.
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:
7.7.10 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.
7.8 Fase de Construcción: Diseño
En la fase de Diseño se
crea una solución a nivel lógico para satisfacer los requisitos,
basándose en el conocimiento
reunido en la fase de Análisis.
7.8.1 Actividades
Las actividades que se realizan en la
etapa de Diseño son las siguientes:
1. Definir los Casos de Uso Reales.
2. Definir Informes e Interfaz de
Usuario.
3. Refinar la Arquitectura del Sistema.
4. Definir los Diagramas de
Interacción.
5. Definir el Diagrama de Clases de
Diseño. (en paralelo con los Diagramas de Interacción)
6. Definir el Esquema de Base de Datos.
El paso de Refinar la
Arquitectura del Sistema no tiene por qué realizarse en la posición
3, puede realizarse antes o
después.
7.8.2 Casos de Uso Reales
Un Caso de Uso Real
describe el diseño real del caso de uso según una tecnología
concreta de entrada y de salida y su
implementación. Si el caso de uso implica una interfaz de usuario,
el caso de uso real
incluirá bocetos de las ventanas y detalles de la interacción a
bajo nivel con los widgets (botón, lista
seleccionable, campo editable, etc.) de la ventana. Como alternativa a la
creación de los Casos de Uso Reales, el desarrollador puede crear
bocetos de la interfaz en papel,
y dejar los detalles para la fase de implementación.
7.8.3 Diagramas de Colaboración
Los Diagramas de
Interacción muestran el intercambio de mensajes entre instancias del
modelo de clases para cumplir
las post-condiciones establecidas en un contrato.
Hay dos clases de
Diagramas de Interacción:
1. Diagramas de Colaboración.
2. Diagramas de Secuencia.
De entre ambos tipos se
prefieren los Diagramas de Colaboración por su expresividad y por su
economía espacial (una interacción compleja puede ser muy larga en
un Diagrama de Secuencia).
La creación de los
Diagramas de Colaboración de un sistema es una de las actividades
más importantes en el
desarrollo orientado a objetos, pues al construirlos se toman unas
decisiones clave acerca del
funcionamiento del futuro sistema. La creación de estos diagramas,
por tanto, debería ocupar un
porcentaje significativo en el esfuerzo dedicado al proyecto entero.
7.8.3.1 Creación de Diagramas de
Colaboración
Para crear los Diagramas
de Colaboración se pueden seguir los siguientes consejos:
•Crear un diagrama
separado para cada operación del sistema en desarrollo en el ciclo
de desarrollo actual.
- Para cada evento del
sistema, hacer un diagrama con él como mensaje inicial.
• Si el diagrama se complica,
dividirlo en diagramas más pequeños.
• Usando los apartados
de responsabilidades y de post-condiciones del contrato de operación, y la descripción del
caso de uso como punto de partida, diseñar un sistema de objetos que interaccionan para
llevar a cabo las tareas requeridas.
La capacidad de realizar
una buena asignación de responsabilidades a los distintos objetos es una habilidad clave, y
se va adquiriendo según aumenta la experiencia en el desarrollo orientado a objetos. Booch, Rumbaugh y
Jacobson definen responsabilidad como “un contrato u obligación de
una clase o tipo”[BJR97].
Las responsabilidades están ligadas a las obligaciones de un objeto
en cuanto a su
comportamiento. Básicamente, estas responsabilidades son de los dos
siguientes tipos:
•Conocer:
- Conocer datos privados
encapsulados.
- Conocer los objetos relacionados.
- Conocer las cosas que puede
calcular o derivar.
•Hacer:
- Hacer algo él mismo.
- Iniciar una acción en otros
objetos.
- Controlar y coordinar actividades en
otros objetos.
Por ejemplo, puedo decir
que “un Recibo es responsable de imprimirse” (tipo hacer), o que
“una Transacción es responsable de saber su fecha” (tipo
conocer). Las responsabilidades de tipo “conocer” se pueden
inferir normalmente del Modelo Conceptual.
Una responsabilidad no
es lo mismo que un método, pero los métodos se implementan para satisfacer
responsabilidades.
7.8.4 Diagrama de Clases de Diseño
Al construir los
Diagramas de Colaboración se van usando clases procedentes del
Modelo Conceptual, junto con
otras creadas para encargarse de responsabilidades específicas. El conjunto de todas las
clases usadas, junto con sus relaciones, forma el Diagrama de Clases
de Diseño.
Un Diagrama de Clases de
Diseño muestra la especificación para las clases software de una aplicación. Incluye la
siguiente información:
• Clases, asociaciones
y atributos.
• Interfaces, con sus
operaciones y constantes.
• Métodos.
• Navegabilidad.
• Dependencias.
A diferencia del Modelo
Conceptual, un Diagrama de Clases de Diseño muestra definiciones de
entidades software más que conceptos del mundo real. En la Figura
anterior se muestra un ejemplo de Diagrama de Clases de
Diseño sencillo.
7.8.4.1 Relaciones de
Dependencia para Representar Visibilidad entre Clases
Cuando una clase conoce
a otra por un medio que no es a través de un atributo (una
asociación con la navegabilidad
adecuada), entonces es preciso indicar esta situación por medio de
una dependencia.
Un objeto debe conocer a
otro para poder llamar a uno de sus métodos, se dice entonces que el primer objeto tiene
“visibilidad” sobre el segundo. La visibilidad más directa es
por medio de atributo, cuando hay una
asociación entre ambas clases y se puede navegar de la primera a la segunda (un atributo de
la primera es un puntero a un objeto de la segunda). Hay otros tres
tipos de visibilidad que hay
que representar en el diagrama de clases mediante relaciones de dependencia:
- Parámetro: Cuando a un
método de una clase se le pasa como parámetro un objeto de otra clase, se dice que
la primera tiene visibilidad de parámetro sobre la segunda. La relación de dependencia
entre ambas clases se etiqueta con el estereotipo <<parámetro>>
(<<parameter>> en inglés).
- Local: Cuando en un
método de una clase se define una variable local que es un objeto de otra clase, se dice
que la primera tiene visibilidad local sobre la segunda. La relación de dependencia entre
ambas clases se etiqueta con el estereotipo <<local>>.
- Global: Cuando hay una
variable global en el sistema, y un método de una clase llama a un método de esa
variable global, se dice que la clase tiene visibilidad global sobre
la clase a la que pertenece
la instancia que es una variable global. La relación de dependencia entre ambas
clases se etiqueta con el estereotipo <<global>>.
No es necesario
representar la relación de dependencia entre clases que ya están
relacionadas por medio de una
asociación, que se trata de una “dependencia” más fuerte. Las
relaciones de dependencia se incluyen
tan solo para conocer qué elementos hay que revisar cuando se
realiza un cambio en el diseño
de un elemento del sistema.
a) Solitario: Caso
Particular de Visibilidad global
El uso de variables
globales no se aconseja por los efectos laterales que se pueden
presentar, pero hay un caso en el
que sí hay cierta globalidad: las clases que sólo van a tener una
instancia. Suele tratarse de clases
que se han creado en el diseño, que no aparecían en el Modelo Conceptual.
Varias clases de nuestro
sistema pueden querer llamar a los métodos de la única instancia de
una clase de ese tipo,
entonces sí se considera que es beneficioso que se pueda acceder a
esa instancia como un valor
accesible de forma global. Una solución elegante para este caso se implementa mediante un
método de clase para obtener esa única instancia (los métodos de
clase los permiten algunos
lenguajes orientados a objetos, por ejemplo Java), en vez de
definirla directamente como una
variable global. Para indicar que una clase sólo va a tener una
instancia, se etiqueta la clase con
el estereotipo <<solitario>> (<<singleton>>
en inglés), y las relaciones de dependencia entre las
clases que la usan y se etiquetan también <<solitario>>
en vez de <<global>>.
7.8.4.2 Construcción de
un Diagrama de Clases de Diseño
Para crear un Diagrama de
Clases de Diseño se puede seguir la siguiente estrategia:
1. Identificar todas las
clases participantes en la solución software. Esto se lleva a cabo analizando los Diagramas
de Interacción.
2. Representarlas en un
diagrama de clases.
3. Duplicar los atributos
que aparezcan en los conceptos asociados del Modelo Conceptual.
4. Añadir los métodos,
según aparecen en los Diagramas de Interacción.
5. Añadir información
de tipo a los atributos y métodos.
6. Añadir las
asociaciones necesarias para soportar la visibilidad de atributos
requerida.
7. Añadir flechas de
navegabilidad a las asociaciones para indicar la dirección de
visibilidad de los atributos.
8. Añadir relaciones de
dependencia para indicar visibilidad no correspondiente a atributos.
No todas las clases que
aparecían en el Modelo Conceptual tienen por qué aparecer en el Diagrama de Clases de
Diseño. De hecho, tan solo se incluirán aquellas clases que tengan interés en cuanto a que
se les ha asignado algún tipo de responsabilidad en el diseño de la interacción del
sistema. No hay, por tanto, un transición directa entre el Modelo
Conceptual y el Diagrama de Clases de
Diseño, debido a que ambos se basan en enfoques completamente distintos: el primero en
comprensión de un dominio, y el segundo en una solución software.
En la fase de Diseño se
añaden los detalles referentes al lenguaje de programación que se
vaya a usar. Por ejemplo, los
tipos de los atributos y parámetros se expresarán según la
sintaxis del lenguaje de
implementación escogido.
7.8.4.3 Navegabilidad
La navegabilidad es una
propiedad de un rol (un extremo de una asociación) que indica que es posible “navegar”
unidireccionalmente a través de la asociación, desde objetos de la
clase origen a objetos de la
clase destino. Se representa en UML mediante una flecha.
La navegabilidad implica
visibilidad, normalmente visibilidad por medio de un atributo en la clase origen. En la
implementación se traducirá en la clase origen como un atributo que
sea una referencia a la clase
destino.
Las asociaciones que
aparezcan en el Diagrama de Clases deben cumplir una función, deben
ser necesarias, si no es así
deben eliminarse.
Las situaciones más
comunes en las que parece que se necesita definir una asociación con navegabilidad de A a B
son:
• A envía un mensaje a
B.
• A crea una instancia
B.
• A necesita mantener
una conexión con B.
7.8.4.4 Visibilidad de
Atributos y Métodos
Los atributos y los
métodos deben tener una visibilidad asignada, que puede ser:
+ Visibilidad pública.
# Visibilidad protegida.
- Visibilidad privada.
También puede ser
necesario incluir valores por defecto, y todos los detalles ya
cercanos a la implementación que sean necesarios para completar el
Diagrama de Clases.
7.8.5 Otros Aspectos en
el Diseño del Sistema
En los puntos anteriores
se ha hablado de decisiones de diseño a un nivel de granularidad
fina, con las clases y objetos
como unidades de decisión. En el diseño de un sistema es necesario también tomar
decisiones a un nivel más alto sobre la descomposición de un
sistema en subsistemas y sobre la
arquitectura del sistema. Esta parte del Diseño es lo que se denomina Diseño
del Sistema. Estas decisiones no se toman de forma distinta en un desarrollo orientado a
objetos a como se llevan a cabo en un desarrollo tradicional. Por
tanto, no se va a entrar en este
documento en cómo se realiza esta actividad. Sí hay que tener en
cuenta que las posibles divisiones en subsistemas tienen que hacerse
en base a las clases definidas
en el Diagrama de Clases del Diseño
Bibliografia
http://zarza.usal.es/~fgarcia/doc/tuto2/I_1.htm
(I.1. Introducción a la programación Orientada Objeto)
http://luis.izqui.org/resources/ProgOrientadaObjetos.pdf
(Introducción a la Programación Orientada a Objetos. [PDF])
http://algonzalezpoo.wordpress.com/caracteristicas-de-poo/
(Caracteristicas de P.O.O)
http://frameworkphp.wordpress.com/2007/09/19/caracteristicas-de-la-programacion-orientada-a-objetos/
(Características de la programación orientada a objetos)
http://android-linux.net/12-desarrollo/22-ventajas-de-la-programacion-orientada-a-objetos-poo
(Ventajas de la Programación Orientada a Objetos (POO))
http://www.ciberaula.com/articulo/ventajas_poo/
(Ventajas de la programación orientada a objetos)
http://codejavu.blogspot.com/2013/05/conceptos-de-programacion-orientada.html
(Conceptos Básicos de Programación Orientada a Objetos)
http://dis.um.es/~jfernand/0506/dai/poo.pdf
(Programación Orientada a Objetos)
http://profesores.fi-b.unam.mx/carlos/java/java_basico3_3.html
(Encapsulamiento)
http://borjacasla.blogspot.com/2013/03/los-5-lenguajes-de-programacion-mas_2795.html
(Los 5 lenguajes de programación más utilizados en la actualidad)
http://www.uv.mx/personal/maymendez/files/2011/05/umlTotal.pdf
(Desarrollo Orientado a Objetos con UML)



















No hay comentarios:
Publicar un comentario