Analisis Preliminar
Durante el análisis vamos a definir más claramente qué es lo que va a hacer nuestro programa. Debemos
hacer varias cosas principalmente:
Identificar actores. En lenguaje UML, actores son los usuarios y cualesquiera otros sistemas con los que se
pueda comunicar nuestro programa. En nuestro programa de ajedrez, un actor sería el usuario que va a
jugar al ajedrez. Le llamaremos "jugador". También se indicaba como requisito que pueda aprender
aperturas. La persona que le va a enseñar aperturas a nuestro programa podría ser otro actor, al que
podemos llamar "maestro". Una misma persona puede ser varios actores. Por ejemplo si alguien compra
nuestro programa de ajedrez, a veces puede jugar y otras veces puede enseñarle aperturas. Es la misma
persona, pero el papel que desempeña en cada caso es distinto.
Identificar casos de uso. Un caso de uso es algo que un actor quiera hacer con nuestro sistema.
Por ejemplo, un caso de uso para un "jugador" es "jugar una partida". Está claro que el jugador quiere
nuestro programa para jugar una partida de ajedrez. Otro posible caso de uso es "análisis de un
tablero". El "jugador" pone las piezas en determinada posición y quiere que el ordenador le dé una lista de
posibles movimientos, etc, etc. En resumen, debemos obtener una lista de cosas que los actores van a
querer hacer con nuestro sistema. Deben ser cosas grandes y no meternos en los detalles. "Mover una pieza"
no sería un caso de uso, sino una parte de "jugar una partida". De aquí saldría un diagrama UML de casos
de uso.
Detallar casos de uso. En un texto vamos poniendo varios puntos. En cada punto ponemos sentencias del
estilo "el usuario hace tal cosa y el programa hace tal otra". Es decir, explicamos por escrito, desde el punto
de vista del usuario, qué es lo que tiene que hacer y qué es lo que va a hacer el ordenador. Por ejemplo,
para "jugar una partida"
El usuario indica que quiere jugar una partida. El programa le pregunta el color de las piezas con las que
quiere jugar.
El usuario elige el color. El programa le dibuja el tablero con las piezas colocadas en la posición
inicial. Las piezas del usuario en la parte inferior de la pantalla. Si el programa tiene blancas, piensa y
realiza el primer movimiento.
El usuario mueve su pieza. El programa comprueba que el movimiento es correcto, piensa y realiza su
propio movimiento.
Se repite el paso anterior hasta llegar a jaque mate o tablas.
En el caso de uso se detalla una situación normal, sin fallos ni situaciones raras. Al final debería ponerse
una pequeña lista con los posibles fallos o situaciones anómales.
Si el movimiento del ordenador pone en jaque al usuario, el ordenador avisa del jaque
Si el usuario intenta un movimiento incorrecto, el ordenador avisa y deja al usuario que vuelva a intentarlo
Advertir que en ningún caso nos hemos metido a detallar cómo va a hacer algo nuestro programa,
sólamente qué es lo que va a hacer.
Siguiendo los esquemas UML, podemos incluso hacer por cada caso de uso un diagrama de secuencia en
el que los objetos implicados son el actor (el "jugador") y nuestro programa, sin meternos dentro de él.
También en este paso podemos ir empezando a pensar en cómo van a ser las pantallas de la interface de
usuario, de nuestro programa.
Diagrama de clases del negocio. Es un diagrama de clases de objetos que tienen sentido para el usuario.
En el caso del ajedrez los objetos serían del estilo "tablero", "pieza blanca", "torre blanca", "jugador",
"cronómetro", "partida", "torneo" etc. Nunca "lista de piezas", "array de casillas", etc. También se presentan
las relaciones entre ellos, como "las piezas están en el tablero", "la torre blanca es una pieza blanca", etc.
Este diagrama a este nivel tiene dos utilidades:
Asegurar que los que saben del tema y los que hacen el programa están hablando de lo mismo.
Servir de base para el diseño detallado orientado a objetos.
Cuando el tema es más complejo o menos conocido que una partida de ajedrez, es posible que el
informático que programa no tenga muy claros muchos de los conceptos que tiene que manejar. No sabe
qué es un asiento contable, un balance, si hay relación entre ellos, etc. Es por eso importante hacer un
diagrama de este tipo, en conjunto con un experto o con el cliente, para asegurar que no hay
malentendidos.
DISEÑO PRELIMINAR
Aquí ya empezamos a pensar en cómo vamos a hacer las cosas.
En el diseño preliminar tratamos de establecer la arquitectura de nuestro programa. La arquitectura es un
esquema de en qué módulos/paquetes vamos a dividir nuestro programa, qué librerías. Si el programa es
suficientemente grande, quizás vaya en varios ejecutables, una arquitectura cliente/servidor, etc.
Viendo los casos de usos, deberíamos ver qué cosas podemos hacer comunes o como librerias aparte, que
podamos reutilizar. Por ejemplo, en nuestro caso del juego de ajedrez, podríamos hacer los siguientes
paquetes:
Paquete de ajedrez. Un paquete que sea capaz de jugar al ajedrez, pero sin ningún tipo de relación con las
pantallas. Si es una clase, tendría métodos del estilo "Poner_Piezas_Posición_Inicial()", "Mover_Pieza()",
"Dame_Siguiente_Movimiento()", etc, etc. Sólo con este paquete, seríamos capaces de jugar al ajedrez, o
de instanciar dos paquetes y hacer que jueguen entre ellos, o jugar en red, etc.
Interface con el usuario. Un paquete con el dibujo del tablero, las piezas, recoger los movimientos del
usuario etc.
Dentro de estos paquetes, podemos ir pensando más subpaquetes, etc.
En este punto y con los casos de uso en general, debemos tener cuidado. Según una crítica generalizada
a los casos de uso, estos llevan a un diseño funcional y no a uno orientado a objetos. Debemos tratar de
pensar en objetos y almacenarlos juntos en la misma librería cuando estén muy relacionados entre sí, no en
funciones. Por ello es buena idea tratar de agrupar las clases del diagrama de clases del negocio en
paquetes y tratar de desarrollar la arquitectura a partir de ellas.
Es importante en este paso definir las interfaces y relaciones entre paquetes. Para ello puede servir de
ayuda hacer los diagramas de secuencia de los casos de uso mostrando los actores, los paquetes y los
mensajes entre ellos. Según vayan creciendo los diagramas de secuencia por aquello de ir entrando en
detalles, podremos ir extrayendo subcasos de uso, como "mover pieza", "elegir color", etc.
DISEÑO DETALLADO
En el diseño detallado ya se entra a nivel de clases y métodos. Por cada paquete que hayamos extraido
en el paso anterior y siguiendo siempre los casos de uso, debemos ir detallando las clases que vamos a
implementar y los métodos que van a tener. Detallamos aun más los casos de uso y las interfaces de las
clases.
En este punto pueden ser de ayuda los patrones de diseño. La gente que ha ido diseñando a lo largo de la
historia, se ha encontrado con problemas (¿cómo hago que la clase A se entere que la clase B ha
cambiado sin necesidad de que B vea a A?, ¿En qué clase pongo el metodo que suma las clases A y B?
¿Como me aseguro que de esta clase sólo se haga una instancia?, etc, etc). Algunos de dichos problemas
salen con mucha frecuencia (como los indicados de ejemplo) y se han establecido soluciones "estandard",
que funcionan bien. Dichas soluciones se llaman patrones. No está de más leer algo sobre patrones de
diseño orientados a objetos para tener una lista de "soluciones" a aplicar.
Hay incluso patrones a nivel de arquitectura. Es bastante conocido, por ejemplo, el patrón separación
modelo-vista. En nuestro caso "modelo" sería el conjunto de clases que juegan al ajedrez. "Vista" sería el
conjunto de clases que "pintan" la partida en la pantalla. Hacer esa separación en dos módulos, hace que
nuestro módulo de ajedrez sea reaprovechable, incluso si cambiamos de entorno de ventanas
(de windows a ms-dos o de ms-dos a unix). Eso sí, es imprescindible que sólo la "vista" vea al "modelo" y
nunca al revés. Si lo hacemos al revés y queremos llevarnos nuestro "modelo" juego de ajedrez, tendremos
que llevarnos también parte de la "vista".
Implementación
En la etapa de Implementación comenzamos con el resultado de la etapa de Diseño e implementamos el
sistema en términos de componentes, es decir, ficheros de código fuente, scripts, ficheros de código binario,
ejecutables y similares.
El objetivo principal de la etapa de implementación es desarrollar la arquitectura y el sistema como un
todo. De forma más específica, los propósitos de la Implementación son:
- Definir la organización del código.
- Planificar las integraciones de sistema necesarias en cada iteración.
- Implementar las clases y subsistemas encontrados durante el Diseño.
- Para conseguir estos objetivos el flujo de trabajo de la etapa de Implementación consta de las
siguientes etapas:
- Estructurar el Modelo de Implementación.
- Crear el Plan de Integración.
- Implementar componentes.
- Validar componentes implementados.
- Integrar subsistemas.
- Validar Subsistemas implementados.
- Integrar el Sistema Software.
Los productos de desarrollo del software fundamentales que se desarrollan en la etapa de Implementación
son:
- Modelo de Implementación, que incluye Componentes, Subsistemas y el Producto.
- Informe del Modelo de Implementación.
- Arquitectura del Software (Modelo de Implementación).
- Plan de Integración.
En el ciclo de vida del software la etapa de Implementación es el centro durante las iteraciones de
construcción, aunque también se lleva a cabo el trabajo de implementación durante la fase de
Elaboración, para crear la línea base ejecutable de la arquitectura, y durante la fase de Transición, para
tratar defectos tardíos.
Ya que el modelo de implementación denota la implementación actual del sistema en términos de
componentes y subsistemas de implementación, es natural mantener el modelo de implementación a lo
largo de todo el ciclo de vida del software.
En la fase de implementación se instala el nuevo sistema de información para que empiece a trabajar y se
capacita a sus usuarios para que puedan utilizarlo. Pero la instalación puede realizarse según cuatro
métodos: Directo, paralelo, piloto y en fases. Veamos en qué se diferencian estos métodos:
• Método directo: Se abandona el sistema antiguo y se adopta inmediatamente el nuevo. Esto puede ser
sumamente riesgoso porque si algo marcha mal, es imposible volver al sistema anterior, las correcciones
deberán hacerse bajo la marcha. Regularmente con un sistema nuevo suelen surgir problemas de pequeña
y gran escala. Si se trata de grandes sistemas, un problema puede significar una catástrofe, perjudicando o
retrazando el desempeño entero de la organización.
• Método paralelo: Los sistemas de información antiguo y nuevo operan juntos hasta que el nuevo
demuestra ser confiable. Este método es de bajo riesgo. Si el sistema nuevo falla, la organización puede
mantener sus actividades con el sistema antiguo. Pero puede representar un alto costo al requerir contar
con personal y equipo para laborar con los dos sistemas, por lo que este método se reserva
específicamente para casos en los que el costo de una falla sería considerable.
• Método piloto: Pone a prueba el nuevo sistema sólo en una parte de la organización. Al comprobar su
efectividad, se implementa en el resto de la organización. El método es menos costoso que el paralelo,
aunque más riesgoso. Pero en este caso el riesgo es controlable al limitarse a ciertas áreas, sin afectar toda
la empresa.
• Método en fases: La implementación del sistema se divide en partes o fases, que se van realizando a lo
largo de un periodo de tiempo, sucesivamente. Una vez iniciada la primera fase, la segunda no se inicia
hasta que la primera se ha completado con éxito. Así se continúa hasta que se finaliza con la última
fase. Es costoso porque se hace más lenta la implementación, pero sin duda tiene el menor riesgo.
Los métodos piloto y en fases suelen ser los más practicados puesto que tienen menor riesgo. Como se
puede observar la decisión de adoptar cualquiera de los métodos estará influenciada por factores de riesgo
y disponibilidad de recursos. Otro aspecto importante de esta fase es la capacitación del personal, que
cobra especial importancia para asegurar el uso acertado del sistema. Se puede adelantar camino al
capacitar personal, antes incluso de contar con los equipos nuevos, para que el usuario se familiarice
con el nuevo sistema. Si el sistema es sencillo y el usuario tiene cierta experiencia, la capacitación
formal no se hace necesaria y bastarán algunas instrucciones para ponerle al tanto.
Testing
La prueba (testing) del software es un elemento crítico para la garantía de la calidad del software. El
objetivo de la etapa de pruebas es garantizar la calidad del producto desarrollado. Además, esta etapa
implica:
Verificar la interacción de componentes.
Verificar la integración adecuada de los componentes.
Verificar que todos los requisitos se han implementado correctamente.
Identificar y asegurar que los defectos encontrados se han corregido antes de entregar el software al cliente.
Diseñar pruebas que sistemáticamente saquen a la luz diferentes clases de errores, haciéndolo con la
menor cantidad de tiempo y esfuerzo.
La prueba no es una actividad sencilla, no es una etapa del proyecto en la cual se asegura la calidad, sino
que la prueba debe ocurrir durante todo el ciclo de vida: podemos probar la funcionalidad de los primeros
prototipos; probar la estabilidad, cobertura y rendimiento de la arquitectura; probar el producto
final, etc. Lo que conduce al principal beneficio de la prueba: proporcionar feedback mientras hay todavía
tiempo y recursos para hacer algo.
La prueba es un proceso que se enfoca sobre la lógica interna del software y las funciones externas. La
prueba es un proceso de ejecución de un programa con la intención de descubrir un error. Un buen caso de
prueba es aquel que tiene alta probabilidad de mostrar un error no descubierto hasta entonces. Una
prueba tiene éxito si descubre un error no detectado hasta entonces.
La prueba no puede asegurar la ausencia de defectos; sólo puede demostrar que existen defectos en el
software.
Cualquier proceso de ingeniería puede ser probado de una de dos formas:
Se pueden llevar a cabo pruebas que demuestren que cada función es completamente operativa.
Se pueden desarrollar pruebas que aseguren que la operación interna se ajusta a las especificaciones
y que todos los componentes internos se han comprobado de forma adecuada.
La primera aproximación se denomina prueba de la caja negra y la segunda prueba de la caja blanca.
Prueba de caja blanca:
Permiten examinar la estructura interna del programa. Se diseñan casos de prueba para examinar la
lógica del programa. Es un método de diseño de casos de prueba que usa la estructura de control del
diseño procedimental para derivar casos de prueba que garanticen que:
Se ejercitan todos los caminos independientes de cada módulo.
Se ejercitan todas las decisiones lógicas.
Se ejecutan todos los bucles.
Se ejecutan las estructuras de datos internas.
Prueba de caja negra:
Las pruebas se llevan a cabo sobre la interfaz del software, y es completamente indiferente el comportamiento
interno y la estructura del programa.
Los casos de prueba de la caja negra pretende demostrar que:
Las funciones del software son operativas.
La entrada se acepta de forma adecuada.
Se produce una salida correcta, y La integridad de la información externa se mantiene.
Se derivan conjuntos de condiciones de entrada que ejerciten completamente todos los requerimientos
funcionales del programa.
La prueba de la caja negra intenta encontrar errores de las siguientes categorías:
Funciones incorrectas o ausentes.
Errores de interfaz.
Errores en estructuras de datos o en accesos a bases de datos externas.
Errores de rendimiento.
Errores de inicialización y de terminación.
Los casos de prueba deben satisfacer los siguientes criterios:
Reducir, en un coeficiente que es mayor que uno, el número de casos de prueba adicionales.
Que digan algo sobre la presencia o ausencia de clases de errores.
Capacitación
Uno de los principales objetivos de softwarefactory® es asegurar el éxito de laimplementación ayudando al
cliente a comprender el gran potencial que la solución desarrollada tiene dentro de su organización.
El servicio de Capacitación de softwarefactory® permite a las empresas maximizar su inversión accediendo
a los conocimientos necesarios para aprovechar a fondo todas las funcionalidades de la metodología y/o
tecnología implementada. Un plan de Capacitación tradicional de softwarefactory® identificará las
necesidades de capacitación de la empresa, planificará cuidadosamente una estrategia e implementará
un plan efectivo para cumplir los objetivos.
softwarefactory® dicta cursos de entrenamiento en la aplicación de todos sus programas. Los cursos son
impartidos por los mismos que laboran día a día con estas herramientas en las tareas de consultoría, por lo
que se encuentran capacitados para transmitir no solamente las instrucciones de uso de los programas, sino
tambien las filosofías de modelamiento aplicado a la solucion del problema.
Tecnologias
Le asesoramos de las tecnologías que más se adaptan a su proyecto optimizando los recursos y costes
siempre orientados al usuario final.
Asesoramos a nuestros clientes para que rentabilicen al máximo su inversión en nuevas tecnologías,
aconsejándolos para alcanzar el máximo número de usuarios posibles.
En SoftwareFactory, tras analizar su demanda, podremos determinar el desarrollo software que necesita y
elegir el lenguaje de programación adecuado. La aplicación resultante será dinámica y contemplará las
posibles ampliaciones que puedan surgir en un futuro.