El desafío de la calculadora: resuelto

Un par de semanas atrás, compartía un ejercicio que utilizaba para evaluar habilidades de diseño OO en entrevistas de reclutamiento. Recibí algunos comentarios interesantes de diferentes personas. Hoy quiero compartir una respuesta. Como alguien señaló, este es un problema muy simple, pero aún así, no he podido encontrar nadie que solucionara el problema. Ni uno solo. En mi experiencia, el momento en que la entrevista fue en una dirección diferente a un ejercicio CRUD el desarrollador se perdia. Así que vamos a revisar el planteamiento del problema:

Diseñar un programa que dado una cadena como «(1+2)/3 * 4» devuelve el resultado correcto.

Encontrar las abstracciones

Así que tenemos un objeto que se evalúa una expresión y devuelve un valor numérico. Sencillo.


Sin embargo, tener un objeto que evalúa cada tipo de operación presente en la expresión es una violación del principio de responsabilidad individual. ¿La solución? Divide y vencerás. Vamos a crear un objeto para cada operación.


Ahora, lo único que debe hacer la calculadora es pasar la expresión a cada objeto operación. El valor devuelto de cada objeto de la operación debe ser la expresión con los valores resueltos para que puede pasarse al siguiente objeto de la operación. Para ampliar las capacidades de la calculadora todo lo que se necesita es añadir otro objeto operación. Esto se logra fácilmente utilizando una interfaz implementada por todos los objetos operación.


Centrándose en el qué, no cómo

Quiero llamar su atención sobre el hecho de que hasta ahora no hemos discutido cómo estos objetos van a evaluar las partes relevantes de la expresión. Aún no tenemos los tipos de datos en los mensajes (es expresión una cadena o un objeto?) Para mí esto es el sello distintivo de un desarrollador OO experimentado: la capacidad de concentrarse en el panorama global e ignorar los pequeños detalles hasta que se necesite. Esto se denomina abstracción. Tradicionalmente estamos capacitados para pensar de forma algorítmica, pensando en cada detalle. Toma algo de tiempo y esfuerzo para empezar a centrarse en el qué y posponer el cómo. Sin embargo de esta manera podemos utilizar otra técnica para el diseño de los objetos (los detalles de implementación) como TDD. En este caso, probablemente utilizaría una expresión regular para coincidir con el signo aritmético, extraer los valores, ejecutar la operación y reemplazar el valor en la expresión.

El próximo desafío

Por lo tanto, si alguna vez estuviste en una entrevista conmigo, esta es la respuesta que probablemente casi encontraste. De todos modos, tengo otro reto: ¿puedes identificar los patrones de diseño utilizados en esta solución? ¿Qué patrones usarias para mejorarla?