Antes de realizar cualquier tipo de codificación (o ver el cursor parpadeante en la pantalla de nuestro ambiente de desarrollo) sin tener en mente lo que vamos a realizar, tenemos que comprender el problema, luego planificar la solución, y luego comenzar con la construcción de la pieza de software.
Metodologías de desarrollo
¿Hay una metodología que me permita de manera
óptima la realización de un programa?.
La respuesta a la pregunta
anterior es no, ya que existen actualmente muchas metodologías de desarrollo para diversas
necesidades. Recordar que no existe sólo un tipo de software.
La primera metodología
usada fue la llamada “en cascada”, la cual consistía en que pasábamos a la
siguiente etapa de desarrollo, sólo si la etapa actual estaba realizada.
Lamentablemente esta metodología actualmente no funciona. Los requerimientos
del cliente van en constante cambio, lo que sugiere volver a etapas anteriores
y así sucesivamente.
Por otro lado, tenemos el enfoque ágil e iterativo que actualmente es el más utilizado.
En cada uno de ellos haremos análisis, diseño y programación. Esto lo repetiremos
varias veces en cada etapa.
Lenguajes orientados a objetos
Antes de la aparición de
los lenguajes orientados a objetos, existían lenguajes de bajo nivel los cuales
se estructuraban por código línea a línea. A medida que los programas se
hicieron más y más grandes, estos lenguajes se veían limitados.
En los lenguajes orientados
a objetos cada objeto posee sus propios datos y su propia lógica. Estos objetos
se comunican entre sí para crear grandes proyectos con una mayor simplicidad.
Algunos de estos lenguajes son C++, C#, Perl, PHP, Python, Java, Ruby, VB.net y muchos más.
¿Qué es un objeto?
Para responder esta
pregunta debemos analizar que es un objeto en el mundo real.
Los objetos poseen
características inherentes que los hacen únicos. Una taza de café puede estar
llena o vacía, una manzana puede ser verde o roja, una copa de vino puede ser
grande o pequeña. Estas características son el estado de un
objeto, como su color, tamaño, forma, etc. Cada objeto posee un estado
que lo define y que es distinto al de otro objeto. Si apagamos una ampolleta,
esto no significa que apagaremos todas las ampolletas del mundo.
Además cada objeto posee un
comportamiento (acciones que pueden realizar), un perro ladra, una cuenta de
banco permite realizar un depósito, un balón se mueve, un televisor se
enciende y apaga, etc.
Los objetos no necesariamente deben ser objetos
físicos.
Los objetos no necesariamente deben ser
visibles.
Clase
Las clases describen como
serán nuestros objetos. Es una especie de plano el cual es usado para construir
nuestro objeto.
Instancias
El proceso de creación de
objetos se denomina instanciación. Cada objeto puede poseer ilimitado números
de instancias las cuales representan entidades diferentes. En este caso podemos crear N objetos Persona los cuales poseerán diferentes características que los hará únicos.
Muchas clases ya han sido creadas para satisfacer necesidades simples como generar una fecha, conectarse a una red, etc. Están clases están almacenadas en librerías de clases, más conocidas como frameworks de desarrollo, las cuales poseen funciones adicionales.
· Java Class Library
· .NET Framework
· C++ Standard Library
Es momento de hablar sobre las características principales de la programación orientada a objetos.
Abstracción
Nos centramos en las
características genéricas de un objeto y no en un ejemplo concreto.
Por ejemplo si decimos
auto, nuestra mente visualiza un auto verdad?. Esta imagen abstracta no está ligada a
ninguna propiedad en particular. No hemos dicho el auto rojo, o el auto de 4
puertas, solo hemos dicho auto. Eso es lo que hace la abstracción. Nos
centramos en las características generales y no entidades definidas.
Encapsulamiento
Ocultamiento de
información. Cada objeto sólo debe comunicarse con otro objeto sólo mediante
métodos, y prohibir el acceso a propiedades directamente. Esto nos da mayor
modularidad y mayor seguridad en nuestra aplicación.
Los atributos de clases deben ser siempre
privados.
Herencia
Re utilización de código.
Una clase hereda de otra y al mismo tiempo hereda todo lo que lleva consigo,
propiedades y métodos. Además puede agregar nuevas características a la
subclase.
Clase > Subclase
Clase padre > Clase hija
Podemos afirmar que una persona es un mamífero, y que un perro es un mamífero.
Polimorfismo
El término de polimorfismo se refiere a que una clase puede tomar diferentes formas. O sea, este mecanismo permite invocar operaciones idénticas con respecto a su interfaz padre, pero con una implementación diferente en la clase hija.
Como dijimos anteriormente, una subclase puede heredar todo lo que tiene su clase padre, y a su vez, modificar éstos últimos. Este y los demás temas hablados en esta entrada del blog, serán vistos con mayor profundidad en la sección de Java.
Proceso de diseño de Software
Para realizar un trabajo correcto, debemos seguir los siguientes procedimientos:
- Tomar requerimientos del cliente (lo que debe hacer nuestra aplicación)
- Describir la aplicación
- Identificar los objetos principales
- Identificar las interacciones entre nuestros objetos
- Crear nuestro diagrama de clases
Requisitos funcionales
Se refiere a lo que la aplicación en sí debe hacer, definiendo las características y capacidades del software a desarrollar.
Requisitos no funcionales
Se refiere a temas no realizadas con el desarrollo, ya sea el cumplimiento de leyes, que soporte se le dará y cuan a menudo, cual será su rendimiento óptimo, que se hará en caso de fallas, etc.
UML (Lenguaje unificado de modelado)
Este lenguaje se encarga de conceptualizar nuestras clases, objetos, paquetes, etc. en un diagrama que es mucho más entendible para un trabajo más rápido. Serán nuestros planes que nos servirán para decirnos que debemos hacer.
Casos de uso
Los casos de uso sirven para representar la interacción del usuario con el sistema, y como realiza diferentes acciones dentro del mismo.
Los diagramas de casos de uso están estructurado con los siguientes elementos:
- Caso de uso
- Actor
- Relaciones
Caso de uso: Es una tarea específica que se realiza mediante un agente externo, ya sea el propio actor, un actor de otro caso de uso, o incuso un sistema propiamente tal.
Posee un titulo (cual es el objetivo), un actor (quién lo ejecuta), y un escenario (cómo llegar al objetivo).
Actor: Es un rol que un usuario desempeña en el sistema. No necesariamente debe ser una persona, sino que es un ejecutante genérico de algún caso de uso.
Relaciones: Para unir nuestros actores con sus respectivos casos de uso debemos generar una relación que determine qué y cómo se ejecutará dicha operación.
Escenarios
Al determinar los escenarios de nuestros casos de uso, debemos hacer énfasis en el objetivo del actor en el sistema, y obviar escenarios que no correspondan a ello.
Por ejemplo, tenemos una aplicación mobile para pedir comida rápida a domicilio. Para llegar a realizar un pedido debemos de registrar nuestros datos para que los dueños del restaurant sepan donde vivimos y realicen el trayecto con éxito. ¿Cuál es el objetivo del usuario, registrar sus datos o pedir comida a casa?.
No debemos crear casos de uso que no contribuyan con el objetivo principal del usuario.
Diagrama de casos de uso
Es un tipo de diagrama UML encargado de ilustrar los diferentes casos de uso y actores, mostrando una perspectiva global de los miembros y sus interacciones.
Historias de usuario
Una historia de
usuario es más corto que un caso de uso. Se describe solo un pequeño escenario
centrado en el usuario y su objetivo. Se escriben en tarjetas con contenido
breve.
Estructura:
·
Cómo…
(tipo de usuario)
·
Quiero…
(objetivo)
·
Para…
(razón o fin)
Como usuario
Quiero ver el listado de productos disponibles
Para poder comprar una camisa
Modelo conceptual del sistema
Tenemos que
identificar los objetos principales,
refinarlos, y por último dibujarlos en un diagrama.
Nos enfocaremos en la construcción orientada a
objetos.
- Identificar los sustantivos escritos en nuestro escenario de caso de uso
- Crear una lista con los sustantivos seleccionados y eliminar duplicidades o sustantivos los cuales sean propiedades de un objeto y no un objeto en sí
- Luego creamos las clases con los sustantivos seleccionados
Definir responsabilidades
Éstos serán los comportamientos que se
convertirán en métodos. Buscaremos los verbos para recoger todas las
responsabilidades.
Las responsabilidades deben estar distribuidas
entre las diferentes clases. Una clase que realiza una acción, no significa que
sea responsable de esa acción.
Hay que
evitar las clases dios, o clases sistema.
Tarjetas CRC
Las tarjetas CRC definen cuáles serán las
responsabilidades de una clase y sus clases colaboradoras. Son creadas en papel
y se discuten entre el equipo de desarrollo.
Podemos tomar las tarjetas creadas y ponerlas
en un mesón para detectar sus interacciones.
Diagramas de clase
Evitar estructuras de datos planas al escribir
demasiadas propiedades sin métodos (responsabilidades) que los completen y/o
utilicen.
Miembros estáticos
Son variables o
métodos compartidos que no dependen
de un objeto en particular, sino que depende de la clase.
Ejemplo: private
static final cargo = 25000;
Esta variable puede
ser accedida por distintos objetos y su valor será igual para todos. Existirá
solo una copia de ésta.