Sé liberal en lo que aceptas ... ¿o no?

43

[Descargo de responsabilidad: esta pregunta es subjetiva, pero preferiría obtener respuestas respaldadas por hechos y / o reflexiones]

Creo que todos saben sobre el Principio de robustez , generalmente resumido por la Ley de Postel:

  

Sé conservador en lo que envíes; Sé liberal en lo que aceptas.

Estoy de acuerdo en que para el diseño de un protocolo de comunicación generalizado esto puede tener sentido (con el objetivo de permitir una fácil extensión), sin embargo, siempre he pensado que su aplicación a HTML / CSS fue un fracaso total, cada navegador implementa su posee detección / comportamiento de ajustes silenciosos, lo que hace casi imposible obtener una representación coherente en varios navegadores.

Sin embargo, me doy cuenta de que la RFC del protocolo TCP considera aceptable el "Fallo silencioso" a menos que se especifique lo contrario ... lo que es un comportamiento interesante, por decir lo menos.

Hay otros ejemplos de la aplicación de este principio en todo el comercio de software que aparecen regularmente porque han mordido a los desarrolladores, desde el principio:

  • inserción de punto y coma de Javascript
  • C (silencioso) conversiones incorporadas (que no serían tan malas si no se truncaran ...)

y hay herramientas para ayudar a implementar el comportamiento "inteligente":

Sin embargo, me parece que este enfoque, si bien puede ser útil cuando se trata de usuarios no técnicos o para ayudar a los usuarios en el proceso de recuperación de errores, tiene algunos inconvenientes cuando se aplica al diseño de la interfaz de biblioteca / clases:

  • es un tanto subjetivo si el algoritmo adivina "correcto", y por lo tanto puede ir en contra del Principio de menos asombro
  • hace que la implementación sea más difícil, por lo tanto, hay más posibilidades de introducir errores (violación de YAGNI ?)
  • hace que el comportamiento sea más susceptible de cambiar, ya que cualquier modificación de la rutina de "adivinación" puede romper los programas antiguos, casi excluyendo las posibilidades de refactorización ... ¡desde el principio!

Y esto es lo que me llevó a la siguiente pregunta:

Al diseñar una interfaz (biblioteca, clase, mensaje), ¿te inclinas hacia el principio de robustez o no?

Yo mismo tiendo a ser bastante estricto, utilizando una extensa validación de entrada en mis interfaces, y me preguntaba si quizás era demasiado estricto.

    
pregunta Matthieu M. 16.10.2010 - 15:41

10 respuestas

33

Yo diría que robustez cuando no introduce ambigüedades .

Por ejemplo: Al analizar una lista separada por comas, ya sea que haya o no un espacio antes / después de que la coma no cambie el significado semántico.

Al analizar una guía de cadenas, debe aceptar cualquier número de formatos comunes (con o sin guiones, con o sin llaves).

La mayoría de los lenguajes de programación son robustos con el uso de espacios en blanco. Específicamente en todas partes que no afecta el significado del código. Incluso en Python, donde el espacio en blanco es relevante, sigue siendo flexible cuando estás dentro de una lista o declaración de diccionario.

Definitivamente estoy de acuerdo en que si algo se puede interpretar de varias maneras o si no está claro al 100% de lo que se quería decir, demasiada solidez puede terminar siendo un dolor, pero hay mucho espacio para la robustez sin ser ambiguo.

    
respondido por el Davy8 16.10.2010 - 18:25
14

Definitivamente no. Técnicas como la programación defensiva oculta los errores, lo que hace que su apariencia sea menos probable y más aleatoria, lo que dificulta su detección, lo que dificulta el aislamiento.

El Escribir código sólido fue subestimado en gran medida al enfatizar repetidamente la necesidad y las técnicas de hacer Errores tan difíciles de introducir u ocultar. A través de la aplicación de sus principios, como "Eliminar el comportamiento aleatorio. Forzar que los errores sean reproducibles". y, "Siempre busque, y elimine, fallas en sus interfaces". los desarrolladores mejorarán enormemente la calidad de su software al eliminar la ambigüedad y los efectos secundarios no controlados que son responsables de una gran cantidad de errores.

    
respondido por el Huperniketes 16.10.2010 - 18:14
9

La aplicación excesiva de robustez te lleva a adivinar lo que el usuario deseaba, lo cual está bien hasta que te equivocas. También requiere la fe completamente equivocada de que sus clientes no abusarán de su confianza y crearán un alboroto al azar que simplemente funciona, pero que no podrá admitir en la versión 2.

La aplicación excesiva de la corrección lo lleva a negar a sus clientes el derecho de cometer errores menores, lo cual está bien hasta que se quejan de que sus cosas funcionan bien en el producto de su competidor, y le dicen qué puede hacer con su estándar de 5,000 páginas. tiene la palabra "BORRADOR" aún garabateada en la portada del crayón, y al menos 3 expertos afirman que tiene fallas fundamentales, y 200 expertos más honestos dicen que no entienden completamente.

