viernes, 20 de febrero de 2009

Qi4j and state modeling

Un amigo me pasó este link sobre algo que están haciendo en Java: http://www.jroller.com/rickard/entry/qi4j_and_state_modeling
Es interesante, pero es algo que nuevamente refleja las complicaciones que tienen en Java para poder hacer cosas sencillas. 
Primero: el problema que tienen por usar POJOs (Plain Java Objects, lo que comúnmente hacemos en Smalltalk) puesto que lo escrito es muy distinto a lo que se "habla" en el dominio. Me alegro de escuchar ese argumento!, quiere decir que la gente está empezando a apreciar lo que venimos diciendo por años y es la importancia de hablar "el mismo idioma" con el experto del dominio, el problema es que no se dan cuenta que el "problema" está en la sintaxis y diseño de Java y que hay otros lenguajes, como Smalltalk, donde eso no sucede. O sea, el problema no está en usar Plain Objects, el problema esta en usar Plain Objects con la sintaxis de Java. Justamente debido a la sintaxis de Smalltalk es que a nadie se le ocurriría hacer algo como lo que está haciendo esta gente. 
Segundo: Habla de que quieren tener un lenguaje similar al del dominio del problema, pero sin embargo usar un keyword que seguro nadie del dominio entiende como @UseDefault. ¿Qué significa eso para un experto del dominio?, seguro nada
Tercero: Me vuelven loco los ejemplo pelotudos de uso de interface como este en donde extrae la propiedades de ser "nombrable" y crea la interface "Nameable". Y perdón por la palabra pelotudo, pero la verdad este tipo de ejemplos lo único que hacen es complicarle la vida al que aún está aprendiendo. Uno de los motivos es porque esto sucede al final de un desarrollo, no mientras se está desarrollado y entendiendo el dominio. De este ejemplo se puede sacar la conclusión de que cualquier cosa que tenga sentido se puede poner en una interface por que si, sin analizar que hacerlo puede agregar complejidad al diseño! ¿qué otra cosa que no sea un ser humano puede tener nombre y apellido? Nada! Entonce, ¿para que factorizarlo así?. Por otro lado, el motivo por el cual dice que es bueno hacerlo es porque ahora podrán preguntar si "x instanceOf Nameable"... parece que de polimorfismo poco esta persona. Justamente preguntar por el tipo de un objeto es el claro ejemplo de que aún están pensado en "estructurado" y no en objetos. No más palabras sobre esto porque me está subiendo la temperatura
Tercero: Dice que cuando modelan le gusta hablar de propiedades, relaciones, etc., pero en ningún momento veo que hable de comportamiento! lo más importante! Si solo le interesa propiedades y relaciones, ¿por qué no hace un DER?. Nuevamente, un ejemplo de que no lograron entender el paradigma de objetos y están usando técnicas de otros paradigmas. 
Cuarto: No entiendo por qué separan Entity de Value. Es algo que ya lo vi varias veces y el motivo es que los Values son inmutables, las entities no. Nunca escuche esta separación en filosofía ni en epistemología ni en nada similar, solo en nuestra profesión y por lo tanto me parece que es un problema del dominio computable... si es así, ¿por qué confundirlo a experto del dominio con esto?.
Quinto: El ejemplo del método listName() en la sección Privitanzing State me mató! jaja. Más me mató la frase siguiente: "Heat huh?". ¿Neat?, yo diría "a mess man!" a mess que rompe el encapsulamiento y que para perdir un nombre tengo que envier el mensaje "name()" y luego "get()"! o sea, primero tengo algo que no es lo que quiero (seguramente será un Value o Entity) y luego le pido su "valor" que es lo que realmente quiero... ¿no debería ser al revés en todo caso para que sea más simple?... en fin.

Algo que me gusto, es que como vine escribiendo últimamente, evitan usar nil (o null en java). Parece que esta idea está empezando a tomar forma simultáneamente en otras comunidades lo cual es bueno. Otra cosa interesante es que reifican las relaciones (algo esperable también por la orientación al paradigma relacional que tienen), algo que también veo como importante pero que lamentablemente nunca tuve la oportunidad de probarlo seriamente.
Conclusión, que lástima ver el tiempo que se pierde en tratar de resolver problemas no esenciales (reinventar la rueda pinchada como dice Alan Kay) creados a partir de decisiones de diseño incorrectas (en este caso decisiones del diseño del lenguaje Java).

4 comentarios:

Diego dijo...

Acabo de ver el sitio y la verdad es que no entendi bien el "valor" de lo que estan haciendo.

No se por que distinguen POJOs de otros objetos, en si la palabra POJO se empezo a usar en J2EE para distinguir entre objetos que dependen del framework: subclases de Servlet, EJB, etc, y objetos "simples" que no dependen de nada.

En otros frameworks se usa el mismo termino para hablar de objetos que heredan de una clase del framework y los que no (por ejemplo en Spring, Hibernate, etc usan la palabra en ese sentido).

Hoy en dia mucha gente en Java esta acostumbrada a usar la nomenclatura de set/get (cosa que no es necesaria es solo una restriccion cultural, escribi un poco de eso en mi blog ;). Y cuando hablan de POJO se refieren a objetos mutables con setters y getters (creo que a eso se refiere con POJO el articulo).

En fin los problemas que mencionan se pueden eliminar no usando el prefijo set/get, teniendo objetos inmutables y construyendolos bien el constructor.

Me parece que la complejidad del ejemplo lo dice todo. Por ejemplo no termino de entender la intencion del los Mixins en el ejemplo, un comentario del autor (accerca de un ejemplo mas complejo de mixins) dice:
This makes it possible for the assembler, or deployer, of the application to make overrides if necessary.

El rol de "assembler" o "deployer" hecho por una persona ajena al desarrollo es ficticio, en los laburos que hice con j2ee nunca vi a nadie que configure un XML de j2ee o Spring sin conocer el desarrollo: los administradores lo ven como algo complejo y se lo delegan siempre a los desarrolladores.

Me parece que la gente de Ruby con los DSL esta teniendo una actitud mas pragmatica y directa al problema.

Hernan Wilkinson dijo...

Que haces Diego! no sabía que tenías un blog! ya me suscribí!
Gracias por el comentario.

Rickard dijo...

@Hernan,
Just a few clarifications on what I wrote. First of all, the notion of "Entity" and "Value" are well-defined, so if you haven't heard about it, then I suggest you look it up. Second, the article *is* about state modeling, hence the lack of behaviour.
The @UseDefaults annotation may not have any meaning to a domain expert, but it's not the domain expert reading the code: it's a developer trying to express the domain, and for a developer it certainly will have a meaning.
@Diego,
The deployer may perhaps not develop extensions themselves, but they might definitely have a choice between multiple implementations, provided by developers, of which they choose one. This is less important for consultant gigs, and more relevant for packaged products where you have multiple customers, so it might depend on your background whether you have seen it or not. The "assembler" of an application, however, is probably going to be a developer, but we differentiate between the developer creating the composites and the developer creating the application. One of the goals is to allow applications to be assembled from pre-existing components, and the notion of overrides is therefore essential as a component may fit some but not all of your needs.

Hernan Wilkinson dijo...

Hi Richard,
thanks for your comment.
I know about the notion of Entities and Values used in Computer Science and Engineering, but I do not agree with it. From an object (and behavior) point of view, it is an unnecessary distinction that adds complexity to the language.
I did not know that your post was about state modeling only. For me programing is about behavior, is about objects talking to each other. State is just an implementation detail. So when I see things that only concentrate on state I think they are loosing the most important part. Of course, not everybody has to agree...