jueves, 19 de julio de 2007

Paso IV: ¿Conoce usted qué significa desarrollar con Objetos?

Debemos resolver ahora el algoritmo de cálculo del costo. Tenemos una sola clase, Llamada, para “codificar” ese algoritmo, pero al hacerlo ¡la llamada tendrá que determinar si es local, nacional o internacional!, ¡estamos más o menos en lo mismo! Humm, ¿será momento de empezar a cuestionarnos todo lo que creemos y buscar alternativas distintas?, ¿será el momento de utilizar el pensamiento lateral?

Si haber hecho este cambio de diseño no mejoró el cálculo del costo, puede significar que: 1) el cambio no es bueno 2) el cambio es correcto pero no hay una mejor manera de calcularlo o 3) no es correcto asignarle la responsabilidad de calcular el costo a la llamada.

De las tres opciones, la más revolucionaria es la 3, y es justamente la correcta. Usted dirá “¿cómo es posible que una llamada no sepa responder su costo?, ¿para qué existe entonces?, ¿quién se encarga de calcularlo?”. La realidad es que una llamada no tiene por qué saber responder su costo.

Pensemos por un momento que podemos hablar con una llamada, que le podemos hacer preguntas y que ella nos responde, ¿qué pasaría si le preguntaría su costo?, ¿qué respondería? La verdad es que no respondería nada porque ¡ella sola no puede saberlo! Para determinar el costo tiene que conocer la tabla de costos, que tipo de llamada es, etc., y nada de esto es esencial a una llamada. Una llamada es un ente que nos podrá responder el número de teléfono origen y destino, la hora en que se realizó, cuanto duró, pero no mucho más.

Un ejemplo que ayuda a entender este concepto es el siguiente: supongamos que estamos en una casa de alquiler de videos y necesitamos saber cuanto cuesta alquilar uno de ellos, ¿cómo resolvemos este problema?, ¿le preguntamos al video cuanto cuesta? Indudablemente no, si lo hiciéramos las personas de alrededor dudarían de nuestra cordura, y con razón. Lo que haríamos sería preguntarle a la persona que atiende la tienda el costo del mismo y él seguramente utilizaría una lista de precios (o se acordaría de ella, que en definitiva es usarla) para respondernos. Lo mismo sucede con la llamada, el problema es análogo y por lo tanto, también la solución. Una llamada nunca podrá responder cuál es su costo, para eso están otros objetos que luego analizaremos, aunque imagino que los irán intuyendo.

Si aún no los convencí con estos argumentos, les doy otro motivo por el cual no es correcto tener tres clases por cada tipo de llamada. Hacerlo implica que al momento de crear la llamada, alguien tiene que decidir de qué clase es. Esto implica que una vez decidida su clase, la llamada no puede cambiar de categoría puesto que un objeto no puede cambiar de clase (esto no es completamente verdad, pero hacerlo implicaría trabajar a un meta nivel distinto). Sin embargo pueden existir momentos donde no se sepa el tipo de una llamada o que una llamada haya sido mal tipificada.

Este error es muy difícil de verlo, más aún porque estamos acostumbrados a escribir código de prueba de la siguiente manera:


llamada1 = new LlamadaLocal (…);
llamada2 = new LlamadaNacional (…);
llamada3 = new LlamadaInternacional (…);
//etc

Es difícil de verlo porque sucede que en este caso es usted, el programador, quien está decidiendo el tipo de la llamada, a que clase pertenece, y el problema es justamente que usted lo decida. En este paradigma los objetos deben decidir qué hacer, no usted el programador. Y esta regla vale realmente para cualquier paradigma de programación que utilice. Uno de los objetivos que tenemos que buscar como programadores, es que la computadora haga más cosas y nosotros, los seres humanos, menos, simplemente porque la computadora “no se equivoca”. Por lo tanto, tenemos que lograr que sean los mismos objetos los que decidan que tipo de llamada es una llamada.

Utilizando el ejemplo de los videos se entiende mejor. Un video podría ser un estreno o un clásico. Esto se determina a partir de que tan nuevo o viejo es, por lo tanto el costo de alquilar uno u otro depende de una característica temporal. Si para resolver esta categorización se crearan las clases “VideoDeEstreno” y “VideoClasico”, no se podría cambiar la categoría de un video, de estreno a clásico por ejemplo, puesto que se debería cambiar la clase del video. Más simple es tener un conjunto de videos de estreno y otro conjunto con videos clásicos y por lo tanto el cambio de categoría de un video es simplemente sacarlo de un conjunto y agregarlo en otro.

Repasemos. De las cuatro clases que teníamos en la solución original para representar las llamadas, bajamos a una y le sacamos la responsabilidad de calcular el costo. Ahora tenemos que decidir a quién se la damos. Este es uno de los puntos que más me gusta de este problema, porque la solución no está “a la vista”.

Ya se hizo muy largo este post... mañana seguiré

No hay comentarios.: