Hola

Leyendo el mail inicial de Nahuel veo que hace referencia a un concepto, que 
sería el motivo que lo llevó al otro a prescindir de los setters: el 
concepto de inmutabilidad.

A mí me parece que si uno está definiendo el protocolo de un objeto 
inmutable ¿para qué ponerle setters? ¿para qué ofrecer un servicio que no se 
va a utilizar? ¿o mejor dicho, que se utiliza solamente en el momento de la 
creación del objeto, y que puede ser expresado mejor como inicialización de 
las variables de instancia que como el seteo individual de cada una de ella?

Supongamos que el Point de Smalltalk fuera tal objeto inmutable, y se 
hubiera definido así en Smalltalk, en ese caso bastaría con el protocolo 
#x:y: en Point class, y un método de inicialización como parte del protocolo 
privado de la instancia

Point class>>x: xCoord y: yCoord
    ^self basicNew initializeWithX: xCoord y: yCoord

Point>>initializeWithX: xCoord y: yCoord
    x := xCoord.
    y := yCoord

Point>>x
    ^x

Point>>y
    ^y

etc.

¿Y porqué meterse con conceptos como el de inmutabilidad?
Porque fundamentalmente un objeto inmutable tiene una existencia más simple, 
y no está expuesto al problema de la identidad.

El tema de la identidad y de la inmutabilidad creo que es un temón, muy 
intereseante, pero que excede al de la temática de los setters. Tuve la 
oportunidad de asistir a una clase magistral que dio Dan Rozenfarb en la 
materia de Diseño Avanzado con Objetos, y luego a otra que dio Hernán 
Wilkinson sobre la misma temática. Y una de las conclusiones fue que los 
objetos inmutables son objetos mucho más simples de utilizar, por lo tanto 
si queremos representar algo que es visto como inmutable, no perdamos la 
oportunidad de construirlo como inmutable en nuestro modelo.

Ejemplos típicos de objetos inmutables de en la "realidad" serían los 
objetos matemáticos, como es el caso de los números. Y como es el los pares 
ordenados que representan puntos en el espacio bidimensional. De ahí que 
cuando pregunté si no hubiera sido mejor que el Point de Smalltalk fuera 
inmutable, Hernán respondió que sí, que no hay ningún motivo para que Point 
sea mutable , y que hubiera sido un mejor diseño en Smalltalk un Point 
inmutable.

Un punto representa un punto en el espacio. Y si queremos tener otro punto 
en el espacio podemos construir otro punto, y punto. A mi entender el Point 
de Smalltalk más que punto es un puntero. Uno puede utilizarlo como punto 
mediante la disciplina de no enviar los mensajes de setting, pero ¿para qué 
cargarse con reglas disciplinarias cuando en Smalltalk es tan fácil 
construir la representación del concepto deseado y luego utilizar los 
objetos que lo instancian con toda libertad, como al boleo?

Saludos
Juan

----- Original Message ----- 
From: "Andres Valloud" <[email protected]>
To: <[email protected]>
Sent: Tuesday, June 02, 2009 6:17 PM
Subject: [clubSmalltalk] Re: setters y getters



El problema, basicamente, es que no hay un solo punto de vista con
respecto a los accessors cuando se considera la encapsulacion.  Lo que
entendemos por encapsulacion cambia segun nuestras intenciones, porque
lo que queremos es lo que dibuja los bordes que despues nos permiten
decir que algo esta encapsulado.

Estan aquellos que dicen "las variables x, y, z son detalles internos
de implementacion de TalClase, y por lo tanto no tiene que haber
accessors [getters/setters] porque si no otros objetos podran
manipular detalles internos, violando la encapsulacion".

Desde el punto de vista del proposito de los objetos considerados
individualmente, quiza haya algo de sentido en ese argumento.  Pero
los que lidiamos con las consecuencias somos nosotros, y ademas
nosotros tenemos un punto de vista mas abarcador.  Tambien usamos
puntos de vista meta, que estan mas alla del proposito individual de
cada objeto.  Hay propositos perfectamente validos, como por ejemplo
encontrar todas las instancias de TalClase tales que sus variables de
instancia estan rotas.  Tipica expresion de debugger:

