Además, como ya puse en otros posts, no hay que perder de vista que los objetos representarán la esencia de dichos entes mediante su comportamiento, no estructura, relaciones, etc.
Sin embargo hay otro punto del que siempre hablamos y es la identidad. La identidad es la que permite identificar únivocamente un ente. Todo ente posee una identidad y por lo tanto el objeto que lo representa en nuestro modelo también debe tener una. Sin embargo hay una gran confusión entre lo que es identidad, lo que algunos llaman "estado de un objeto" y lo que es la identidad del objeto. Voy a empezar por este último.
Un objeto, por ser a la vez un ente de la realidad (además de estar representado otro) también posee una identidad. Esa identidad en un ambiente de objetos está generalmente implementada por medio de la posición de memoria que ocupa el objeto. Es lo que hace que ese objeto sea único, no puede haber otro objeto en la misma zona de memoria que otro.
En Smalltalk, se puede saber si dos objetos ocupan la misma zona de memoria usando el mensaje #== Este mensaje tiene por propósito verificar si dos "objetos" son identicos, o sea, si ocupan la misma zona de memoria pero no puede decir nada sobre la identidad del ente que representan dicho objetos. En rigor de verdad, si dos objetos son idénticos significa que están representando al mismo ente y por lo tanto representan la misma identidad del ente, pero si dos objetos no son identicos no se puede asegurar que estén representando a entes no idénticos. Es acá donde se ve claramente la diferencia entre identidad de objeto e identidad de ente. Un ejemplo lo va a aclarar.
En Smalltalk existe la clase Date, pero si evalúo dos veces la siguiente colaboración "Date today" obtengo dos objetos que no son idénticos pero que sí representan al mismo ente, el día de hoy. Por lo tanto no hay que confundir identidad de objeto que viene dado por el ambiente de objetos de identidad del ente que la tenemos que definir nosotros en nuestro modelo.
¿Cómo representamos la identidad del ente? Dependerá del ente que estemos modelando o la implementación que utilicemos. Por ejemplo, los SmallInteger en Smalltlk nos dan la sensación de ser únicos (o sea, de que hay uno y solo un objeto por cada uno de ellos). A nivel implementativo sabemos que no es así, pero es un claro ejemplo donde la identidad del ente esta asociada a la identidad del objeto. Otro ejemplo son los objetos instancia de Symbol, no puede haber más de un objeto para el mismo símbolo que representan de la realidad. Como vismo, no sucede así con las fechas y con otros objetos como aquellos instancias de Time, Point, etc.
¿Qué es lo que representa entonces la identidad de los entes para estos objetos? Siempre es un conjunto de colaboradores internos (variables de instancia) que cumplen ese propósito. En el caso de Date, dependiendo de la implementación serán el número de día, mes y año. En el caso de Point serán esos objetos que representan la coordenada x e y.
Una característica interesante que tenemos que cumplir con estos colaboradores que representan la identidad de los objetos es que no pueden cambiar, puesto que si lo hacen el mismo objeto estaría en un instante de tiempo representando un ente y luego otro, sería un objeto con "problema de personalidad" no les parece?. Es por ello que es fundamental entender bien qué colaboradores internos representan la identidad de un objeto puesto que ellos no pueden cambiar. Hay otras implicancias interesantes de este hecho, la primera es que el mensaje #= del objeto devolverá true si los colaboradores internos que representan la identidad del ente son iguales. Esto significa que si queremos saber si dos objetos representan el mismo ente, debemos usar el mensaje #=, es este mensaje el que nos dirá si dos objetos representan a un ente idéntico o en otras palabras, a exactamente el mismo ente. Moraleja, no confundir identidad de objeto de identidad de ente y por lo tanto nunca, pero nunca usar el mensaje #== en un modelo a menos que ese modelo esté tratando con un dominio de problema computacional y donde realmente se tenga por intención saber si se está tratando a exactamente "el mismo objeto" sin importar si además si representan exactamente el mismo ente.
Esto que estoy comentando les debería disparar una nueva explicación de porque el hash debe estar relacionado con el #= y por qué cuando un objeto cambia los colaboradores que representan la identidad cambia su hash que termina produciendo un descalabro importante en aquellos objetos que dependen de la invariabilidad de esta característica.
También esto tiene que empezar a dispararnos la idea de que hay colaboradores internos que representan la identidad del ente que modela el objeto y otros que no. ¿qué características pueden tener estos otros? ¿pueden cambiar? ¿que representan?. Son muchas preguntas, no tengo una respuesta 100% segura, pero en la mayoría de los casos me parece que dichos colaboradores existirán por motivos implementativos como por ejemplo tener un cache, poder acceder más rápido a un objeto, etc. y no a cuestiones esenciales del dominio de problema en si, pero no lo puedo asegurar.
Otra pregunta interesante para hacerse es, ¿debería el lenguaje ofrecerme herramienta particulares para hacer uso de esta diferencia? Por ejemplo, que defina una clase de esta manera:
Object subclass: #Point
identityDefinedBy: 'x y'
instanceVariableNames: ''
... etc.
Al hacerlo, automáticamente el ambiente podría asegurar que la identidad no puede cambiar, y algo más interesante aún que la misma se defina en el momento de crear el objeto, algo que veremos en el próximo tip.... mientras tanto tiro la idea, yo aún no tengo un posición tomada.