Mi solución personal siempre ha estado en desuso. Usted los apoya, pero dígales que lo están haciendo mal y (si es posible) el camino más fácil hacia la corrección. De esa manera, cuando desactiva la característica de error 10 años después, al menos tiene el rastro del documento para indicar que "le avisamos de que esto podría suceder".

    
respondido por el deworde 15.11.2011 - 12:09
9

Desafortunadamente, el llamado "principio de robustez" no conduce a la robustez. Tomemos HTML como ejemplo. Muchos problemas, lágrimas, pérdida de tiempo y energía podrían haberse evitado si los navegadores hubieran analizado estrictamente el HTML desde el principio en lugar de tratar de adivinar el significado del contenido mal formado.

El navegador simplemente debería haber mostrado un mensaje de error en lugar de intentar solucionarlo debajo de las cubiertas. Eso habría obligado a todos los bichos a arreglar su desorden.

    
respondido por el ThomasX 15.11.2011 - 13:50
6

Divido las interfaces en varios grupos (agrega más si quieres):

  1. los que están bajo su control deben ser estrictos (normalmente las clases)
  2. API de biblioteca, que también deben estar en el lado estricto, pero se recomienda una validación adicional
  3. interfaces públicas que deben manejar todos los tipos de abuso que se producen (normalmente protocolos, entradas de usuarios, etc.). Aquí la solidez en la entrada realmente vale la pena, no se puede esperar que todo el mundo arregle sus cosas. Y recuerde, para el usuario, que será su culpa si la aplicación no funciona, no la parte que envió alguna basura mal formateada.

La salida siempre debe ser estricta.

    
respondido por el MaR 15.11.2011 - 18:11
5

Creo que HTML y la World Wide Web han proporcionado una prueba a gran escala en el mundo real del Principio de Robustez y han demostrado que es un gran fracaso. Es directamente responsable del confuso lío de los estándares casi competitivos de HTML que hace que la vida sea miserable para los desarrolladores web (y sus usuarios) y empeora con cada nueva versión de Internet Explorer.

Hemos sabido desde la década de 1950 cómo validar el código correctamente. Ejecutar a través de un analizador estricto y si algo no es sintácticamente correcto, lanzar un error y abortar. No pase, no recolecte $ 200, y por amor a todo lo que es binario ¡no permita que algún programa de computadora intente leer la mente del codificador si cometió un error!

HTML y JavaScript nos han mostrado exactamente qué sucede cuando se ignoran esos principios. El mejor curso de acción es aprender de sus errores y no repetirlos.

    
respondido por el Mason Wheeler 16.10.2010 - 15:52
3

Como contrapunto al ejemplo de Mason, mi experiencia con el Protocolo de inicio de sesión fue que mientras que diferentes pilas interpretarían las relevantes Los RFC son diferentes (y sospecho que esto sucede con todos los estándares que se hayan escrito), ser (moderadamente) liberal en lo que aceptas significa que puedes realizar llamadas entre dos dispositivos. Debido a que estos dispositivos son cosas físicas habituales en lugar de piezas de software en un escritorio, simplemente tiene que ser liberal en lo que acepta, o su teléfono no puede llamar a otro teléfono de una marca particular. ¡Eso no hace que tu teléfono se vea bien!

Pero si está escribiendo una biblioteca, probablemente no tenga el problema de que varias partes interpreten un estándar común de manera incompatible entre sí. En ese caso, diría que sea estricto en lo que acepta, porque elimina las ambigüedades.

El archivo de jerga también tiene una historia de horror sobre "adivinar" un usuario intención.

    
respondido por el Frank Shearar 16.10.2010 - 16:50
3

Tienes razón, la regla se aplica a los protocolos y no a la programación. Si realiza un error tipográfico al programar, recibirá un error tan pronto compile (o ejecute, si es uno de esos tipos dinámicos). No hay nada que ganar dejando que la computadora adivine por ti. A diferencia de la gente común, somos ingenieros y somos capaces de decir exactamente lo que quiero decir. ;)

Entonces, al diseñar una API, yo diría que no sigue el Principio de Robustez. Si el desarrollador comete un error, debe informarse de inmediato. Por supuesto, si su API usa datos de una fuente externa, como un archivo, debe ser indulgente. El usuario de su biblioteca debe descubrir sus propios errores, pero no los de nadie más.

Como nota aparte, supongo que se permite un "fallo silencioso" en el protocolo TCP porque, de lo contrario, si la gente te lanzara paquetes mal formados, serías bombardeado con mensajes de error. Eso es simple protección DoS allí mismo.

    
respondido por el Note to self - think of a name 16.10.2010 - 17:31
1