TalClase allInstances select: [:any | any z esCualquiera]

Sin accessors, esto es imposible.  Las alternativas son por demas
molestas... seguro, siempre es posible usar instVarAt:, pero por que
la necesidad de ser tan bruto (en el sentido de la fuerza bruta)?  Y
si instVarAt: existe, porque preocuparse de los accessors y la
encapsulacion?  Hay que redefinir instVarAt: como shouldNotImplement,
acaso?  Entonces, desde nuestro punto de vista, la encapsulacion no
existe necesariamente siempre en el mismo lugar, porque en presencia
de instVarAt: e instVarAt:put: vale cualquier cosa.  Lo que si es
interesante es que nosotros decimos eso porque sabemos como esta
implementado instVarAt:.  Los objetos no saben, necesariamente.  Creo
que aca es donde se arma la galleta: la confusion entre nuestro punto
de vista, y el punto de vista mas estrecho de cada objeto.

A mi gusto, los que programamos somos nosotros.  Entonces, por nuestro
propio beneficio, tiene que haber accessors para todas las variables
de instancia.  Esto hace mas facil debuggear objetos rotos.  Ademas,
facilita browsear codigo porque las referencias a las variables de
instancia no pasan de 2 metodos (en algunos casos de lazy
initialization se puede hacer "bien" con un metodo, pero entonces no
hay setters y a veces molesta porque no hay z: para arreglar las
instancias de TalClase donde z esCualquiera).  Incluso facilita
encontrar errores porque si interesa enterarse de cuando una variable
de instancia cambia a un valor critico, la presencia del setter hace
que solo haya que poner UN breakpoint.  Cambiar la estructura interna
de los objetos con accessors es trivial, ya que desde el punto de
vista de los objetos la implementacion de los mensajes SI esta
encapsulada.

Pero que hacer con los objetos que mandan setters que no deberian
mandar, no?  Para esto, lo que me parece mejor es poner los setters
que son privados en un protocolo llamado "private - accessing" o algo
parecido, y no usarlos donde no corresponde.  Una buena revision de
codigo siempre elimina cualquier caso en el que se te escape un
mensaje inapropiado.

Cada tanto escucho excusas del estilo "ahh, pero como te aseguras
nadie va a mandarse una guarangada?".  A mi gusto, la mejor solucion
es que aquellos que sientan que saben algo valioso lo compartan y lo
enseñen.  O sea, en vez de prohibir accessors y privarnos de sus
beneficios, programemos mejor.  Ademas, nada impide escribir un test
que verifique que aquellos mensajes en protocols llamados 'private*'
no se mandan desde cualquier lugar.

Para sintetizar entonces... accessors para todas las variables de
instancia porque hacen mas facil programar, browsear, debuggear, y
cambiar la estructura de los objetos minimizando los cambios
secundarios indeseados.  Los que sean privados, favor de ponerlos en
un protocolo que se llame 'private*', y no mandarlos de maneras
irresponsables desde un punto de vista concreto como el que tienen los
objetos individuales.

Andres.


2009/6/2 Nahuel Silva <[email protected]>:
> Hola gente.
>
> Les cuento, en el trabajo discutiendo con mi compañero sobre accesors no
> logramos llegar a un acuerto.
> Mis críticas son que en la mitad de sus clases no estan definidos los
> accesors (tanto setters como gettters) y me resulta no solo bastante
> engorroso debugguear el código, ya que de repente aparece una variable,
> variableA y no sabés de donde carajo sale, sino que yo entiendo que
> programar en smalltalk sin accesors (setters) está mal y el considera que
> no, argumentando historietas sobre objetos inmutables y otras yerbas, que 
> no
> quita que sa ea correcto.
>
> Que me pueden decir ustedes, que consideraciones puedo tener a la hora de
> determinar cuando usar accesors, cuándo definirlos, que criterio tengo en
> cuenta ?. Ésto es una pavada (tal vez), pero quiero más opiniones.
>
> Abrazo
>
> Nahuel
>
> >
>



--~--~---------~--~----~------------~-------~--~----~

To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]

http://www.clubSmalltalk.org
-~----------~----~----~----~------~----~------~--~---

Responder a