Java para programadores(4.5). Programación orientada a objetos

Análisis y diseño orientado a objetos

Un gran proyecto de programación pasara por una gran cantidad de etapas, empezando con la especificación del problema que ha de resolver, seguido por el análisis del problema y el diseño del programa que lo resolverá.Solo entonces llegara la codificación, en donde el diseño del programa se expresara en algún lenguaje de programación real. Esto viene seguido por las pruebas y la depuración del programa. Posteriormente llega un largo periodo de mantenimiento, donde se van resolviendo cualquier problema nuevo que pueda aparecer en el programa y modificándolo para irlo adaptando a nuevos requerimientos. Todas estas etapas forman parte de un conjunto que se ha dado en llamar ciclo de vida del programa. ( En el mundo real esta secuencia ideal de etapas consecutivas, no es algo que se encuentre fácilmente. Durante la fase de análisis a menudo se descubre que las especificaciones están incompletas o son inconsistentes. Un problema que aparece durante la fase de pruebas puede requerir como mínimo un pequeño retorno a la etapa de codificación. Y si es lo bastante serio, puede enviarnos nuevamente a la de diseño.)

Los grandes y complejos proyectos de programación, solo pueden tener éxito si se realiza una lenta y cuidadosa aproximación al problema durante todas las etapas de su ciclo de vida.

La aproximación sistemática a la programación empleando las leyes aceptadas sobre diseño correcto, se llama ingeniería de software.

La ingeniería de software intenta construir programas eficientes por medio de la verificación previa de las especificaciones, y haciendo mas fácil la modificación si fuera necesario. Existen un gran rango de metodológicas que pueden emplearse para ayudarle a sistematizar el diseño de programas. (La mayoría de esas metodológicas están relacionadas con el dibujar pequeñas cajas que representan componentes del programa, con flechas etiquetadas que representan relaciones con otras cajas.)

Hasta ahora,  hemos hablado de lo que es importante para el desarrollo del programa en la etapa de codificación, en un lenguaje de programación orientado a objetos. Pero también existe metodología orientada a objetos para el análisis y el diseño. La pregunta aquí es:

¿Como se puede descubrir o inventar la estructura global del programa?.

Como ejemplo a la aproximación mas simple al análisis y diseño orientados a objeto, tenga en cuenta este consejo:

Escriba la descripción del problema.

Subraye todos los sustantivos que encuentre.

Los sustantivos deben considerarse posibles candidatos para convertirse en clases en el diseño del programa.. De forma similar, subraye los verbos. Estos serán candidatos a métodos. Este es su punto de arranque.

Posteriores análisis pueden convencerle de la necesidad de mas clases y métodos, y pueden revelarle como organizar las clases jerárquicamente para aprovechar las similitudes entre clases.

Puede que lo haya expuesto de una forma un poco simple, pero la idea es clara. Analizar el problema para descubrir los conceptos implicados, y crear clases que representen estos conceptos. El diseño nace del propio problema, y puede finalizar con un programa en cuya estructura se refleja la estructura del problema en la vida real.


Componentes comunes de programas

Cada programador produce una cantidad importante de técnicas y experiencias expresadas como pequeños trozos de código que pueden reutilizarse en nuevos programas por el conocido método de cortar y pegar.

El código antiguo se copia en el nuevo programa y puede ser editado y personalizado si fuera necesario. El problema es que esta edición es una posible fuente de errores y de consumo de tiempo y el conjunto de la aventura depende de la habilidad de un programador de encontrar el trozo de código apropiado que puede estar entre los proyectos desarrollados el ultimo año. (A nivel de empresa, se quiere ahorrar dinero por medio de no tener que reinventar la rueda en cada nuevo proyecto, precisamente el seguimiento de donde paran esas viejas ruedas es una de las mayores tareas.)

Un diseño correcto de las clases permite que los componentes de programas puedan ser reutilizados sin necesidad de editarlos. Si necesita personalizar la clase, se puede crear una subclase haciendo en ella  las adiciones o modificaciones necesarias sin necesidad de hacer ningún cambio en la clase original.

Esto es lo que se tiene que hacer cuando el programador no tiene accedo al código fuente original de la clase y no sabe nada acerca de los detalles internos, de su implementacion oculta.

Muchas clases están diseñadas específicamente como bases para construir subclases.   Por ejemplo el paquete (package) java.awt incluye una clase llamada Frame; un objeto de esta clase representa una ventana de la pantalla con interface gráfica de usuario. Un objeto Frame tiene la mayoría de comportamientos asociados a Windows:

Por ejemplo, puede ser redimensionado por arrastre.Pero esta totalmente vacío. Una ventana Frame está completamente en blanco. Es el programador que quiere la ventana, que debe crear una subclase de Frame y regrabar algunos métodos para poder darle contenido a la ventana.La mayoría del comportamiento de esta ventana se hereda de Frame y no necesita ser reprogramado.


Vamos a ver , con un trabajo previo, como podemos construir Curso de Java. Orientacion a objetosuna clase. Suponga que quiero trabajar con un mosaico de cuadrados de colores, donde los colores están ordenados simétricamente como muestra la ilustración de la derecha. Cada vez que se colorea un cuadrado, el cuadrado correspondiente por reflexión vertical y horizontal respecto al centro del mosaico, se debe colorear de la misma forma. Los cuatro cuadrados rojos del dibujo, por ejemplo se crean como cuadrados simétricos, lo mismo ocurre con los púrpura y con los verdes.(El cuadrado azul esta en el centro del mosaico, por lo que su reflexión no puede producir otro ya que es el mismo.)

