2010-12-26 32 views
16

¿Es una mala práctica pasar el argumento NULL a métodos o en otras palabras deberíamos tener definiciones de métodos que permitan el argumento NULL como argumento válido?¿Los argumentos NULL son una mala práctica?

Supongamos que quiero dos métodos 1. para recuperar la lista de todas las empresas 2. para recuperar la lista de empresas según el filtro.

cualquiera Podemos tener dos métodos como el de la siguiente manera

List<Company> getAllCompaniesList(); 
    List<Company> getCompaniesList(Company companyFilter); 

o podemos tener un único método

List<Company> getCompaniesList(Company companyFilter); 

aquí en el segundo caso, si el argumento es NULL entonces lista de regreso método para todos compañías.

Al lado de la cuestión de las buenas prácticas, prácticamente veo un problema más con el enfoque posterior que se explica a continuación.

Estoy implementando Spring AOP, en el que quiero tener algunos controles sobre argumentos como 1. ¿Es argumento NULL? 2. es el tamaño de la colección 0?

Hay algunos escenarios en los que no podemos tener argumento nulo en absoluto como para el método

void addBranches(int companyId, List<Branch>); 

Esta comprobación se puede realizar muy bien mediante el uso de primavera AOP mediante la definición de método como seguir

@Before(argNames="args", value="execution(* *)") 
void beforeCall(JoinPoint joinPoint ,Object[] args) 
{ 
      foreach(Object obj in args) 
      { 
       if(obj == NULL) 
       { 
        throw new Exception("Argument NULL"); 
       } 
      } 
} 

Pero el problema al que me enfrento es que he definido algunos de los métodos que deberían aceptar el argumento NULL para la funcionalidad múltiple de un único método, como se mencionó anteriormente para el método List getCompaniesList (Company companyFilter); Así que no puedo aplicar el AOP uniformemente para todos los métodos y ninguna de las expresiones para la coincidencia de nombres de métodos será útil aquí.

Háganme saber si se requiere más información o el problema no es lo suficientemente descriptivo.

Gracias por leer mi problema y pensar en ello.

+1

Es una cuestión de estilo. No hay una sola respuesta correcta. –

Respuesta

14

Está bien, en los casos en que hay demasiados métodos sobrecargados. Entonces, en lugar de tener todas las combinaciones de parámetros, permite que algunos de ellos sean null. Pero si lo hace, documentar esto explícitamente con

@param foo foo description. Can be null 

En su caso tendría los dos métodos, cuando la primera de ellas invoca el segundo con un argumento null. Hace que la API sea más útil.

No hay una línea estricta donde detener la sobrecarga y dónde empezar a confiar en los parámetros que aceptan nulos. Es una cuestión de preferencia. Pero tenga en cuenta que, por lo tanto, su método con la mayoría de los params permitirá que algunos de ellos se puedan anular, así que documente esto también.


También tenga en cuenta que una forma preferida de hacer frente a múltiples parámetros de constructor es a través de un generador. Así que en lugar de:

public Foo(String bar, String baz, int fooo, double barr, String asd); 

donde cada uno de los argumentos es opcional, se puede tener:

Foo foo = new FooBuilder().setBar(bar).setFooo(fooo).build(); 
+0

Pero, entonces tenemos que crear un método por parámetro (a menos que agrupemos algunos parámetros en un objeto, por ejemplo, string username, string password = object user). Es útil y bonito, pero ¿no es demasiado código? Además, henning77 dice que no está bien desde una perspectiva práctica debido a todos los NPE que podría causar. – testerjoe2

5

Es una práctica común, pero hay formas de hacer que su código sea más claro, evitando las comprobaciones nulas a veces, o moviéndolos a otro lugar. Busque el patrón de objeto nulo: puede ser exactamente lo que necesita: http://en.m.wikipedia.org/wiki/Null_Object_pattern?wasRedirected=true

+0

Gracias, ¿pueden proporcionarnos algunos enlaces buenos si ya lo saben? –

+0

Sí, se editará ... –

+0

El patrón de objeto nulo puede ser útil para algunos escenarios, como devolver colección, en todos los casos, como en el caso de que su único objeto devuelva NULL. –

2

La regla es: interfaz simple, complicado aplicación.

Las decisiones de diseño sobre su API deben tomarse teniendo en cuenta cómo es probable que el código de cliente lo use. Si usted espera ver ya sea

getAllCompaniesList(null); 

o

if (companyFilter == null) { 
    getAllCompaniesList(); 
} else { 
    getAllCompaniesList(companyFilter); 
} 

entonces estás haciendo mal. Si el posible caso de uso es que el código del cliente, en el momento en que está escrito, tenga o no filtro, debe proporcionar dos puntos de entrada; si esa decisión probablemente no se realiza hasta el tiempo de ejecución, permita un argumento nulo.

13

que utiliza una regla muy simple:

Nunca permita nulo como un argumento o valor de retorno de un método público.

Hago uso de Optional y Preconditions o AOP para hacer cumplir esa regla. Esta decisión ya me ahorró muchas horas de corrección de errores después del comportamiento extraño o de NPE.

+0

Grandes enlaces! Como programador experimentado que está ganando más alfabetización en Java, esto es muy útil. – Duke

+0

'setLocationRelativeTo (null);' ... Desearía que Sun/Oracle supiera que es una mala práctica. – Stepan

+0

Pero Bozho dice que está bien permitir argumentos nulos a veces. ¿Estarías de acuerdo? – testerjoe2

0

Otro enfoque que puede ser viable puede ser tener una interfaz CompanyFilter con un método que acepta un companyIsIncluded(Company)Company y devuelve verdadero o falso decir si una empresa debe ser incluido. Company podría implementar la interfaz para que el comportamiento del método companyIsIncluded refleje equals(), pero uno podría tener fácilmente un singleton CompanyFilter.AllCompanies cuyo método companyIsIncluded() siempre devolvería verdadero. Usando ese enfoque, no hay necesidad de pasar un valor nulo, simplemente pase una referencia al singleton AllComapnies.

Cuestiones relacionadas