Sunday, October 14, 2007

Jerarquias (Object Based)

Disclaimer:

Este post es (particularmente) computronico, si quieren no lo lean :)

Historia previa:

El otro dia (asi empiezan todas las historias), con mat y despues con tenuki estabamos pensando sobre el concepto de classe en la programacion basada en objetos. No se si ellos estaban de acuerdo con lo que voy a escribir, pero ayudaron mucho a que estas cosas se organizen asi en mi cabeza :P.

Idea:


Basicamente, pensamos que existen dos tipos distintos de penzar el concepto de clase cuando se programa pensando en objetos.
La primer forma de penzar las clases (y la jerarquia de clases) es desde un punto de vista conceptual. Una clase representa un concepto, y sus subclases representan particularidades de este concepto (la idea de especie y subespecies). Este es un approach Top-Down, ya que primero hacemos el circulo grande donde definimos a la clase, y adentro de este circulo grande hacemos los circulos pequeños que definen a las subespecies. El consumidor de este concepto es un consumidor externo al objeto que es de la clase (o subclase).
Ejemplo: a un mamifero le podemos preguntar la cantidad de tetas que tiene. Eso lo podemos hacer, por que independientemente del mamifero que sea, el concepto de mamifero implica tener tetas.
Como el consumidor es externo, y el concepto es un concepto que se presenta al mundo, tiene sentido que los metodos (los mensajes) de las instancias de esta clase sean publicos, ya que esperamos que desde afuera se utilize este objeto a travez de la representacion conceptual que esta jerarquia esta ofreciendo. Mas aun, desde este punto de vista, tiene todo el sentido del mundo el concepto de classes abstractas (pure concept), y estas clases definen una interface para ofrecer al mundo, pero los elementos que estan en niveles mas particulares (inferiores ?) de la jerarquia tienen que definir como es el comportamiento puntual. Volviendo al ejemplo, sabemos que los mamiferos tienen tetas, pero dependiendo de cada especie la cantidad de tetas que (mas o menos) tienen.
Una de las principales ventajas que tiene esta forma de pensar las clases es la facilidad del uso, yo no necesito saber de que subespecie es tal objeto en particular, ya que puedo utilizar los conceptos que me brinda la especie. Ademas, permite programar comportamiento utilizando metaforas, que es una forma comoda para nuestro cerebro de manejar unos y ceros de forma compleja.


Por otro lado, existe otra forma de pensar el concepto de clases, que es desde un punto de vista mas matematico o funcional. Tenemos un par de objetos (que corresponden a clases distintas), y podemos pensar que puede existir alguna relacion entre estas clases cuando comparten algun tipo de comportamiento. Entonces vamos a agrupar a estas clases en una clase que va a ser "comparten tal comportamiento". Aca el approach es Bottom-Up, ya que primero tenemos los circulitos chiquitos con las clases particulares, y despues armamos un circulo mas grande en donde las agrupamos gracias a este comportamiento compartido. Los usuarios de esta jerarquia son las mismas subclasses, cuando se pretende reusar comportamiento, y agruparlo en un mismo lugar. Me parece que desde este punto de vista, tiene todo el sentido del mundo la existencia de mensajes o herencia "protected", ya que esta jerarquia no ayuda a trabajar con las clases a los consumidores externos, pero permite la reutilizacion de codigo.
Para que este tipo de jerarquia funcione bien, creo que los metodos que se comparten deberian ser metodos donde existe pure behaviour, que esta mas relacionado con el paradigma funcional que con el de Basado en Objetos.
Una de las desventajas de esta forma de ver las clases (me parece), es poder identificar una forma univoca de crear las superclases (un nombre), pero quizas si se pienza como el comportamiento compartido, y no como un concepto compartido, sea mas facil de encontrarlo (al nombre).

