Pregunta

Yo estaba teniendo una discusión con uno de mis colegas sobre cómo tránsito de código debe ser. Estoy totalmente a favor programación defensiva, pero hay que saber dónde parar. Estamos trabajando en un proyecto que se mantendrá por otros, pero esto no significa que tengamos que comprobar si todas las cosas locas un desarrollador podría hacer. Por supuesto, se puede hacer eso, pero esto va a agregar una gran sobrecarga al código.

¿Cómo saber dónde trazar la línea?

¿Fue útil?

Solución

No sé que no hay realmente ninguna manera de responder a esta. Es sólo algo que se aprende de la experiencia. Sólo tiene que preguntarse qué tan común es probable que sea un problema potencial y hacer un juicio. Ten en cuenta también que no necesariamente Tienes para siempre código defensiva. A veces es aceptable sólo para en cuenta los posibles problemas en la documentación de su código.

En última instancia, sin embargo, creo que esto es algo que una persona tiene que seguir su intuición. No hay manera correcta o incorrecta de hacerlo.

Otros consejos

Cualquier cosa que un usuario entra en forma directa o indirecta, que debiera siempre cordura-cheque. Más allá de eso, unos pocos assert está aquí y no le hará daño, pero realmente no se puede hacer mucho acerca de locos programadores edición y rompiendo su código, de todos modos -!)

tiendo a cambiar la cantidad de defensa que puse en mi código basado en el lenguaje. Hoy en día estoy trabajando principalmente en C ++ por lo que mis pensamientos van a la deriva en esa dirección.

Cuando se trabaja en C ++ no puede ser lo suficientemente programación defensiva. Trato a mi código como si estuviera guardando secretos nucleares y cualquier otro programador es a por ellos. Afirma, tiros, tiempo compilador hacks plantilla de error, la validación de argumentos, la eliminación de los punteros, en profundidad las revisiones de código y la paranoia general, son todos juego justo. C ++ es un lenguaje maravilloso mal que yo tanto amor y severamente desconfianza.

No soy un fan del término "programación defensiva". A mí me sugiere código como el siguiente:

void MakePayment( Account * a, const Payment * p ) {
    if ( a == 0 || p == 0 ) {
       return;
    }
    // payment logic here
}

Esto está mal, mal, mal, pero debe haber visto cientos de veces. La función nunca debería haber sido llamado con punteros nulos en el primer lugar, y es absolutamente erróneo para aceptar tranquilamente ellos.

El enfoque correcto aquí es discutible, pero una solución mínima es fracasar ruidosamente, ya sea usando una aserción o por lanzar una excepción.

Editar No estoy de acuerdo con algunas otras respuestas y comentarios aquí - No creo que todas las funciones deben revisar sus parámetros (para muchas funciones esto es simplemente imposible). En su lugar, yo creo que todas las funciones deben documentar los valores que son aceptables y estado que otros valores darán como resultado un comportamiento indefinido. Este es el enfoque adoptado por las bibliotecas con más éxito y más ampliamente utilizados que se han escrito -. Bibliotecas estándar ++ la C y C

Y ahora deja que los downvotes comienzan ...

Si usted está trabajando en API públicas de un componente entonces vale la pena hacer una buena cantidad de validación de parámetros. Esto me llevó a tener un hábito de hacer la validación en todas partes. Eso es un error. Todo lo que el código de validación no se hace la prueba y, potencialmente, hace que el sistema sea más complicado de lo que tiene que ser.

Ahora prefieren para validar mediante pruebas unitarias. Validación definitivamente sucede para los datos procedentes de fuentes externas, pero no para las llamadas de los desarrolladores no externas.

Siempre Debug.Assert mis suposiciones.

Mi ideología personal:. La actitud defensiva de un programa debe ser proporcional a la máxima ingenuidad / desconocimiento de la base de usuarios potenciales

Al ser defensiva contra los desarrolladores consumiendo su código API no es tan diferente de estar a la defensiva frente a los usuarios habituales.

  • Compruebe los parámetros para asegurarse de que están dentro de los límites adecuados y de tipos esperados
  • Compruebe que el número de llamadas a la API que podría hacerse están dentro de sus Términos de Servicio. Generalmente se llama estrangulación por lo general sólo se aplica a los servicios web y funciones de comprobación de la contraseña.

Más allá de eso, no hay mucho más que hacer, excepto asegurarse de que su aplicación se recupera bien en el caso de un problema y que siempre da una amplia información a los desarrolladores para que puedan entender lo que está pasando.

La programación defensiva es sólo una forma de hounouring un contrato en un diseño por contrato tipo de codificación.

Los otros dos son

  • total de la programación y
  • programación nominal.

Por supuesto, usted no debe defenderse contra el cada cosa loca un desarrollador podría hacer, pero entonces usted debe indicar en su contexto wich que va a hacer lo que se espera que el uso de condiciones previas.

//precondition : par is so and so and so 
function doSth(par) 
{
debug.assert(par is so and so and so )
//dostuf with par 
return result
}