¿Como puedo implementar una rejilla de cuadrados?. Lo podría hacer empezando desde cero, pero en antes explique la clase MosaicWindow que implementa una rejilla de cuadrados de colores aunque no necesariamente simétricos. Si esta clase está disponible, quizás pueda construir una clase llamada SymmetricMosaic que siempre presente  patrones simétricos de cuadrados de colores.

De hecho la idea es simple:SymmetricMosaic es exactamente igual a MosaicWindow excepto que siempre que se establece un cuadrado de color, establecemos automáticamente el color de los cuadrados situados en los lugares simétricos. Requerirá algo de matemática para calcular los lugares concretos de los cuadrados reflejos teniendo en cuenta que la filas se numeran de 0 a ROWS-1 y las columnas desde 0 1 COLUMNS-1. (Si quiere puede verificar las formulas que empleo)

Ahora, la clase MosaicWindow ya tiene un método llamado setColor(), para establecer el color de un cuadrado concreto. Deberemos regrabar este método con otro que ponga el mismo color también en los lugares simétricos. Para poner el color de cada cuadrado, necesitare llamar al método setColor() desde la superclase MosaicWindow. Para hacerlo, usare la variable especial super descrita en la sección anterior. Entonces, la clase SymetricMosaic puede quedar definida así:

        class SymmetricMosaic extends MosaicWindow {
            void setColor(int R, int C, double r, double g, double b) {
                  // establece el color del cuadrado en la fila R,
          // columna C al color con los componentes rojo, azul
                  // y verde definidos por r,g,y b. También cambia 
                  // los colores de los cuadrados obtenidos por 
                  // la reflexión vertical y horizontal.
                super.setColor(R, C, r, g, b);
                super.setColor(R, COLUMNS - 1 - C, r, g, b);
                super.setColor(ROWS - R - 1, C, r, g, b);
                super.setColor(ROWS - R - 1, COLUMNS - 1 - C, r, g, b);
            }
        }

Esto deberia bastar. En SymmetricMosaic los cuadrados se colorean en grupo para conservar la simetría. Esto asumiendo, por cierto, que ROWS y COLUMNS son instancias de variables pertenecientes a MosaicWindow que definen el numero de filas y columnas del mosaico. Asumiendo también que tanto ROWS como COLUMNS no se declararon en MosaicWindow como private en cuyo caso no seria correcto su uso aquí. Mas probablemente debieron ser declaradas como protected para hacerlas accesibles a las subclases de MosaicWindow.

Todo esto deberia ser así, pero vale la pena observar que cuando realmente lo quiero emplear, me doy cuenta que no puedo hacer ningún objeto del tipo SymmetricMosaic!. El problema es que MosaicWindow tiene un constructor,

MosaicWindow(int ROWS, int COLUMNS)

El constructor especifica el numero de filas y columnas que se desean para el mosaico. El problema esta en que cada constructor en la subclase SymmetricMosaic debe llamar al constructor de la superclase.  Entonces voy a tener que hacer en la subclase un sencillo constructor que llame al constructor de la superclase. En un  articulo anterior vimos las explicaciones sobre constructores en las subclases.(Todo esto es un tecnicismo que se hubiera podido evitar si se hubiera diseñado Java un poco mejor en este aspecto) Aquí tenemos completa la versión correcta de la clase SymmetricMosaic:

        class SymmetricMosaic extends MosaicWindow {
            SymmetricMosaic(int ROWS, int COLUMNS){  // constructor
               super(ROWS, COLUMNS); // llama al constructor de la superclase
            }
            void setColor(int R, int C, double r, double g, double b) {
                super.setColor(R, C, r, g, b);
                super.setColor(R, COLUMNS - 1 - C, r, g, b);
                super.setColor(ROWS - R - 1, C, r, g, b);
                super.setColor(ROWS - R - 1, COLUMNS - 1 - C, r, g, b);
            }
        }

En otro articulo usé la clase MosaicWindow en un programa que presentaba una “alteración” errante vagando de forma aleatoria sobre un mosaico, cambiando los colores por donde pasaba. Es importante observar que podemos modificar el programa para emplear el mosaico simétrico cambiando únicamente la línea

MosaicWindow mosaic = new MosaicWindow(ROWS,COLUMNS);

por

MosaicWindow mosaic = new SymmetricMosaic(ROWS,COLUMNS);

Todas las llamadas que se hacían a mosaic.setColor()   cambiaran el color de forma simétrica a cuatro cuadrados. (De esta forma, después de ver el resultado,  me doy cuenta que el ojo no es capaz de detectar la simetría basándose únicamente en el cambio de colores por lo que pienso que se vera mejor si empiezo sobre un fondo blanco, para que se vea como se va construyendo el mosaico con cuadrados simétricos:)

Acerca de Miguel Garcia

Programador, Desarrollador web, Formador en distintas areas de informatica y director de equipos multidisciplinares.
Esta entrada fue publicada en Formacion, Java y etiquetada , . Guarda el enlace permanente.

2 respuestas a Java para programadores(4.5). Programación orientada a objetos

  1. Pingback: Java para programadores(4). Diseño de programas II. Objetos y clasesRecursos para formacion

  2. Pingback: Java - Un resumen organizado....o no.Recursos para formacion

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.