En caso de que el servicio arroje una excepción o una devolución cuando no haya elementos especificados para su eliminación

12

Tengo un código que se puede representar como:

public class ItemService {

    public void DeleteItems(IEnumerable<Item> items)
    {
        // Save us from possible NullReferenceException below.
        if(items == null)
            return;

        foreach(var item in items)
        {
            // For the purpose of this example, lets say I have to iterate over them.
            // Go to database and delete them.
        }
    }
}

Ahora me pregunto si este es el enfoque correcto o si debería lanzar una excepción. Puedo evitar las excepciones, ya que la devolución sería lo mismo que iterar sobre una colección vacía, lo que significa que, de todos modos, no se ejecuta ningún código importante, pero, por otro lado, posiblemente estoy ocultando problemas en algún lugar del código, porque ¿por qué alguien querría llamar? DeleteItems con el parámetro null ? Esto puede indicar que hay un problema en otra parte del código.

Este es un problema que normalmente tengo con los métodos en los servicios, porque la mayoría de ellos hace algo y no devuelve un resultado, por lo que si alguien pasa información no válida, no hay nada que hacer el servicio, por lo que devuelve.

    
pregunta FCin 24.05.2018 - 09:12

5 respuestas

58

Estas son dos preguntas diferentes.

¿Debes aceptar null ? Eso depende de su política general sobre null en la base del código. En mi opinión, prohibir null en todas partes excepto donde se documenta explícitamente es una buena práctica, pero es una práctica aún mejor atenerse a la convención que ya tiene su código base.

¿Debes aceptar la colección vacía? En mi opinión: sí, absolutamente. Es mucho más esfuerzo restringir a todas las personas que llaman a colecciones no vacías que a hacer lo correcto matemáticamente, incluso si sorprende a algunos desarrolladores que están dudosos con el concepto de cero.

    
respondido por el Kilian Foth 24.05.2018 - 10:06
9

Valor nulo

Como ya dijo @KilianFoth, apégate a tu política general. Si eso es tratar a null como una "abreviatura" para una lista vacía, hazlo de esa manera.

Si no tiene una política consistente sobre los valores de null , recomendaría la siguiente:

null debe reservarse para representar situaciones que no pueden ser expresadas por el tipo "normal", por ejemplo. usando null para representar "No sé". Y esa es una buena opción, ya que todos los que intenten usar este valor sin cuidado obtendrán una excepción, que es lo correcto.

Usar null como una abreviatura para una lista vacía no califica de esa manera, ya que ya existe una representación perfecta, siendo una lista con cero elementos. Y es una opción técnicamente mala, ya que obliga a cada parte de su código que se ocupa de las listas a verificar la taquigrafía válida null .

Lista vacía

Para un método DeleteItems() , pasar una lista vacía efectivamente significa no hacer nada. Permitiría eso como un argumento, no lanzar una excepción, simplemente regresar rápidamente.

Por supuesto, la persona que llama podría verificar primero los elementos cero y omitir la llamada DeleteItems() en ese caso. Si estamos hablando de una API web, por razones de eficiencia, la persona que llama debería hacerlo para evitar el tráfico innecesario y las latencias de ida y vuelta. Pero no creo que tu API deba hacer cumplir eso.

    
respondido por el Ralf Kleberhoff 24.05.2018 - 12:13
1

Lance una excepción y maneje los nulos en el código de llamada.

Como regla de diseño, intente evitar el valor nulo como valores de parámetros. Reducirá las NullPointerExceptions en general, ya que los nulos realmente serán una excepción.

Además de eso, mira el resto de tu código. Si este es un patrón común en tu proyecto, entonces mantente consistente.

    
respondido por el serprime 24.05.2018 - 09:32
0

En general, las excepciones de lanzamiento deben reservarse para situaciones excepcionales, es decir, si el código no tiene un curso de acción razonable en el contexto actual.

Puedes aplicar ese proceso de pensamiento a esta situación. Dado que se trata de una clase pública con un método público, tiene una API pública y, en teoría, no tiene control sobre lo que se le pasa.

Su código no tiene contexto sobre lo que lo llama (como no debería), y no hay nada que pueda hacer razonablemente con un valor nulo. Esto ciertamente sería un candidato para un ArgumentNullException .

    
respondido por el richzilla 24.05.2018 - 10:24
0

Esta pregunta no parece ser sobre excepciones, sino sobre null como argumento válido.

Por lo tanto, primero y más importante, debe decidir si null es un valor permitido para el argumento de ese método. Si lo es, entonces no necesita una excepción. Si no lo es, entonces necesitas una excepción.

Si desea permitir null , o no, es discutible, como lo demuestran los muchos éxitos de Google al respecto. Lo que significa que no obtendrá una respuesta clara, y depende de la opinión y la tradición en el lugar donde trabaja.

Otra área de discusión es si una función de biblioteca debe ser realmente estricta con respecto a tales cosas, o tan indulgente como sea posible, siempre que no intente "arreglar" parámetros erróneos. Compare esto con el mundo de los protocolos de red, transferencia de correo, etc. (que son contratos de interfaz, al igual que los métodos de programación). Por lo general, la política es que el remitente debe ajustarse lo más estrictamente posible al protocolo, mientras que el receptor debe hacer todo lo posible para poder trabajar con lo que se presente.

Entonces, tienes que decidir: ¿es realmente el trabajo de un método de biblioteca aplicar una política bastante grande como null de manejo? Especialmente si su biblioteca también es utilizada por otras personas (que pueden tener políticas diferentes).

Probablemente me equivocaría al permitir los valores de null , definir y documentar su semántica (es decir, null = empty array en este caso) y no lanzar una excepción, a menos que el 99% de tu otro código similar (código de estilo de "biblioteca") lo hace al revés.

    
respondido por el AnoE 24.05.2018 - 13:28

Lea otras preguntas en las etiquetas