(continuación de Desafio de diseño: objetos inteligentes)
Hay varias formas de atacar este problema de la “testeabilidad”.
La primera opción que muchas veces viene a la mente, es hacer públicos los métodos privados y testearlos unitariamente. Si desde el punto de vista práctico esta opción puede parecer viable, cuando la miramos desde el punto de vista conceptual resulta incorrecta, pues dichos métodos son conceptualmente privados y no seria correcto cambiar su visibilidad para solo probar la clase. Si estuvieramos trabajando con C# Visual Studio nos ofrece una alternativa basada en reflexion para acceder a miembros privados de la clase, pero conceptualmente esto sigue siendo incorrecto.
Si pensamos el problema un poco más, nos daremos cuenta que puede que la clase tenga algunos problemillas de responsabilidades. Para ser más explícitos, tiene demasiadas responsabilidades: decidir si moverse y en caso positivo hacerlo, decidir si disparar y en caso positivo hacerlo, etc, etc. Bueno, si asumimos este diagnostico entonces hemos dado el primero paso: identificar el problema.
Repensemos la cuestión una vez más. Una clase que toma muchas decisiones (si X, si Y, si X, etc) y hace muchas cosas (X, Y, Z, etc). Cada una de esas cuetiones las hemos encapsulado en un método privado de cara a tener un código más legible. ¿y si fueramos un paso más allá? ¿Que tal si convertimos cada uno de ese métodos privados en una clase? De esta forma tenenemos una clase con la lógica de movimiento, otra clase con la lógica de disparo y asi sucesivamente. Así nuestro objeto inteligente tiene mucho menos código y su responsabilidad está limitada a coordinar “las estrategias” de movimiento, disparo, etc, etc. Al mismo tiempo cada estrategia puede ser testeada independientemente.
Bueno, este ha sido el primer desafio, próximamente vendrán algunos más.
Eso es lo que decía Adrián en la otra opción… Pero no puedo dejar de pensar… me suena parecido a hacer un objeto anémico… Como que todo lo delega en otros… terminás teniendo 2000 clases que hacen concretamente una cosa *útil*. Además que permitís que «terceros» hagan uso de las clases que usa tu objeto «importante» cosa que tampoco se si me copa mucho…
pd: ¿Hay una solución realmente? yo veo esto como un workaround.