2008-08-05 16 views
8

Me pregunto si es una buena idea para hacer verificaciones en captadores y setters, o en otra parte del código.¿Verificaciones de datos en Getter/Setter o en otro lugar?

Esto puede sorprender a ser cuando se trata de optimizaciones y exceso de velocidad el código, creo que no se debe hacer verificaciones en los captadores y definidores, pero en el código en el que está actualizar sus archivos o base de datos. ¿Me equivoco?

Respuesta

12

Bueno, uno de los motivos por los que las clases suelen contener miembros privados con getters/setters públicos es exactamente porque pueden verificar los datos.

Si tiene un número que puede estar entre 1 y 100, definitivamente pondré algo en el colocador que valida eso y luego podría lanzar una excepción que está siendo atrapada por el código. La razón es simple: si no lo hace en el colocador, debe recordar esa limitación de 1 a 100 cada vez que lo configura, lo que conduce a un código duplicado o cuando lo olvida, lo lleva a un estado no válido.

En cuanto a rendimiento, estoy con Knuth aquí:

"Debemos olvidarnos de pequeñas eficiencias, por ejemplo alrededor del 97% del tiempo:. Optimización prematura es la raíz de todo mal"

1

La validación debe capturarse por separado de getters o setters en un método de validación. De esta forma, si la validación debe reutilizarse en múltiples componentes, está disponible.

Cuando se llama al colocador, dicho servicio de validación debe utilizarse para desinfectar la entrada al objeto. De esta forma, usted sabe que toda la información almacenada en un objeto es válida en todo momento.

No necesita ningún tipo de validación para el captador, porque la información sobre el objeto ya es confiable.

¡No guarde su validación hasta que se actualice la base de datos! Es mejor fail fast.

+0

¿Podría dar más detalles? ¿Estás diciendo, por ejemplo, que compruebes <5 && > 0 en un método de validación independiente? Entonces, ¿qué están haciendo exactamente sus getters y setters que un campo regular no hace? –

3

Desde la perspectiva de tener el código más fácil de mantener, creo que debe hacer la mayor validación posible en el establecimiento de una propiedad. De esta forma, no almacenará en caché ni tratará datos inválidos.

Después de todo, esto es para lo que están diseñadas las propiedades. Si todo lo que tiene es un montón de propiedades como ...

public string Name 
{ 
    get 
    { 
     return _name; 
    } 
    set 
    { 
     _name = value; 
    } 
} 

... que bien podría ser campos

3

depende.

En general, el código debe fallar rápidamente. Si el valor puede establecerse mediante múltiples puntos en el código y solo se valida después de recuperar el valor, el error parece estar en el código que realiza la actualización. Si los setters validan la entrada, sabrá qué código intenta establecer valores no válidos.

1

Quizás quieras echar un vistazo a Domain Driven Design, por Eric Evans.DDD tiene esta noción de una Especificación:

... tipo predicado explícito VALOR OBJETOS para fines especializados. Una especificación es un predicado que determina si un objeto hace o no no cumple algunos criterios.

Creo que una cosa es fallar rápido y la otra es dónde mantener la lógica para la validación. El dominio es el lugar correcto para mantener la lógica y creo que un Objeto de especificación o un método de validación en los objetos de tu dominio sería un buen lugar.

1

Me gusta implementar IDataErrorInfo y poner mi lógica de validación en su Error y estas propiedades [columnName]. De esta forma, si desea verificar mediante programación si hay un error, simplemente puede probar cualquiera de esas propiedades en el código, o puede pasar la validación al enlace de datos en formularios web, formularios Windows Forms o WPF.

La propiedad de enlace "ValidatesOnDataError" de WPF lo hace particularmente fácil.

4

@Terrapin, re:

Si todo lo que tiene es un montón de propiedades [sencilla conjunto público/get] ... que bien podría ser campos de

Las propiedades tienen otras ventajas sobre los campos. Son un contrato más explícito, están serializados, pueden depurarse más tarde, son un buen lugar para la extensión a través de la herencia. La sintaxis de clunkier es una complejidad accidental: .net 3.5, por ejemplo, supera esto.

Una práctica común (y defectuosa) es comenzar con campos públicos y convertirlos en propiedades más adelante, según sea necesario. Esto rompe su contrato con cualquiera que consuma su clase, por lo que es mejor comenzar con las propiedades.

1

Intento nunca dejar que mis objetos entren en un estado inválido, por lo que los setters definitivamente tendrían validación, así como también cualquier método que cambie el estado. De esta forma, nunca tengo que preocuparme de que el objeto con el que estoy tratando no sea válido. Si mantiene sus métodos como límites de validación, nunca tendrá que preocuparse por los marcos de validación y las llamadas al método IsValid() salpicadas por todos lados.

Cuestiones relacionadas