Posted by: Camilo Torres | June 4, 2009

Una relación entre la POO y las oraciones.

Una relación entre las oraciones, las clases, las variables y los métodos.

He estado viendo algún código escrito en Java que resulta no solo un poco difícil de entender sino que también es muy pesado para leer. Es un código difícil de entender porque el algoritmo no se ve claramente, resulta que muchas veces el programa tiene 300 o 500 líneas de código contínuas con puros detalles de implementación, todo metido en un solo método. En la mayoría de los casos, ese código hace algo sencillo como: generar un archivo con un formato particular, aplicar unas reglas a unos registros de BD, generar un reporte y cosas así. Pero resulta muy dificil de entender por la estructura desorganizada del código. También resulta pesado de leer precisamente por ese desorden, porque el código está todo metido en un solo método de Java con todos los detalles de implementación uno tras otro.

Ese código resulta difícil de mantener: toma mucho tiempo entender lo que hace. Al leerlo hay que adivinar el algoritmo y a la vez estar pendiente de los detalles. Cuando se llega a la mitad de un método que tiene 400 líneas de código, ya uno no recuerda lo que hacen las primeras líneas. En ese momento uno desearía que el código estuviera dividido en subtareas y que las subtareas sean llamadas de forma ordenada en un método controlador que sea corto y que al leerlo se vea claramente el algoritmo.

A raíz de esto me puse a reflexionar varias cosas sobre la programación orientada a objetos y sobre el diseño de los programas. Alguna gente piensa que mientras se programa también se va diseñando la solución. Esto no significa que no se haga un diseño previo de los programas, lo que significa es que la programación implica un esfuerzo intelectual que incluye la generación de parte del diseño del programa, más que todo el diseño detallado. Esto ocurre frecuentemente porque es muy costoso y lleva mucho tiempo hacer un diseño detallado para luego programarlo de forma casi mecánica; por el contrario en muchos casos es más conveniente hacer un diseño hasta cierto nivel de detalle intermedio y saltar luego a la programación, donde se teminan de diseñar los detalles mientras se construye el programa.

Es probable que en los programas que yo vi no pasaran por ninguna etapa de diseño. En algunos casos da la impresión que ni siquiera se reflexionó un poco sobre la estructura del programa. Ni hablar siquiera de refactoring; es comprensible que un primer diseño y un primer programa tenga ciertos defectos, al hacer refactor se logra ir mejorando el diseño del programa y la estructura del código fuente. Pero en estos casos hay indicios de que no se intentó hacer refactoring, da la impresión que dejaron el primer código que hicieron y funcionó, sin preocuparse por la estructura.

La Reflexión
Hay muchas cosas que se pueden hacer para remediar este problema, basta con seguir los consejos de programación que existen desde hace años.

Pero esto me ha llevado a una sencilla reflexión de cómo enseñar algunas cosas a las personas que están aprendiendo a programar y también a los que programan desordenadamente. El bojetivo de esta reflexión es buscar una forma sencilla de explicar o enseñar a los programadores un solo aspecto sobre el paradigma de programación orientado a objetos. Aquí van mis reflexiones.

La Oración: Sujeto y Predicado
La oración está compuesta principalmente por dos elementos: sujeto y predicado.

El sujeto de la oración es la persona, ser o cosa sobre la cual se está refieriendo.

El predicado es lo que hace o sobre lo que se aplica en el sujeto. Existen dos tipos de predicados: predicados nominales y predicados verbales.

Los predicados nominales representan una cualidad o un estado del sujeto en la oración. Los predicados verbales representan una acción del o sobre el sujeto.

Ejemplos de Oraciones
Veamos ahora con unos ejemplos:

Oración: el ratón está quieto
El sujeto es: el ratón; el predicado es de tipo nominal, ya que representa una cualidad o estado del ratón: está quieto.

Oración: el ratón se detiene
El sujeto sigue siendo: el ratón; el predicado ahora es de tipo verbal, pues representa una acción que está realizando el sujeto: se detiene. La diferencia con el predicado nominal del ejemplo anterior es que no se sabe si el ratón está quieto o no, solo se sabe que está detiéndose.

Oración: el ratón salta de la ventana al jardín
Esta oración es más complicada, el sujeto sigue siendo el mismo ratón; el predicado es verbal, porque indica una acción que está haciendo el ratón, pero da unos datos adicionales que son la ventana y el jardín, los lugares de origen y destino del salto. La ventana y el jardín forman parte nominal del predicado porque indican el estado anterior y el estado posterior a la acción (es decir al salto).

¿Qué tiene que ver esto con la POO?
Ya entendiendo esta simple estructura de la oración pasamos a ver cómo se une con la programación orientada a objetos.

