Mucho se ha dicho acerca de la importancia y desafíos al diseñar una buena API. Es difícil hacerlo bien la primera vez y es incluso más difícil cambiarlo después. Algo así como la crianza de niños. La mayoría de los programadores experimentados han aprendido que una buena API sigue un nivel consistente de abstracción, exhibe consistencia y simetría, y forma el vocabulario para un lenguaje expresivo. Por lo tanto, estar consciente de los principios guía no se traduce automáticamente en un comportamiento adecuado. Comer dulces es malo para ti.
En vez de predicar desde las alturas, quiero tomar una “estrategia” específica de diseño de API, una que me encuentro una y otra vez: el argumento de conveniencia. Comienza típicamente con los siguientes “puntos de vista”:
Aunque sea bien intencionado, tales argumentos son propensos a disminuir la legibilidad del código al usar el API. Una invocación de método como esta:
parser.processNodes(text, false);
no tiene virtualmente algún significado si no sabemos la implementación, o al menos consultar la documentación. Este método fue probablemente diseñado para la comodidad del implementador como un opuesto de la conveniencia de quien llama. “No quiero que quien hace la llamada tenga que hacer dos llamadas separadas” se traduce en: “no quería codificar dos métodos separados”. No hay nada fundamentalmente malo con la conveniencia si tiene intención de ser el antídoto del tedio, falta de idea o incomodidad. Sin embargo, si pensamos más cuidadosamente en ello, el antídoto para esos síntomas es la eficiencia, consistencia y elegancia, no necesariamente la conveniencia. Se supone que el API oculta la complejidad subyacente, podemos esperar de manera realista que un buen diseño de API requiere algo de esfuerzo. Un solo método largo podría ser ciertamente más conveniente de escribir que un bien pensado conjunto de operaciones, pero ¿sería fácil de usar?
La metáfora del API como un lenguaje puede guiarnos hacia mejores
decisiones de diseño en estas situaciones. Un API debe proporcionar un
lenguaje expresivo, lo cual nos da en el siguiente nivel suficiente de
vocabulario para preguntar y responder preguntas útiles. Esto no implica
que debería proveer exactamente un método o verbo por cada pregunta que
valga la pena. Un vocabulario diverso nos permite expresar matices de
significado. Por ejemplo, preferimos decir correr
en vez de
caminar(true)
, a pesar de que podría ser visto como esencialmente la
misma operación, sólo ejecutada en una velocidad distinta. Un
vocabulario API consistente y bien pensado hace expresivo y fácil de
entender el código del siguiente nivel. Más importante aún, un
vocabulario que pueda ser mejorado permite a otros programadores usar el
API de formas que quizás no habías anticipado –¡de hecho, una gran
conveniencia para los usuarios del API!–. La próxima vez que estés
tentado a agrupar unas cuantas cosas en un método API, recuerda que el
idioma inglés no tiene una palabra para
MakeUpYourRoomBeQuietAndDoYourHomeWork
(LimpiaTuCuartoSeCalladoyHazTuTarea), a pesar de que parece muy
conveniente para una operación tan frecuentemente solicitada.
Traducción: Espartaco Palma