Yo creo que hay que traer a la pregunta de si va a crear pruebas también. Usted debe estar a la defensiva en su codificación, pero como ha señalado JaredPar - también creo que depende del idioma que está utilizando. Si se trata de código no administrado, entonces usted debe ser extremadamente defensiva. Si se las ha arreglado, creo que tiene un poco de wiggleroom.

Si tiene pruebas, y algún que otro desarrollador intenta diezmar a su código, las pruebas se producirá un error . Pero, de nuevo, que depende de la cobertura de prueba en su código (si hay alguna).

Trato de escribir código que es más defensivo, pero hasta hostil derecha. Si algo va mal y puedo solucionarlo, lo haré. si no, tirar o pasar en la excepción y que sea alguien vigilara problema. Cualquier cosa que interactúa con un dispositivo físico - sistema de archivos, conexión de base de datos, conexión de red se debe considerar unereliable y propensos al fracaso. anticipando estas fallas y atrapándolos es crítico

Una vez que tenga esta forma de pensar, la clave es ser consistente en su enfoque. Qué se puede esperar a devolver los códigos de estado a comminicate problemas en la cadena de llamada o te gusta hacer excepciones. modelos mixtos van a matar o al menos conducir a beber. fuertemente. si está utilizando a alguien vigilara api, a continuación, aislar estas cosas en los mecanismos que atrapan / informe en cuanto a que utilice. utilizar estas interfaces de envolver.

Si la discusión aquí es cómo codificar defensiva contra el futuro (posiblemente malévolas o incompetentes) mantenedores, hay un límite a lo que puede hacer. Cumplimiento de contratos a través de la cobertura de la prueba y el uso liberal de hacer valer sus supuestos es probablemente lo mejor que puede hacer, y se debe hacer de una manera que idealmente no saturar el código y hacer el trabajo más difícil para los futuros mantenedores no malignas de la código. Afirma son fáciles de leer y entender y dejar claro cuáles son los supuestos de una determinada pieza de código es, por lo que son por lo general una gran idea.

Codificación defensiva contra las acciones del usuario es otro tema por completo, y el método que utilizo es pensar que el usuario es a por mí. Cada entrada es examinado con tanto cuidado como puedo manejar, y hacer todo lo posible para que mi código de prueba de fallos - trate de no persistir cualquier estado que no es examinada con rigor, correcta donde se puede, salida con gracia si no se puede, etc. Si sólo pensar en todas las cosas bozo que podrían ser perpetrados en su código por agentes externos, lo que se interpone en el derecho de pensar.

Codificación defensiva contra otro código, tal como su plataforma u otros módulos, es exactamente lo mismo que los usuarios: están tratando de hacerte daño. El sistema operativo siempre va a intercambiar el hilo en un momento inoportuno, las redes siempre van a desaparecer en el momento equivocado, y en general, el mal abunda en cada esquina. No es necesario para codificar en contra de cada problema potencial por ahí - el costo de mantenimiento podría no valer la pena el aumento de la seguridad - pero seguro que no está de más pensar en ello. Y por lo general no hace daño a comentar de forma explícita en el código si hay un escenario que pensó en lo que se refiere, pero como poco importante por alguna razón.

Los sistemas deben tener límites en los que ocurre la comprobación defensiva bien diseñado. No debe ser una decisión acerca de dónde se valida la entrada del usuario la interacción del motor (a qué límite) y donde otras cuestiones defensivas potenciales requieren de control (por ejemplo, puntos de integración de terceros, pública APIs disponibles, reglas o diferentes unidades codificadas por diferentes equipos de programadores ). comprobación más defensivo que viola SECO que en muchos casos, y sólo se suma el coste de mantenimiento por muy poco benifit.

Una vez dicho esto, hay ciertos puntos en los que no puede ser demasiado paranoico. Potencial de desbordamientos de búfer, la corrupción de datos y cuestiones similares debe ser muy rigurosa defendió en contra.

Recientemente tuve escenario, en el que los datos de entrada del usuario se propaga a través de la interfaz remota fachada, fachada de interfaz local de entonces, entonces alguna otra clase, para finalmente llegar al método en el que se utiliza realmente. Me preguntaba a mi mismo una pregunta:? ¿Cuándo se debe validarse el valor I añade código de validación sólo a la clase final, en la que se utiliza realmente el valor. La adición de otros fragmentos de código de validación en las clases que ponen en el camino de propagación de programación sería demasiado defensivo para mí. Una excepción podría ser la fachada remoto, pero yo saltamos también.

Buena pregunta, no tengo flip se dejó caer entre hacer comprobaciones de validez y no hacerlas. Es un 50/50

situación, probablemente me tomo un punto medio en el que lo haría solamente "Bullet Proof" ningún rutinas que son:

(a) Llamado desde más de un lugar en el proyecto

(b) tiene lógica que es probable que cambie

(c) No se pueden utilizar los valores por defecto

(d) la rutina no se puede 'falló con gracia

Darknight

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top