¿Qué principios básicos desearías en una biblioteca?

8

Se habla sobre la sintaxis y la característica que le gusta en un lenguaje de programación; ahora le preguntaré qué principios o características principales le gustaría tener en una biblioteca en su idioma favorito (o cualquier otro).

Un ejemplo es tener agregar list + = anotherList válido como opuesto a permitir solo list + = listElement (aunque algunos pueden ver esto como una mala idea)

dsimcha
fuente
66
Valores tradicionales de la biblioteca, como "shhh" y "no besarse en las pilas". :-)
Stephen C

Respuestas:

6

Seguiría las mejores prácticas que puede encontrar en Cómo diseñar una buena API y por qué es importante por Joshua Blosh (Google) . La versión en PDF se puede encontrar aquí .

Según él, las características de una buena API son:

Fácil de aprender
Fácil de usar, incluso sin documentación
Difícil de mal uso
Fácil de leer y mantener el código que lo usa
Suficientemente potente para satisfacer los requisitos
Fácil de extender
Adecuado para la audiencia

David
fuente
"Fácil de usar mal" sería el deseo de un hacker (en un sentido más amplio), creo.
mojuba
@mojuba: Reformularía esto un poco como "hacer lo correcto debería ser fácil, hacer lo incorrecto debería ser difícil", es decir, el usuario de la lib se siente obligado a usar la biblioteca de la manera correcta. Eso no evita el tipo de abuso que alegra la mente de los hackers.
peterchen
5

Quiero lo siguiente:

  • Un espacio de nombres claramente definido. Como C es mi lenguaje principal, también quiero que las macros coincidan con esto. Resolver conflictos en esa área apesta.

  • Si asigna algo, deme una pista obvia de que tiene que ser liberado. Esto va al siguiente punto, que es la documentación.

  • Documentar la biblioteca. Herramientas como Doxygen son simples y portátiles, no hay excusa para no darme algo que pueda generar y navegar.

  • Documentar tipos opacos en encabezados públicos. Voy a encontrarlos de todos modos, dime por qué no quieres que me meta con ellos y qué podría pasar si lo hago. Si realmente quieres parches, necesito saber lo que estabas pensando.

  • No te caigas y corras. Realmente aprecio comentarios como "Por favor, no me contacten sobre esto. No tengo intención de mantenerlo. Esto resolvió mi problema inmediato, tal vez resolverá su problema. No me importa, no voy a actualizar esto y puedes sentirte libre de bifurcarlo ". No puedo decirte cuánto tiempo me ahorra.

  • No debe agregar pérdidas de memoria o errores al código existente. Si no realiza la prueba antes de insertar cosas en su propio código, ¿por qué me tienta a llevarlo al mío?

  • Si de hecho es una biblioteca, use una licencia permisiva y sea consistente. No decida dentro de tres meses que debería ganar más dinero con él. Eso es más que molesto la noche antes de enviar algo y darse cuenta de que tiene que volver a escribir un montón de código de biblioteca porque la licencia cambió. Ese es exactamente el tipo de cosas que me irritan lo suficiente como para volver a implementar sus cosas bajo la licencia MIT.

  • Sea coherente en el estilo de codificación, otras personas tienen que leer su código para descubrir qué está haciendo realmente cuando las cosas no funcionan como se esperaba.

  • No use más de 110 columnas, es posible que su código deba editarse en su lugar, y es posible que solo tenga una pantalla de 80x25. Si confía en las pestañas para que las cosas se vean más 'elegantes', tiene otros problemas que resolver.

  • Intente al menos considerar los puertos, si no se trata de un lenguaje interpretado. Incluso entonces, intenta al menos considerar los puertos.

  • Dame pruebas. Espero que los tenga, podría sugerirles lo contrario y podría ayudarlo a escribirlos en base a un gráfico de llamadas. Si voy a través de todos esos problemas, por favor, los utilizan . De lo contrario, obtienes parches que "funcionan para mí !!!" :)

  • No rompas la API, punto. Sé que puedes darte cuenta de que lo has hecho todo mal, pero asegúrate de que las cosas que te enlazan no se rompan en una simple actualización. Eso puede significar algunos rudos y descuidos, bienvenidos al mundo de las bibliotecas.

  • Dame una hoja de ruta para que no duplique tu trabajo o el trabajo de otros.

Es probable que edite esta publicación para agregar más.

