Este sitio web usa cookies de terceros para analizar el tráfico y personalizar los anuncios. Si no está de acuerdo, abandone el sitio y no siga navegando por él. ×


6. Programación orientada a objetos

6.1. ¿Por qué los objetos?

Cuando tenemos que realizar un proyecto grande, será necesario descomponerlo en varios subprogramas, de forma que podamos repartir el trabajo entre varias personas.

Esta descomposición no debe ser arbitraria. Por ejemplo, será deseable que cada bloque tenga unas responsabilidades claras, y que cada bloque no dependa de los detalles internos de otros bloques.

Existen varias formas de descomponer un proyecto, pero posiblemente la más recomendable consiste en tratar de verlo como una serie de "objetos" que colaboran entre sí.

Una forma de "descubrir" los objetos que forman parte de un programa es partir de la descripción del problema, y subrayar los nombres con un color y los verbos con otro color.

Como ejemplo, vamos a dedicar un momento a pensar qué elementos ("objetos") hay en un juego como el clásico Space Invaders. Cuando entramos al juego, aparece una pantalla de bienvenida, que nos recuerda detalles como la cantidad de puntos que obtendremos al "destruir" cada "enemigo":

Space Invaders, pantalla de bienvenida

Y cuando comenzamos una partida, veremos una pantalla como ésta, que vamos a analizar con más detalle:

Space Invaders, pantalla de juego

Observando la pantalla anterior, o (preferiblemente) tras jugar algunas partidas, podríamos hacer una primera descripción del juego en lenguaje natural (que posiblemente habría que refinar más adelante, pero que nos servirá como punto de partida)

Nosotros manejamos una "nave", que se puede mover a izquierda y derecha y que puede disparar. Nuestra nave se esconde detrás de "torres defensivas", que se destruyen poco a poco cuando les impactan los disparos. Nos atacan (nos disparan) "enemigos". Además, estos enemigos se mueven de lado a lado, pero no de forma independiente, sino como un "bloque". En concreto, hay tres "tipos" de enemigos, que no se diferencian en su comportamiento, pero sí en su imagen. Tanto nuestro disparo como los de los enemigos desaparecen cuando salen de la pantalla o cuando impactan con algo. Si un disparo del enemigo impacta con nosotros, perderemos una vida; si un disparo nuestro impacta con un enemigo, lo destruye. Además, en ocasiones aparece un "OVNI" en la parte superior de la pantalla, en la parte superior de la pantalla, que se mueve del lado izquierdo al lado derecho y nos permite obtener puntuación extra si le impactamos con un disparo. Igualmente, hay un "marcador", que muestra la puntuación actual (que se irá incrementando) y el récord (mejor puntuación hasta el momento). El marcador se reinicia al comienzo de cada partida. Antes de cada "partida", pasamos por una pantalla de "bienvenida", que muestra una animación que nos informa de cuántos puntos obtenemos al destruir cada tipo de enemigo.

A partir de esa descripción, podemos buscar los nombres (puede ayudar si los subrayamos con un rotulador de marcar), que indicarán los objetos en los que podemos descomponer el problema, y los verbos (con otro rotulador de marcar, en otro color), que indicarán las acciones que puede realizar cada uno de esos objetos.

De la descripción subrayada de este juego concreto podemos extraer los siguientes objetos y las siguientes acciones:

(En general, esta descomposición no tiene por qué ser única, distintos programadores o analistas pueden llegar a soluciones parcialmente distintas).

Esa serie de objetos, con sus relaciones y sus acciones, se puede expresar mediante un "diagramas de clases", que en nuestro caso podría ser así (simplificado):

Space Invaders, diagrama de clases inicial

El nombre "diagrama de clases" se debe a que se llama "clase" a un conjunto de objetos que tienen una serie de características comunes. Por ejemplo, un Honda Civic Type-R con matrícula 0001-AAA sería un objeto concreto perteneciente a la clase "Coche".

Algunos de los detalles que se pueden leer de ese diagrama (y que deberían parecerse bastante a la descripción inicial) son:

Faltan detalles, pero no es un mal punto de partida. A partir de este diagrama podríamos crear un "esqueleto" de programa que compilase correctamente pero aún "no hiciese nada", y entonces comenzaríamos a repartir trabajo: una persona se podría encargar de crear la pantalla de bienvenida, otra de la lógica del juego, otra del movimiento del bloque de enemigos, otra de las peculiaridades de cada tipo de enemigo, otra del OVNI...

Nosotros no vamos a hacer proyectos tan grandes (al menos, no todavía), pero sí empezaremos a crear proyectos sencillos en los que colaboren varias clases, que permitan sentar las bases para proyectos más complejos, y también entender algunas peculiaridades de los temas que veremos a continuación, como el manejo de ficheros en C#.

Como curiosidad, cabe mencionar que en los proyectos grandes es habitual usar herramientas gráficas que nos ayuden a visualizar las clases y las relaciones que existen entre ellas, como hemos hecho para el Space Invaders. También se puede dibujar directamente en papel para aclararnos las ideas, pero el empleo de herramientas informáticas tiene varias ventajas adicionales:

La metodología más extendida actualmente para diseñar estos objetos y sus interacciones (además de otras muchas cosas) se conoce como UML (Unified Modelling Language, lenguaje de modelado unificado). El estándar UML propone distintos tipos de diagramas para representar los posibles "casos de uso" de una aplicación, la secuencia de acciones que se debe seguir, las clases que la van a integrar (que es lo que a nosotros nos interesa en este momento), etc. Disponemos de herramientas gratuitas como ArgoUML, multiplataforma, que permite crear distintos tipos de diagramas UML y que permite generar el código correspondiente al esqueleto de nuestras clases, o Dia, también multiplataforma, pero de uso más genérico (para crear diagramas de cualquier tipo) y que no permite generar código por ella misma pero sí con la ayuda de Dia2code.

En los próximos ejemplos partiremos de una única clase en C#, para ampliar posteriormente esa estructura e ir creando proyectos más complejos.