2010-10-17 14 views
5

Últimamente he encontrado el patrón de diseño Objeto nulo y mis colegas dicen que se puede utilizar para eliminar las comprobaciones de puntero nulo que se encuentran en todo el código.Patrón de objeto nulo para evitar las comprobaciones nulas?

por ejemplo, supongamos que una clase DAO devuelve información sobre el cliente (en un objeto de valor denominado CustomerVO). Se supone que mi clase principal debe extraer el firstName y el emailId y enviar un correo electrónico al cliente.

... 
CustomerVO custVO = CustomerDAO.getCustomer(customerID); 
if(custVO != null) { // imp, otherwise we may get null ptr exception in next line 
    sendEmail(custVO.getFirstName(), custVO.getEmailID()); 
} 
... 

Esto es muy simple ejemplo, pero tales cheques nulos pueden propagarse rápidamente a través de su código basado en la complejidad de los objetos de valor.

Tengo dos problemas con el registro de entrada nula, - tienden tmake el código feo y difícil de leer - menos experimentados desarrolladores ponen cheques nulos innecesarios cuando en realidad se supone que lanzar excepciones. por ej. en el código anterior, sería mejor emitir una excepción de getCustomer() en sí mismo porque si no puede encontrar información del cliente para CustID dado, indica que CustID no es válido.

bien, volviendo al patrón de objeto nulo, ¿podemos usar un objeto CustomerVO 'nulo' para ocultar la verificación nula?

CustomerVO { 
    String firstName = ""; 
    String emailID = ""; 
} 

No tiene sentido. ¿Qué piensas?

Y cuáles son las cosas que debe seguir para minimizar las comprobaciones nulas en su aplicación.

Respuesta

2

En este caso, un objeto nulo puede ser inapropiado ya que el valor predeterminado puede de hecho ocultar lo que en realidad es una excepción. Si tiene que verificar si tiene nulo seguro para realizar alguna otra actividad, el patrón nulo no le comprará nada.

Como dijiste, muchos desarrolladores nuevos pasan tiempo tratando de proteger su código de situaciones de excepción que son peores que un programa de interrupción.

3

Si bien el patrón de objeto nulo tiene su uso, igual va a necesitar marcar aquí, de lo contrario, intentará sendEmail() a una dirección de correo electrónico que sea la cadena vacía (o presione el cheque hacia sendEmail(), que también podría comprobar fácilmente para null).

Donde el patrón de objeto nulo sería realmente útil aquí es si la clase CustomerVO implementó el método sendEmail(). a continuación, simplemente podría encadenar las llamadas entre sí, ya que el contrato de getCustomer() se aseguraría de que no sería devuelto una referencia null:

CustomerDAO.getCustomer(customerID).sendEmail(); 

En ese caso, el método sendEmail() comprobaría que su ha pedido a actuar en el especial 'objeto nulo' y simplemente no hacer nada (o lo que sea apropiado).

+1

+1, aunque no me gustaría que mis clientes tienen métodos sendEmail.Eso solo le está dando demasiadas responsabilidades a un cliente. Es como dar a cada clase un método de "impresión" y tener que implementar la lógica de impresión en todas partes o hacer que cada clase dependa de un administrador de impresión, mientras que podría restringirse a un administrador de impresión y los formularios/clases que realmente inician la impresión dando al administrador de impresión las clases para imprimir. Donde el patrón nulo es realmente bueno, está en pruebas unitarias, por ejemplo, para proporcionar una clase de registro que no hace nada, por lo que no es necesario modificar el código que se prueba. –

1

¿Debería su método getCustomer lanzar una excepción si no se encuentra el cliente, en lugar de devolver el valor nulo?

La respuesta, por supuesto, es que depende: ¿debería casi nunca ser el caso de que la identificación del cliente no exista? En otras palabras, ¿es una circunstancia excepcional? Si es así, una excepción es apropiada.

Sin embargo, en una capa de acceso a datos a menudo es bastante normal que algo no exista.En ese caso, es mejor no lanzar, ya que no es una circunstancia excepcional e inesperada.

El 'devolver un objeto no nulo que tiene campos vacíos' probablemente no sea mejor. ¿Cómo se puede saber si el objeto devuelto es "válido" o no sin agregar ahora algún código de comprobación que probablemente sea peor que la verificación nula?

Por lo tanto, si puede ser un estado normal que algo que se está buscando no existe, el patrón de verificación nula es probablemente el mejor. Si es algo inesperado, entonces tener el método de acceso a datos lanzar una excepción NotFound es probablemente mejor.

+0

Vea mi respuesta, si algo no puede existir, tenga un método que verifique si existe. De esta forma, solo necesita lanzar excepciones donde sea excepcional. – nicodemus13

1

Tengo un problema con este tipo de código, que es un patrón común. No necesita los controles nulos en absoluto si descompone lo que realmente está haciendo. El problema aquí, en mi opinión, es que estás violando SRP.

El método CustomerVO custVO = CustomerDAO.getCustomer(customerID); hace dos cosas.

En primer lugar devuelve un cliente, si el cliente existe y en segundo lugar devuelve nulo si no hay tal cliente. Estas son dos operaciones distintas y deben codificarse como tales.

Un mejor enfoque sería:

bool customerExists = CustomerDAO.exists(customerID); 

if (customerExists) 
{ 
    CustomerVO custVO = CustomerDAO.getCustomer(customerID); 
    sendEmail(custVO.getFirstName(), custVO.getEmailID()); 
} 
else 
{ 
    // Do whatever is appropriate if there is no such customer. 
} 

}

Por lo tanto, el método de dividir en dos, uno que comprueba si existe el objeto solicitado y el segundo que en realidad lo recupera. No es necesaria ninguna excepción y el diseño y la semántica son muy claros (lo cual, en mi opinión, con un patrón does-not-exists-returns-null no lo es). Además, en este enfoque, el método CustomerDAO.getCustomer(customerID) arroja un ArgumentException, si el cliente solicitado no existe. Después de todo, ha pedido un Customer y no hay uno.

Futhermore, en mi opinión, ningún método debería devolver null. Null es explícitamente, 'No sé cuál es la respuesta correcta, no tengo valor para devolver'. Null no es un significado, es falta de significado. Pregúntese a sí mismo, '¿por qué estoy devolviendo algo que sé que en realidad no debería suceder? Su método GetCustomer debería devolver un Customer obviamente. Si devuelve null, simplemente está presionando la responsabilidad de qué hacer una copia de seguridad de la cadena de llamadas y rompiendo el contrato. Si hay un valor predeterminado significativo, úsalo, pero lanzar una excepción aquí puede hacerte pensar un poco más acerca de cuál es el diseño correcto.

0

El nombre es el patrón de diseño de objetos NULL y no el patrón de diseño de verificación NULL. El objeto nulo significa la ausencia de un objeto. Esto debería usarse cuando tienes objetos trabajando en COLABORACIÓN. En su caso, está comprobando la existencia de un objeto para el cual la comprobación NULL debería estar bien.

El patrón de diseño NULL no está destinado a reemplazar el manejo de excepciones NULL. Es uno de los beneficios secundarios del patrón de diseño NULL pero la intención es proporcionar un comportamiento predeterminado.

Las comprobaciones NULL no deben reemplazarse con objetos de patrón de diseño NULO, ya que pueden ocasionar defectos silenciosos en la aplicación.

Consulte el artículo a continuación que contiene detalles del patrón de diseño DO y Don de NULO.

http://www.codeproject.com/Articles/1042674/NULL-Object-Design-Pattern

Cuestiones relacionadas