Hace un tiempo tenuki me paso un paper sobre la implementacion de traits en smalltalk, y encontre este link: http://www.iam.unibe.ch/~scg/Research/Traits/ Creo que esto tiene mucho que ver con la segunda forma de ver a las clases.
En particular, creo que la implementacion de traits en smalltalk, puede producir un cambio en la dimension del paradigma. Si pensamos a los paradigmas como un especio, smalltalk esta claramente sobre la recta de Object Based. El poder generar una jerarquia de clases en base a comportamiento compartido desplaza un poco el lenguaje sobre el espacio Object Based-funncional.
Bueno, espero opiniones, por que esto me interesa :) (y ademas espero que no haya sido un lio)

saludos
/jb

13 comments:

jb said...

notas:
1) pensar se escribe con s, no con z :)
2) Creo que las dos formas de pensar la construccion de la jerarquia de clases, cuando las cosas que tienen que ir a infinito van para ese lado (tiempo), y las que tienen que ir para sero, se aproximan a cero (costo), tendrian que producir mas o menos lo mismo, pero lo que me interesa es plantear las diferencias conceptuales para aprobecharlas durante el proceso de construccion
3) La relacion que establesco con el paradigma funcional no tiene que ser necesariamente asi (y de hecho, el que sea asi produce una limitacion), eso lo puse por que tenia en mente la implementacion de trait de squeak, pero las clases pueden compartir cosas distintas a comportamiento para poder definir una superclase a ellas (gracias Manuk!)

Anonymous said...

La jerarquia de clases suena bien en las metaforas como "auto tiene cuatro ruedas,carro tambien tiene cuatro ruedas" o si hagamos el "vehiculo de cuatro ruedas". Pero eso es muy primitivo el mundo abstracto que se genera en los programas que hacemos incluso no muy complejos no es tan simple como eso. Los autos y los seres vivos tienen algunas limitaciones fisicas para su variedad que no la tienen las clases. Creo que deberiamos dejar de usar metaforas tan simples del mundo concreto para estas cosas, podemos buscar metaforas en ciencias abstractas si queremos. En el 2007 hablar todavia de cosas como mamiferos con tetas no lleva a buenas conclusiones sobre programación, despues de unos años programando se ve que son lindas esas metaforas pero solo al principio.
Un concepto simple: composicion, mucho mas poderoso que pensar en herencia. En lugar de " es un" "tiene un". Mamifero tiene tetas, muñeca de goma tiene tetas.
Muñeca de goma no es un mamifero, muñeca de goma puede ser objeto de plastico. Algunas tetas de algunos mamiferos tambien son objetos de plastico.
Esa es la conclusión.

jb said...

Hola anonymous:
a) El ejemplo de la composicion me vino como anillo al dedo, era justamente lo que queria mostrar en la segunda forma de construir clases (clases en el sentido "matematico"). Entonces la composicion es una forma de resolver el problema de las clases (clases en un sentido abstracto) (y reusabilidad de codigo) de forma elegante, pero por otro lado, el problema existe de que no hay una formalizacion en muchos lenguajes OO de definir este tipo de jerarquias (la jerarquia que estas armando cuando estas componiendo), y la unica forma de jerarquizar es a travez del esquema "es subespecie de". Con esto me refieron al nivel que tiene el keyword class o sublclass en relacion a como puedas implementar una composicion.
Asi que gracias por el ejemplo

b) Che, se noto mucha mala onda... keep cool

Gutes said...
This comment has been removed by the author.
Anonymous said...

No estoy de acuerdo con el problema de las metaforas. Por eso son metaforas. Cuando alguien intenta dar un salto cualitativo en una disciplina (principalmente en algo como la computacion, o el paradigma de objetos) las metaforas simples ayudan. Imaginate que para ejemplificarte esquemas de herencia o subespecies me ponga a hablar de tipos de cuenta bancaria, describiendo exhaustivamente como es cada una, que funcionalidades deberia ofrecer... O incluso alguno bien intrincado como los que mencionas "de la vida real". Se pierde el punto, vas a tardar mas tiempo pensando en los detalles de lo que queres modelar antes que en como modelarlo.
A mi me gustan esas metaforas, son 100% adecuadas para ejemplificar conceptos nuevos. Adelante por mi.