Clases ~ Sujetos
En muchos lenguajes el programador va construyendo clases para modelar el programa que quiere construir.

Supongamos que queremos hacer un programa para controlar los ratones virtuales dentro de un juego de simulación que pasea por las casas de las personas virtuales. Entonces podríamos tener una clase llamada Ratón ya que todos los ratones harán básicamente lo mismo: merodear por allí.

public class Raton

Es algo muy natural que el sujeto de la oración se convierta en el objeto o la clase al momento de programar. En la mayoría de los casos los objetos y las clases representan sujetos de las oraciones.

Supongamos que queremos hacer unos reportes de personas asociadas a una logia que llevan: encabezado, cuerpo y un total, cada uno de una base de datos distinta. Al momento de analizar la información de lo que va a hacer el reporte nos damos cuenta que:
– Cada reporte debe colocar las etiquetas nombre, teléfono y servicio en el encabezado.
– Cada reporte debe buscar los datos en una base de datos.
– Cada reporte debe escribir correctamente el nombre, el teléfono y el servicio correcto para cada asociado.
– Cada reporte debe escribir un pie con el total de los asociados.

Vemos que son oraciones, cada requerimiento analizado se puede describir con una oración. En este caso el sujeto siempre es “el reporte” y que todos los reporte hacen básicamente lo mismo, por lo que se podría tener una clase “Reporte” que modele este sujeto:

public class Reporte

Ahora bien, ya vimos que los sujetos en las oraciones se modelan como clases y objetos en la POO. ¿Qué pasa con los predicados? pues bien, veamos cada tipo de predicado por separado.

Predicados Nominales ~ Variables o Atributos de Clases y Objetos
Para el caso de los predicados nominales, estos son los que indican cualidad o estado del sujeto, se utilizan variables de objeto o atributos de objeto (en Java se llaman atributos). Ejemplo, para saber si el ratón está detenido y para saber su velocidad cuando se mueve o salta:

public class Raton {
boolean estaDetenido;
int velocidad;
}

Otro ejemplo con respecto a los reportes que vimos anteriormente, cada reporte toma sus datos de una base de datos distinta:

public class Reporte {
DataSource baseDeDatosDeAsociados;
}

Entonces vemos que los predicados nominales se modelan como atributos o variables de objeto o de clase.

Predicados Verbales ~ Rutínas, Funciones o Métodos
Finalmente los predicados verbales implican alguna acción (algún verbo que indica la acción) que realiza el objeto y se modelan como métodos porque es allí donde van los pasos necesarios para ejecutar una acción. Generalmente el objeto tiene un estado antes de ejecutar la acción y otro distinto luego que termina la acción. Ejemplos:

public class Raton {
boolean estaDetenido;
int velocidad;
String posicion = “ventana”;

boolean detener() {
estaDetenido = true;
velocidad = 0;
return estaDetenido;
}

void saltar(String desde, String hasta) {
if (posicion.equals(desde)) {
posicion = hasta;
}
}

void main() {
detener()
saltar(“ventana”, “jardin”);
}
}

public class Reporte {
DataSource baseDeDatosDeAsociados;

void main() {
baseDeDatosDeAsociados = …;
escribirEncabezado();
traerDatos();
escribirCuerpo();
escribirTotal();
}
void escribirEncabezado() {
….
}
void traerDatos() {
….
}
void escribirCuerpo() {
….
}
void escribirTotal() {
….
}
}

En el ejemplo sencillo que se da del Reporte se puede ver claramente el algoritmo de funcionamiento en el método main(). Lo importante aquí no es mostrar que el programa esté correcto o no, solo es mostrar un ejemplo sencillo de cómo organizar el código para que sea fácil de leer. Por eso busqué la relación que existe entre las oraciones que usamos para comunicarnos en nuestro lenguaje natural y la forma de modelarlas en la programación orientada a objetos y particularmente en Java. Elegí Java porque es el lenguaje en que esta escrito el código que leí.

Conclusiones y Poner Claramente El Algoritmo
Entonces:
– Sujeto: se modela como clases y objetos.
– Predicado nominal: se modela como atributos o variables de clases y objetos.
– Predicado verbal: se modela como métodos de clases y objetos.

No son reglas dogmáticas aunque pienso que aplican en la mayoría de los casos.

Adicionalmente noté que es mejor tener un algoritmo claro (como el método main() del ejemplo del Reporte) y delegar los detalles en subrutinas (métodos de Java). Mientras los nombres de los métodos sean representativos de la acción que realmente hace el método y cada método haga solo una cosa, el algoritmo se entenderá bastante fácilmente.


Responses

  1. Excelente !!! Mejor analogía y tan explicativa imposible.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: