May 08

Aprendiendo Orientación a Objetos observando (y III)

Otro ejemplo de Orientación a Objetos y patrones en la API de java es la forma de construir las ventanas, la interface gráfica de usuario.

Todos los componentes visuales -JButton, JCheckBox, JList, etc- heredan de Component y todos tienen el método paint(Graphics). Este método, en cada componente, dibuja el componente sobre el Graphics que se le pasa.

Pasarle el Graphics es nuevamente una buena idea y una aplicación del patrón Estrategia. Un JButton sabe qué tiene que dibujar -líneas, sombras, icono, etc-, pero es Graphics el que realmente hace el dibujo. Esto da mucha versatilidad, puesto que si al JButton le pasamos un Graphics que pinte en pantalla, el botón se dibujará en pantalla. Si le pasamos un Graphics que dibuje en impresora, el botón se dibujará en una impresora y si le pasamos un Graphics que dibuje en un BufferedImage -una imagen en memoria-, el JButton se dibujará en una imagen. El mismo botón con exactamente el mismo código puede dibujarse en cualquier lado.

Es más, si le pasamos un Graphics2D -que como hereda de Graphics se puede pasar- al que hayamos aplicado alguna transformación con setTransform(), podemos obtener fácilmente botones "deformados": girados, a escala, cizallados, etc.

Sin embargo todo esto va más allá. Hay componentes java como los JPanel que está destinados a "contener" otros componentes java. De esta forma, podemos tener un panel que tenga dentro dos botones, una lista y un checkbox. Estos componentes se llaman Container. Pues bien, los Container también heredan de Component y también tienen un método paint(). ¿Qué hace este método paint() del Container?. Sencillo, simplemente dibuja lo que es el panel y luego, con un bucle, llama al método paint() de cada uno de los componentes que tiene dentro.

Esto es una aplicación del patrón compuesto -Composite-. Tenemos un componente compuesto -el Container- que implementa la misma interface que un componente simple, por lo que se puede tratar perfectamene como cualquier otro componente. Pero en realidad está "compuesto" de otros componentes simples y en el método del componente simple -paint() en este caso-, simplemente va llamando a todos los paint() de los componentes simples.

Este mecanismo permite fácilmente crearse unas piezas simples de un puzzle, crearse nuevas piezas componiendo piezas simples que a su vez podríamos usar para componer piezas más complejas.

Esta idea puede servir de base para una librería gráfica. Una clase Lienzo recibe ObjetosGraficos que tengan un método dibujate(Graphics). Así, por ejemplo, podemos tener un ObjetoGrafico Rectangulo, Circulo, etc. Podemos componer ObjetosGraficos, haciendo un ObjetoGrafico Tablero que esté compuesto de varios Rectangulo, o un coche a base de un par de Circulo-Rueda y alguna cosa más.

La idea importante que pretendo transmitir con estos tres artículos es símplemente que fijándose en como se hacen las cosas en la API de java, podemos aprender mucho sobre cómo hacer nuestros programas orientados a objetos, cómo se deberian organizar las clases para obtener cosas flexibles, modulares, ampliables y sobre todo muy reutilizables.

Si nos ponemos a mirar la API, encontraremos miles de ejemplos de casi todos los patrones de diseño y sería de tontos no dedicar un mínimo de atención a estos ejemplos.

Entradas relacionadas:

  • No hay entradas relacionadas.

Leave a Reply