optimization setter getter verification

optimization - ¿Verificaciones de datos en Getter/Setter o en otro lugar?



verification (8)

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

Si tienes un Número que puede estar entre 1 y 100, definitivamente pondré algo en el colocador que valide eso y luego quizás arroje 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í:

"Deberíamos olvidarnos de pequeñas eficiencias, digamos el 97% de las veces: la optimización prematura es la raíz de todo mal".

Me pregunto si es una buena idea hacer verificaciones en getters y setters , o en otra parte del código.

Esto puede sorprenderle cuando se trata de optimizar y acelerar el código, creo que no debe hacer verificaciones en getters y setters, sino en el código donde está actualizando sus archivos o base de datos. ¿Me equivoco?


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.


Es posible que desee ver Domain Driven Design , por Eric Evans. DDD tiene esta noción de una especificación:

... OBJETOS DE VALOR similares a predicados explícitos para fines especializados. UNA ESPECIFICACIÓN es un predicado que determina si un objeto satisface o no algunos criterios.

Creo que fallar rápido es una cosa, y el otro 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.


La validación se debe capturar 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 se debe utilizar 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, ya que la información sobre el objeto ya es confiable.

¡No guarde su validación hasta que se actualice la base de datos! Es mejor fallar rápido .


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, para esto están diseñadas las propiedades. Si todo lo que tienes es un conjunto de propiedades como ...

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

... bien podrían ser campos


Me gusta implementar IDataErrorInfo y poner mi lógica de validación en su Error y estas propiedades [columnName]. De esta forma, si desea comprobar 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 de Windows o WPF.

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


@Terrapin, re:

Si todo lo que tienes es un conjunto de propiedades [set / get públicas simples] ... podrían ser también campos

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.


Intento que nunca deje 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.