Lo admito, es el primer paso, había olvidado por completo lo que significa la programación orientada a objetos. Soy uno de esos que, como bien me dijo @jacegu, cree que los POJOs son simples contenedores de datos con getters/setters. Es posible que cosas como Hibernate me hayan hecho mucho daño pero lo peor es que yo me he dejado "cautivar". Un síntoma bastante habitual para detectar esto es mirar si cada vez que creas una clase con sus atributos generas sus métodos accesores (getters) y mutadores (setters). Por lo menos "mutadores" es un buen nombre teniendo en cuenta que los atributos "cambian de estado".
¿Qué me ha hecho darme cuenta de esto? Pues como con casi todo la cosa más simple como una conversación en twitter:
No solo @ialcazar me contestó algo, sino también @jmbeas y @jacegu (os recomiendo su blog que descubrí con este artículo sobre la misma discusión). A partir de sus respuestas y enlaces que me enviaron he abierto los ojos con este tema. Realmente daría para un post muy largo (quizás igualmente interesante) si me pongo a escribir lo que he ido descubriendo pero creo útil poner los enlaces que me han servido para darme cuenta de mi error de "conceptos".
A mi me sonaba lo del "modelo anémico", en algún sitio lo había leído, ¿pero donde? y peor aún, ¿realmente que era eso?... Bien, todo mi proceso de estudio hacia la verdad empezó aquí, en este hilo empezado por @jmbeas sobre, precisamente, este tema. Y ahí estaba, entre las primeras líneas, el sitio donde ya había leído antes eso del "modelo anémico", en los artículos de Fowler (no tengo perdón de Dios).
Resulta que nuestro amigo el "modelo anémico" es un señor anti-patrón que viene a ser un conjunto de objetos, nuestro dominio de la aplicación, con poco más que atributos y sus getters/setters. Sin más lógica. Anémicos, no ricos (en lógica). Esto al final los convierte en simples estructuras de datos, ya que, declarar atributos como privados y luego, consecutivamente, implementar sus métodos de acceso es romper automáticamente el paradigma OO y su principio de la encapsulación. Toma moreno!
A través de esto he (re)descubierto el libro de Domain Driven Development de Eric Evans, el cuál, como tantos otros, está en la lista de Amazon, esperando a la primera compra del año que viene. Lo siguiente es extraído del artículo de Fowler que a su vez lo sacó del libro de Eric (vaya esto parece romper la Ley de Demeter xD):
Application Layer [his name for Service Layer]: Defines the jobs the software is supposed to do and directs the expressive domain objects to work out problems. The tasks this layer is responsible for are meaningful to the business or necessary for interaction with the application layers of other systems. This layer is kept thin. It does not contain business rules or knowledge, but only coordinates tasks and delegates work to collaborations of domain objects in the next layer down. It does not have state reflecting the business situation, but it can have state that reflects the progress of a task for the user or the program.
Domain Layer (or Model Layer): Responsible for representing concepts of the business, information about the business situation, and business rules. State that reflects the business situation is controlled and used here, even though the technical details of storing it are delegated to the infrastructure. This layer is the heart of business software.
Además Fowler habla de la definición, a partir de todo esto, de los POJOs (Plain Old Java Objects) que vienen a ser las antiguas clases que seguían los principios de OO manteniendo, en cada clase, estados y la lógica que interactua con ellos. Con estos métodos "tell, don't ask" :)
Aparte de esta colección de enlaces que estoy repartiendo por el post está el capítulo 6 de Clean Code sobre Objetos y Estructura de Datos y alguno de Pragmatic Programmer. Son los dos primeros libros que, de no tener, ahora mismo compraría y, por mi (poca) experiencia los proporcionaba como material de lectura obligada en la universidad (quizás pueda hacer algo para eso, ya os contaré... :D).
Todos sabemos que el ecosistema de tecnologías, técnicas, paradigmas, etc, en la informática es muy grande. No podemos controlar todo pero creo debemos tener claro los conceptos base para saber si un camino está bien trazado o va por zonas de arenas movedizas. La programación OO nació con esa motivación y, en muchas ocasiones, nos hemos olvidado ante la tentación de las cosas sencillas. Soy el primero que encadena llamadas entre objetos colaboradores pero a partir de ya pondré de mi parte para erradicar esto.
Quedo pendiente para otro artículo como seguir afrontando el proyecto que estaba desarrollando en Grails aplicando estos conceptos. Al final el modelo de datos que tengo, realmente, son DTOs o, más bien, Active Records. Es decir, estructuras de datos.
PD: Un último enlace que acabo de descubrir en el blog de @jacegu sobre el Anemic Domain Model ya que le tiene "especial cariño" :D
PDPD: El artículo que ha escrito @ecomba que está relacionado con este tema. Como bien propone él no hay que usar, obligatoriamente, las "bondades" de estructuras como los Active Records, sino que también podemos modelar nuestra lógica, siempre.

