Una buena API es una parte importante del éxito. Sucede que esta es la única razón por la que se eligió esta biblioteca en particular o este producto. No es fácil crear una buena API y no existe una ruta única para crear una, porque cada caso requiere un enfoque diferente. Aquellos que a menudo han tenido que usar varias bibliotecas, probablemente ya tengan una buena idea de qué es exactamente una buena API. Intentaremos recopilar todos los puntos de vista juntos.
1. Versátil pero cómodo
La versatilidad es clara para todos, pero no todos saben qué medio conveniente. Es necesario acceder a algunos elementos con más frecuencia que a otros. Por lo tanto, la clave para desarrollar una API competente puede ser crear un extracto de la documentación completa como referencia sobre los métodos de uso común.
Por ejemplo, veamos una clase Person simple. Él tiene:
Necesita un constructor vacío que cree un objeto vacío cuyos campos se completarán más tarde;
Se requieren métodos set / get para trabajar con nombres y apellidos;
Y métodos para manejar campos adicionales de nombre / apellido (algunas personas tienen más de dos palabras en un nombre).
Se puede construir una API completa a partir de la descripción de todos estos métodos. Y para mayor comodidad, resaltemos por separado la documentación de dichos elementos:
Constructor con dos parámetros: nombre y apellido, ya que esta combinación es la más común del mundo;
Establecer / obtener métodos para nombres adicionales, ya que en algunas culturas del mundo, la mayoría de la gente tiene más de un nombre. Si la aplicación se crea específicamente para dichos países, entonces tiene sentido agregar más parámetros al constructor desde el primer párrafo.
La idea principal aquí no es crear una API completa a la que se pueda acceder de todos modos, sino crear documentación dedicada que contenga enlaces para ayudar a los métodos más utilizados.
2. Aplicable de todos modos, pero no demasiado grande
Este punto, quizás, podría combinarse con el primero, pero aún me gustaría prestarle más atención.
La mayor parte de la documentación se basa en el principio "¿Qué pasa si ...?", Aunque aquí, quizás, deba limitarse, porque no hay límites definidos para considerar todos los casos posibles. No puede decir exactamente de qué deshacerse, porque todo depende de la situación específica. Mientras tanto, aquí hay algunos consejos:
Aquello a lo que mucho está ligado, que no ha cambiado con el tiempo, debe actualizarse gradualmente, preferiblemente con una advertencia previa.
Por ejemplo, IPv6. Hemos estado cambiando al nuevo protocolo durante tanto tiempo, porque una gran cantidad de software está estrictamente vinculado a IPv4. ¿Es correcto? Quizás sí. Ahora el programador tiene la opción de utilizar tecnología moderna o incluso implementar soporte simultáneo para diferentes protocolos. ¿Vale la pena el tiempo? Tú decides.
La conveniencia de las clases y métodos permanece siempre que esté claro qué son estas clases o métodos y de qué son responsables.
3. Los nombres de los métodos deben ser significativos, fáciles de entender, estructurados y lo más breves posible.
Nombrar correctamente es una parte muy importante de escribir una buena API. Aunque es muy importante dar a sus métodos nombres significativos, esta no es la única regla. Y aunque la mayor parte del trabajo del programador consiste en leer el código, todavía tiene que escribir el código, y los métodos con nombres lógicos pueden mejorar significativamente el rendimiento del codificador, sin mencionar la finalización automática.
La estructuración de la API también es importante si la documentación es lo suficientemente extensa. En resumen, debe haber algún tipo de convención de nomenclatura de sufijos / prefijos que separará su API del resto de la documentación.
Además, el nombre del método puede hacerse lógico a expensas de la integridad. Las reglas de nomenclatura deben ser generales para toda la API y preferiblemente similares a las reglas de nomenclatura en la documentación de áreas similares. Es mejor adaptarse inmediatamente al estilo de nomenclatura del lenguaje para el que crea su módulo y escribe la API.
Finalmente, no se le ocurran nombres demasiado largos. Por supuesto, cuanto más largo, por lo general, más claro es el significado, pero aún así siempre hay un cierto límite, el paso a través del cual conducirá a una tautología. Por ejemplo, Integer_Maximum_Value es inútilmente más largo que INT_MAX , pero tiene la misma carga semántica.
4. Centrado en mejorar la productividad sin sacrificar la comodidad
No es necesario acceder a algunas API con frecuencia, mientras que otras deberían estar siempre a mano y, por lo tanto, no utilizarlas no debería reducir la productividad del programador. Y nunca debes olvidarte de la comodidad. Por ejemplo, la API de Windows es un ejemplo de cómo se ha sacrificado la comodidad por el rendimiento. Carece de funciones que llenen las estructuras de datos con valores predeterminados. Es molesto poner a cero cada elemento por separado. Por otro lado, algunas funciones podrían llamarse redundantes: a veces, obviamente, valdría la pena reemplazar varias funciones por una. Por ejemplo, FindFirstFile () y FindNextFile () podrían combinarse, pero ZeroMemory () debería reemplazarse por un memset () más eficiente .
5. Constantes convenientes
Cuanto menos a menudo un desarrollador tenga que reducir el alcance de métodos, clases, etc. para comprenderlos mejor, mejor. En la mayoría de los casos ... Las
constantes también deben tener nombres lógicos.
Por otro lado, también es una buena idea permitir la definición de constantes específicas de la aplicación.
6. Elija el formato de archivo adecuado para representar su API
En resumen, no se detenga ciegamente en XML.
Si está trabajando en un servicio web, piense en cómo presentar la documentación: puede ser XML, JSON u otra cosa. Piense en quién utilizará su API. Hacer que la gente use XML es ... bueno, está bien, use XML si nada más le conviene.
7. Personalizable, pero con moderación
Aquí estamos hablando de frameworks. Muchos de ellos permiten al usuario cambiar el comportamiento de algunos elementos cambiando los parámetros de configuración. Esto es bueno, pero necesita saber cuándo detenerse. Primero, debes entender que algunas configuraciones son completamente estúpidas. Cuantos más parámetros sean susceptibles de cambio, más difícil será tener en cuenta todas las configuraciones posibles, sin mencionar el hecho de que algunos valores de parámetros pueden resultar incompatibles y afectar negativamente al rendimiento.
“Absolutamente todo se puede conectar, expandir y personalizar” no es el enfoque correcto. Es mejor no poder personalizar que personalizar para que nada funcione.
En casos especiales, puede limitar las opciones de configuración a una "caja blanca": en lugar de aumentar el número de combinaciones de parámetros de acuerdo con el principio de "caja negra", puede dividir todas las configuraciones en grupos de valores preestablecidos, y el usuario ajustará el marco por sí mismo combinando estos conjuntos de configuraciones.
8. Ejecución concurrente vs. Hilo único
Cuando se trata de operaciones que requieren mucho tiempo, es mejor negarse a realizar múltiples tareas sincrónicamente. Idealmente, por supuesto, todas las operaciones largas deberían minimizar la sincronización.
Pero en este caso, la aplicación no sincronizada debe tener una alternativa que admita la ejecución simultánea de múltiples tareas. Es extraño Déjanos explicarte. No tiene sentido sincronizar la ejecución de operaciones si tiene una interfaz de usuario decente. La sincronización puede reducir la capacidad de respuesta de una aplicación, pero si decide abandonar la interfaz de usuario, entonces, para evitar retrasos, debe implementar la sincronización de operaciones.
Desafortunadamente, no puede predecir qué versión preferirá el usuario, por lo que tiene sentido crear ambas y darles la opción.
9. No todo el mundo sabe inglés
Si su API admite una interfaz de usuario, asegúrese de implementar una configuración de localización. No se olvide también de los mensajes de error: escriba códigos de excepción que rastreen la configuración de localización o localicen los mensajes de error por sí mismos. PERO si tiene poca idea sobre la localización, asegúrese de consultar a alguien.
10. Compatibilidad con versiones nuevas y antiguas
Idealmente, cualquier versión nueva debería ser compatible con todas las anteriores. Pero en la práctica, esto quizás sea imposible. A continuación se ofrecen algunos consejos:
Diseñe su API inicialmente para que pueda ampliarse en el futuro. Tenga especial cuidado con los argumentos de tipo booleano (puede reemplazarlos con un tipo numerado);
Si conoce de antemano las funciones que se introducirán en el futuro, puede incluirlas inmediatamente en la API para garantizar la compatibilidad con versiones futuras;
Tenga cuidado de mantener la compatibilidad con versiones anteriores, pero no implemente el reflejo de su API, porque en el futuro tendrá que considerar la compatibilidad con el mecanismo de autoprocesamiento de la API;
Es mejor tomar descansos prolongados entre lanzamientos de nuevas versiones de API que lanzar actualizaciones frecuentes. Por supuesto, a nadie le gustan estas interrupciones, pero la necesidad de actualizar con frecuencia parece ser especialmente molesta para los desarrolladores;
No descuide las pruebas alfa / beta, porque la mejor ruta de desarrollo es hacer un seguimiento de los comentarios de los usuarios.
11. La conveniencia excesiva no está justificada
No se puede dejar de conceder suficiente importancia al tiempo del desarrollador. Si un programador escribe menos código, esto no significa que trabaje poco.
Cuando las cosas funcionan automáticamente por arte de magia, puede ser difícil cambiarlas de acuerdo con la tarea en cuestión.
Conclusión
Unas pocas, incluso personas muy inteligentes y experimentadas, no pueden crear buenas API a puerta cerrada. La comunicación con los consumidores, especialmente si dicho contacto se ha establecido desde el comienzo del trabajo, es la clave para una implementación competente.
Comentarios