On Thu, Apr 24, 2008 at 08:25:17AM -0300, Abel Fillol wrote:
> Sencillamente no tienen idea de lo que están hablando...
Yo, como ya lei los otros mails, voy a ignorar estas cosas y
concentrarme en la parte tecnica de la charla =)
Espero no haberte ofendido con el otro mail, la intencion no era "mira
tonto, esto es asi" sino darte mi punto de vista en una discusion
tecnica.
> Los getters y setters son sumamente útiles por muchos motivos, los mas
> básicos son que AYUDAN a la legibilidad, ya que si yo pongo
> this.getAlgo().toString, claramente estoy haciendo referencia al atributo
> "algo" de mi objeto, en cambio si pongo algo.toString, uno a simple vista no
> sabe si ese "algo" es un atributo de la clase, es una variable local, me lo
> pasaron por parámetro es un método que devuelve _algo_ , etc.
Esto creo que pasa por el this, no por getters/setters. Y si, yo estoy
en contra del this implicito, pero creo que es otro tema independiente.
> En otro ejemplo, supongamos una clase A que contiene un atributo b que es
> una instancia de una clase B que a su vez tiene una colección de C. Es
> importante saber que algunos frameworks, al levantar una instancia de A no
> hidratan todos sus atributos (para no ocupar memoria ni tiempo buscando en
> la base cosas, que quizás nunca uses), y si no accedemos a estos por los
> getters, el framerowk no se entera que lo accedimos, nunca lo hidrata y nos
> va a decir que tenemos un null si hacemos a.b cuando en la base de datos si
> teníamos bs que tenían cs. Una vez mas, magia de aspectos.
Yo entiendo lo que vos decis, pero me parece que no se entendio del todo
bien a lo que Luca y yo estabamos haciendo referencia.
Creo que estamos todos de acuerdo que poder pasar por una funcion al
acceder a un atributo puede ser deseable, el tema es que el costo de
hacer eso en lenguajes como Java es alto dado que _siempre_ que queres
acceder al atributo tenes que pasar por una funcion (no hablo de
runtime, sino de costo en "complejidad de codigo").
En otros lenguajes, uno puede hacer _lo mismo_ pero con una sintaxis que
te evite tener la llamada explicita a la funcion, lo cual resulta en
menos "polucion" del codigo.
Vos en java tenes algo como esto (ignorando detalles de sintaxis y cosas
por el estilo que no son relevantes a la discusion):
class A {
private int b;
private bool lei_b;
void A() {
this.lei_b = False;
}
int get_b() {
if (!this.lei_b)
this.b = backend.leer_b_de_la_db();
return this.b;
}
}
Hasta aca no hay ningun misterio. Creo que todos estamos de acuerdo en
que es re deseable poder hacer esto, mas alla de las variaciones
sintacticas.
Ahora, TODAS las veces que quieras usar b tenes que poner obj.get_b(),
para TODO lo que haces.
Y como, claro, esto es deseable, vas a envolver todos los atributos de
esta manera aunque hoy no lo necesites para poder, en el futuro,
poder usarlo sin tener que convertir todo tu codigo de "obj.x = 1" a
"obj.set_x(1)". Entonces todos tus accesos a atributos van a ser del
tipo obj.get_x().
Creo que hasta aca no hice mas que decir lo que es practica comun de
Java, y estoy de acuerdo que en ese lenguaje no queda otra que hacer
esto.
Peeeeeeeero, en otros lenguajes vos podes tener lo lindo (poder hacer
que el acceso a un atributo pase por una funcion) SIN tener que
aguantarte lo feo (tener que poner obj.get_x() por todos lados en donde
queres acceder a x).
En Python la clase de arriba quedaria algo asi:
class A:
# Esta funcion es el constructor
def __init__(self):
self.lei_b = False
# None vendria a ser un objeto que cumple un rol en este
# caso similar al null de Java
self.valor_b = None
def get_b(self):
if not self.lei_b:
self.valor_b = backend.leer_b_de_la_db()
return self.valor_b
# Hasta aca esta todo igual a la de Java. Peeero aca viene el
# elemento diferenciador:
b = property(get_b)
Ese property hace que ahora vos puedas acceder a b de forma
transparente, o sea, haciendo directamente "obj.b", y que _igual_ pases
por la funcion. Solo que a vos, usuario del objeto, no te importa (lo
cual esta bien, porque no tiene que importarte que hace detras el
"getter/setter").
Esto, que quizas parezca una pavada, tiene para mi ramificaciones
importantes:
* No hace que todo el codigo este lleno de get_x() y set_x(), que lo
hacen mas incomodo de leer.
* Te brinda una interfaz mucho mas natural, familiar y amena para el
"getter/setter" ya que usas la que te dio el lenguaje:
"a = obj.y" e "obj.y = a".
* Te permite ser extensible sin costo alguno: si hoy tu atributo es
publico, podes simplemente dejar que accedan a el sin "getter/setter".
Si el dia de mañana resulta que queres ponerle un "getter/setter" lo
podes hacer tan solo modificando la clase y nadie se va a enterar. O
sea, lo mismo que vos en java logras poniendo getters/setters
incondicionalmente, pero sin el costo asociado.
O sea, a mi no me molesta la _idea_ detras del getter/setter (envolver
un acceso en una funcion), de hecho me parece obviamente algo bueno y
deseable. Lo que me parece un bajon (y que es una tara de java) es que
el costo de esto sea ensuciar todo tu codigo de llamadas a funciones
cuando se puede hacer de forma mucho mas clara y amistosa como se hace
en otros lenguajes.
Muchas gracias,
Alberto
_______________________________________________
Lista de correo Programacion.
[email protected]
http://listas.fi.uba.ar/mailman/listinfo/programacion