Gutes

Anonymous said...

b)Cool? buena onda? No esperes eso de mi.

c)Seguimos en inglés ?

d)Las metaforas son peligrosas no es fácil usar buenas metaforas y no se puede usar cualquier metafora con cualquier interlocutor.

Hablar de jerarquías está bien para una clase de introducción a la idea de los objetos y sus posibilidades de reuso de código. Se acuerdan de C++ y de los zip drive? Bueno ya pasó.
La jerarquía de clases es una manera, quien la propone trata de explicarla con metaforas. No reusemos esas metaforas para buscar nuevas formas de reusabilidad. No existe la jerarquía en nuestros problemas y nos obliga a volcarla en nuestro modelo, nosotros inventamos la jerarquía la usamos como herramienta debería ser una de tantas otras como la composición y algunos otros patrones.
La jerarquía como usted dice es una manera de resolver el problema de la resusabilidad. Solo una y tal vez pésima tal vez nunca fue buena idea.
En tu comentarioa a partir de "el problema existe.." no entendí nada de lo que quieres decir.
Y esto te lo esta diciendo un licenciado.

Anonymous said...

Muy bueno!

Valrhon said...

Que grande Anonymous!! jajaja

A mi me gusto lo de las tetas, siempre me gustaron las tetas y la idea de mezclar tetas y pc junta 2 vicios increibles.

Grande JB jejeje

Ano, da la cara :P

Anonymous said...

1- C++ no existe mas mis polainas.
2- conozco tantos licenciados que meten la pata una y otra vez... eso ya no es garantia de nada.
3- Te lo dice un casi licenciado.

Anonymous said...

Que tienes para aportar sobre el aproach bottom up?
Visita my flog.

jb said...

gracias a manuk, encontre que existe algo sobre subject oriented programming. En este paradigma, creo, la jerarquia esta definida desde cada sujeto (subjetiva), me parecio piola: http://en.wikipedia.org/wiki/Subject-oriented_programming

Ikariel said...

Creo que a la conclusión que llegaste está relacionada con dos procesos de razonamiento que van en distinto sentido.

El primer ejemplo que das, el de a partir de un concepto abstraerlo en una clase, y de ahí a las subclases, podríamos vincularlo con la deducción (De lo universal a lo particular). Donde de un modelo inferís las características de las particularidades.

El segundo lo podés ver como inducción, de un conjunto de elementos obtenés el patrón común que te permite meterlos a todos en un conjunto.
Creo que estas dos formas de razonar están vinculadas con la manera de crear clases.

En mi experiencia particular, he encontrado que la deducción es una manera más segura de crear la clase, ya que el concepto es conocido y si cambia la clase, lo va a hacer acorde al concepto.
En el segundo caso te basas en un conjunto de ejemplos, que puede no ser completo y quizás te encuentres con que no generalizaste bien (por lo que un refactor puede ser muy doloroso). En los casos de inducción suele ser menos doloros usar composición para extraer el comportamiento, ya que un cambio en la clase inducida, no produce un cambio estructural (pero puede ser igual de doloroso).

jb said...

gracias ikariel por tu comentario. Estoy muy contento por que claramente el post original permitio que se nos muevan un par de conexiones en nuestro cerebro, y pensar ciertas cosas de otra manera :)
Tambien me gusto mucho la comparacion con induccion/deduccion.
Con respecto a cual de las dos formas es mas dolorosa, creo que hay que tener en cuenta, que los lenguajes orientados a objetos (o basados en objetos), refuerzan la construccion de clases y jerarquias siguiendo la estructura "es subespecie de", por lo que, utilizar otro tipo de preorden (ja, lo dije!) para crear la estructura puede ser doloroso (palabra suficientemente descriptiva).
Insisto en que es algo de los lenguajes (de los que conosco yo, al menos), y, en principio, no seria del preorden.
Aunque, el preorden "es subespecie de", facilita ponerle nombres al conjunto de elementos que definen a la clase. Eso es un punto a favor de esa aproximacion