OMI, la robustez es una parte de un compromiso de diseño, no un principio de "preferencia". Como muchos han señalado, nada apesta como soplar cuatro horas tratando de averiguar dónde salió mal su JS solo para descubrir que el problema real fue que solo un navegador hizo lo correcto con XHTML Strict. Dejó que la página se rompiera cuando una parte del HTML servido fue un completo desastre.

Por otra parte, ¿quién quiere buscar documentación para un método que toma 20 argumentos e insiste en que estén exactamente en el mismo orden con los titulares de posición vacíos o de valor nulo para los que desea omitir? La manera igualmente tremenda y robusta de lidiar con ese método sería verificar cada argumento e intentar adivinar cuál era el que se basaba en las posiciones y tipos relativos y luego fallar en silencio o intentar "hacer" con argumentos sin sentido.

O puede incluir flexibilidad en el proceso al pasar una lista de pares de literal / diccionario / valor-objeto y manejar la existencia de cada argumento al llegar a él. Para el menor compromiso de perf, ese es un escenario de pastel y también se lo come.

La sobrecarga de argumentos en formas inteligentes y coherentes con la interfaz es una forma inteligente de ser sólido con respecto a las cosas. Por lo tanto, la redundancia se está convirtiendo en un sistema en el que se supone que la entrega de paquetes generalmente no se entregará en una red masivamente complicada, propiedad de todos en un campo emergente de tecnología con una amplia variedad de medios potenciales para la transmisión.

Sin embargo, tolerar un fallo abyecto, especialmente dentro de un sistema que usted controla, nunca es un buen compromiso. Por ejemplo, tuve que tomar un respiro para evitar lanzar un ataque sibilante en otra pregunta acerca de poner a JS en la parte superior o inferior de la página. Varias personas insistieron en que era mejor colocar a JS en la parte superior porque, si la página no se cargaba por completo, todavía podría tener alguna funcionalidad. Las páginas a medio trabajar son peores que los bustos completos. En el mejor de los casos, dan como resultado más visitantes a su sitio con razón, asumiendo que usted es incompetente antes de que se entere, en lugar de que la página interrumpida simplemente sea devuelta a una página de error al fallar su propia verificación de validación seguida de un correo electrónico automatizado a Alguien que pueda hacer algo al respecto. ¿Se sentiría cómodo transfiriendo la información de su tarjeta de crédito a un sitio que estuvo medio ocupado todo el tiempo?

Intentar entregar la funcionalidad de 2010 en un navegador de 1999 cuando solo podría entregar una página de tecnología más baja es otro ejemplo de una desventaja de diseño imprudente. Las oportunidades desperdiciadas y el dinero que he visto desperdiciado en el tiempo de desarrollador empleado en soluciones alternativas llenas de errores solo para obtener esquinas redondeadas en un elemento que se cierne sobre un fondo de gradiente de @ # $ ing, por ejemplo, me han sorprendido por completo. ¿Y para qué? Para ofrecer páginas de mayor tecnología que tengan un rendimiento deficiente a los tecnófobos comprobados y al mismo tiempo limitar las opciones en los navegadores de mayor nivel.

Para que sea la elección correcta, la elección de manejar la información de forma robusta siempre debería facilitarle la vida en ambos lados del problema, a corto y largo plazo, a la OMI.

    
respondido por el Erik Reppen 06.04.2012 - 03:53
1

Nunca fallar en silencio . Aparte de eso, intentar adivinar qué quería el usuario de una API / biblioteca, no parece una mala idea. Aunque no lo seguiría; teniendo un requisito estricto, puede exponer errores en el código de llamada y / o interpretaciones erróneas sobre su API / biblioteca.

Además, como ya se ha señalado, depende de lo difícil que sea realmente adivinar lo que el usuario esperaba. Si es muy fácil, entonces tienes dos casos:

  1. Su biblioteca debe diseñarse de manera un poco diferente (cambie el nombre de una función o divídala en dos), de modo que el usuario pueda esperar lo que realmente proporciona.
  2. Si cree que su biblioteca está diseñada correctamente, lo que significa una denominación clara y directa, puede intentar deducir lo que el usuario pretendía.

En cualquier caso que no sea 100% obvio y determinista, que una entrada se convierta en otra, no debe hacer las conversiones, por una serie de razones ya mencionadas (rompiendo la compatibilidad en la refactorización, menos el asombro de los usuarios) .

Cuando se trata de un usuario final, tratar de corregir su entrada / conjetura es muy bienvenido. Se espera que ingrese información no válida; Este caso es completamente excepcional. Otro desarrollador, sin embargo, no es un simple usuario no técnico. Él tiene la experiencia para entender un error, y el error puede tener importancia o ser beneficioso para él. Por lo tanto, estoy de acuerdo con usted en el diseño de API estrictas, mientras que, por supuesto, la rigurosidad viene acompañada de claridad y simplicidad.

Le recomendaría que lea esta pregunta mía , de un caso similar.

    
respondido por el K. Gkinis 12.04.2016 - 10:41

Lea otras preguntas en las etiquetas