Tim Post
fuente
Un motivo favorito para mí en C son las convenciones de devolución de cadenas engorrosas. Por ejemplo, usarlo getcwdcorrectamente requiere hacer un bucle que expanda el búfer hasta que sea lo suficientemente grande ( ver ejemplo ).
Joey Adams
4

Estoy más preocupado por las características suaves de una API. Es decir:

  • Sencillez
  • Consistencia
  • Elegancia
  • Intuitivo
  • Solo funciona

Podría corregir un libro sobre cómo se aplican o se implementarían, pero es suficiente decir que a menos que un usuario de la API pueda entender cómo usarlo de manera efectiva, es de uso limitado. La simplicidad no significa simplismo, así como la elegancia no significa onate. Simplemente significa que es perfecto para el trabajo. Cuanto menos alguien tenga que pensar en cómo usar la API, más podrá usarla.

La forma en que se ven depende del idioma, el propósito y el público objetivo de la API. El último criterio se reduce al principio de menor sorpresa. No hay errores donde no los esperaba. Cualquier interpretación razonable de la API le dará los resultados que desea.

Berin Loritsch
fuente
1
Técnicamente "simplemente funciona" no es una característica de la API sino de su implementación;)
back2dos
:) Sin embargo, parece que es un diferenciador entre API similares. Por eso lo considero una característica.
Berin Loritsch
3

Haga que las cosas simples sean simples y complicadas

Esto resume casi cualquier otra filosofía de diseño. Si su biblioteca solo hace posibles cosas complicadas, las personas que buscan resolver el 80% de los casos de uso más fáciles se verán tentadas a reinventar la rueda en lugar de lidiar con su monstruosidad de ingeniería excesiva que requiere que use 6 clases diferentes para hacer el equivalente de "Hola" a su biblioteca Mundo".

Si su biblioteca solo simplifica las cosas simples, las personas se molestarán muy rápidamente cuando descubran que necesitan reescribir su código solo porque tenían un requisito que estaba un poco fuera de lo común.

Las mejores formas de lograr esto son:

  • Sé liberal en lo que aceptas. Si está programando en un lenguaje dinámico, use la escritura de pato para obtener un efecto completo. Si está programando en C ++ o D, use plantillas siempre que sea posible. Acepte cualquier cosa que satisfaga alguna interfaz estructural razonablemente universal. No obligue a sus usuarios a hacer mucho trabajo ocupado convirtiendo datos de un formato a otro.

  • Cree funciones de conveniencia de alto nivel en su biblioteca, pero hágalo de manera transparente sobre la funcionalidad de nivel inferior y asegúrese de que la funcionalidad de nivel inferior esté disponible para las personas que la necesitan.

  • Siga el principio de la menor sorpresa por defecto, incluso cuando hacerlo puede limitar la flexibilidad o la eficiencia. Si es necesario, agregue una segunda función con un nombre más detallado que enfatice su sorpresa para permitir optimizaciones o mayor flexibilidad.

  • La encapsulación es útil, pero no seas anal al respecto. Las personas con requisitos inusuales e imprevistos ocasionalmente pueden necesitar estar debajo de una de sus abstracciones para hacer el trabajo. Por otro lado, debería ser difícil pegarse un tiro en el pie por accidente, cuando se utilizan construcciones aparentemente inocentes . Tenga esto en cuenta al decidir qué tan bien desea bloquear las cosas.

  • Use ejemplos en gran medida en su documentación. Esto sirve tanto para ilustrar casos de uso comunes para su usuario como para obligarlo a pensar si los casos más comunes están suficientemente optimizados.

  • Tenga valores predeterminados razonables para todo lo que pueda, pero asegúrese de que esos valores predeterminados sean solo valores predeterminados y que esté claro cómo anularlos.

dsimcha
fuente
2
  • Minimalismo razonable y saludable

Eso es todo. Compare, como ejemplo, el mecanismo de tuberías en Windows y UNIX. Uno ofrece un montón de funciones API especializadas con un montón de argumentos oscuros, innecesarios o raramente utilizados, cada uno de los cuales puede tener uno de los muchos valores macro / constantes. UNIX básicamente reutiliza la interfaz existente de abrir / leer / escribir / cerrar, además de algunos métodos muy simples para algunos casos específicos, como socketpair () o pipe (). Realmente hay casi, casi nada nuevo que debería aprender para usar tuberías en UNIX. Ahora compara a esto .

(Para ser justos, Microsoft originalmente solo "tomó prestada" esa interfaz del OS / 2 de IBM).

mojuba
fuente