Genial esta entrada Kini, la verdad es que te hace pensar, porque reviso todos nuestros proyectos y no veas lo anémico que se queda nuestro modelo :-S aunque se intenta ir solucionando poco a poco. Siempre es necesario volver la vista hacia atrás y volver a (re)descubrir lo que ya sabíamos porque a veces se nos olvida, o por lo menos a mi que tengo memoria de pez :-)
Con respecto a esa frase en la que recomiendas Clean Code y The Pragmatic Programmer como lecturas obligatorias en la Universidad me hace gracia, porque lo mismo le comentaba a un compañero hace unas semanas :-D Quizás Domain-Driven Design ya es un poco fuerte para gente que no haya empezado a trabajar en el mundo real, pero una muy buena compra por tu parte.
Un saludo.
Me uno a las felicitaciones. A veri si la gente se conciencia y se da cuenta de que con un modelo anémico no hay orientación al objeto.
Gracias por los enlaces al blog. Voy a añadir una sección de enlaces en el Anemic Wall y añadir este artículo.
Un saludo.
Genial Kini. No sabía que mi tuit había sido el detonante de todo esto.
Se me ha hecho corto el post, justo cuando empezaba a ponerse la cosa interesante se ha acabado :-(. Habrá segunda parte? Quizás algo de código?
Sigue así, cada granito ayuda.
Un abrazo
Gracias a todos por las felicitaciones y pasar por aquí, no tiene que ser fácil leerme hasta el final! xD
@Yeray: Es cierto que si echamos la vista para atrás nos damos cuenta de como hemos "metido la pata" pero también de todo lo que hemos aprendido en este tiempo ya que somos capaces de detectarlo. Siempre que se pueda (re)diseñar y refactorizar! Sobre los libros en la universidad, mandé un correo a un profesor y es posible que en Febrero vaya a dar un seminario o algo así sobre "buena programación" ;)
@Jacegu: Eres uno de los culpables y animadores de este post, me alegro! Esta claro que esta práctica no lleva a OO
@ialcazar: Pues sí, tu tuit fue el primero en hacerme pensar esta movida :) Es cierto que puede quedarse corto, como digo en el post, pero hablar de esto lleva para mucho y creo hay gente que ya lo ha hecho bastante bien. En cualquier caso quiero aplicar estas cosas a un proyecto con Grails (típico caso de ActiveRecord y POJOs) y modelar las clases ricas. Ya contaré algo! :)
Gracias de verás!
Pues yo no conocía lo del modelo anémico, pero me parece bastante interesante. Creo que a veces metemos demasiada lógica en los nuestros pojos, y aunque al principio es poca y es de fácil acceso, cuando crece, perdemos mucha cohesión en el código. Casi prefiero crear servicios (como si fueran los "antigos" DAOs) que reciben como parámetro un pogo, y con los que operar. Puedo crear tantos servicios como quiera en función de una lógica común siguiendo una división vertical. Por ejemplo, puede crear un servicio para renderizar json o xml, y que solo se encargue de hacer eso para todos los objetos de dominio. Esto sería preferible a tener un método para renderizar json en cada objeto de dominio... creo, porque en nuestro caso, lo metemos todo en el pogo... Solo espero que continúes el post y que nos digas cual es la mejor opción, pros y contras: si pogos vitaminados o famélicos y anémicos!! Un abrazo :)
Las cosas no son blancas o negras y menos en la informatica. Los patrones se convierten en antipatrones o viceversa segun el contexto en el que construyes tu software. Partiendo de ahi esta bien subrayar otras formas alternativas de hacer las cosas, sobre todo cuando la forma mas extendida se aplica por defecto y sin plantearse las razones ni si se ajusta a tu dominio, como pasa con el modelo "anemico" o usar estructuras de datos sin codigo asociado.
Sin embargo a veces usar estructuras de datos "anemicas" o simples tiene sus ventajas como en el ejemplo que ponia Alberto, sin modificarlas puedes extender, modificar, añadir o componer los algoritmos o metodos que actuan sobre ellas.
El dejarlas desnudas e ignorantes del mundo exterior salvo por el contenido semantico (los nombres de los campos y de la propia clase) puede convertirlas en piezas facilmente tratables por el codigo exterior y usadas en contextos muy diferentes. Eso no quiere decir perder el encapsulamiento totalmente porque siempre puedes encapsular por capas en lugar de por clases individuales.
Me ha gustado la referencia al "tell dont ask" de alan kay y smalltalk como una fora de mitigar la imperatividad de la oop. Sin embargo el dar mas importancia a los verbos que a los nombres no tiene porque ser mas imperativo, siguiendo el ejemplo de alberto "render (data,format)" que "data.render (format)".
Enhorabuena Kini, pedazo artículo.
Buen debate, en mis 6 años de experiencia laboral voy encontrándome diferentes conceptos de entender la Programación Orientada a Objetos. A mi me recuerda que, como la Real Academia de la Lengua Española, si no hay un organismo oficial o de facto que se dedica a poner ciertas reglas, las cosas al final distorsionan mucho de la idea inicial.
Y es lógico, aquí entra el pragmatismo diario (entregas a toda leche que implican olvidarse de metodologías, diferentes maneras de ver el mismo problema, el jefe que no quiere que le "rayes" con nuevos conceptos, etc).
Saludos y gracias!
A mi me ha gustado tu exposición de un modelo anémico, está bien, pero no creo que tenga que ver con la OO o no. Si no mas bien en saber como enfocar los diferentes problemas.
Ya que no es lo mismo usar un framework ligero como puede ser spring o grails ante un framework pesado como son los ejbs (cada día mas ligeros en forma y desarrollo pero respetando su paradigma por capas). Precisamente el ejemplo claro, que tu pones de hibernate me gusta especialmente, ya que hibernate(copiado, estandarizado a través de JPA) se creo para hacer "desaparecer" la capa DAO, no la capa de negocio y es perfectamente usable con los ejbs.
Y es que no es lo mismo, los objetos de negocio que la lógica de negocio: modelo anémico contra servicios y/o ejbs, bi, procedimientos almacenados... (aquí podríamos tirarnos a discutir las diferencias y desde cuando se ha hace realmente SOA en java). Y es que hay una cosa muy clara, la tendencia a simplicar las capas a veces hace que caigamos en antipatrones o malos diseños.
Un ejemplo claro de mal diseño sería añadir lógica de negocio en un controlador de la vista, pero los frameworks ligeros no nos dejan ver tan claramente donde hemos de ponerlo o como hemos de usarlos.
Pero lo que está claro, que un modelo anémico a día de hoy tiene lógica y decir que hacer eso no es hacer OO no está tan claro.
Como colofón, a mi, el modelo anémico me gusta llamarlo BOM (business object model) Es decir, modelamos el negocio en objetos que pueden usarse para DTOs y para ActiveRecords. Mientras que no tienen porque ser validos como DomainObjects (sobre todo pensando en SOA) ya que puedes exponer al exterior cosas no totalmente necesarias fuera de la aplicación/es internas.
Hola Kini, te me has adelantado, pensaba escribir un post sobre esto pero has sido más rápido. Esto del modelo anémico es una auténtica epidemia.
Por si te sirve de consuelo yo no he visto nunca una aplicación empresarial con un modelo OO, todos eran modelos anémicos, ¿por qué? Pues porque el modelo de negocio no estaba en JAVA, sino en tablas de BBDD y procedimientos almacenados o servicios COBOL. Pensando en que el negocio está en el back-end y no en el servidor de aplicaciones OO, empezaron a surgir frameworks, cuyos nombres no quiero mencionar, que únicamente facilitan la propagación de la epidemia de los modelos anémicos.
¿Cuántas veces al pedir el modelo de dominio en un cliente te han dado un esquema de base de datos? ¿Qué es lo que te dan cuando pides el funcional y el diseño técnico? Las tablas y las maquetas de las pantallas y santas pascuas.
Cuando empezaste a hacer el modelo anémico simplemente has hecho lo que el 90% de los desarrolladores, tirar de las tablas, y usar las "best practices" de los frameworks más de moda. Por lo menos tu te has dado cuenta de que no es la mejor manera de hacer las cosas.
Salud y continua con tus posts !
Si tu aplicación es un CRUD, usar un modelo anémico es una buena opción, pero propagar el modelo de datos hasta más allá del DAO en el resto de problemas me parece que tiene más que ver con no querer hacer el trabajo por el que nos pagan: programar. Claro que requiere un esfuerzo el elegir bien los nombres de las clases, sus responsabilidades, etc... pero es que programar va justamente de eso.