2010-05-27 21 views
22

usamos ASP.NET con C# y en base a proyectos/artículos de código abierto que pasé, encontré muchas propiedades incluyendo lógica pero cuando lo hice el equipo- El líder me dijo que no es bueno colocar la lógica dentro de las propiedades, pero llamar a la lógica a través de métodos ...¿Es una buena práctica implementar lógica en las propiedades

¿eso es realmente malo? y por qué no usar la lógica en las propiedades?

gracias,

+0

En realidad, el líder del equipo estaba hablando de no poner la lógica en la parte getter! por lo que refactorizar mi propiedad "extracto de método" durante la revisión de la tarea. –

Respuesta

32

Se espera que el acceso a la propiedad sea instantáneo (no largas esperas), coherente (sin valores cambiantes) y seguro (sin excepciones). Si puede hacer esas garantías, creo que poner lógica en las propiedades está bien.

+1

Por consistente, ¿se refiere a [idempotent?] (Http://en.wikipedia.org/wiki/Idempotence) –

+11

Las excepciones son correctas para los instaladores, si alguien está intentando establecer un valor ilegal. – Thorarin

+0

Idempotent se aplicaría, creo. Estoy de acuerdo con las excepciones sobre los incubadores, pero creo que definitivamente no debería lanzar una excepción en un getter. –

28

Está bien tienen alguna la lógica de las propiedades. Por ejemplo, la validación de argumentos en setters y el cálculo lento en getters son bastante comunes.

Es generalmente una mala idea para un acceso a la propiedad para hacer algo costoso, como una llamada a la base de datos, sin embargo. Los desarrolladores tienden a suponer que las propiedades son razonablemente baratas de evaluar.

Es una decisión final al final, pero ciertamente rechazo la sugerencia de que las propiedades solo sean triviales en la medida en que puedan implementarse con propiedades automáticas.

+0

Estoy de acuerdo con la respuesta, pero ¿qué sucede con las situaciones basadas en datos en las que un 'Producto' tiene un' Proveedor' y un 'Proveedor' tiene una colección de' Productos'. ¿Debes cargar esas entidades relacionadas durante la construcción del objeto? ¿Primer acceso a la propiedad? ¿O no se debe acceder a ellos a través de las propiedades debido a las trampas que presenta cualquiera de las opciones? –

+0

@Anthony: no creo que la carga de las propiedades en el objeto sea responsabilidad del objeto en sí, sino la responsabilidad de su capa de acceso a datos o ORM. – tvanfosson

+0

@Anthony: Por eso pongo "habitualmente" :) Cosas como Linq to Sql pueden hacer este tipo de cosas, pero espero que los desarrolladores sepan que están tratando con objetos vinculados a ORM. Aunque no es el tipo de cosa que quisiera ver por todos lados. –

9

Properties are methods. Son solo atajos para getter/setters. Cualquier lógica que sería válida en un getter/setter es razonable para poner en una propiedad. Cualquier lógica que normalmente no pondría en un getter/setter sería inapropiado para poner en una propiedad. En términos generales, si usted (como consumidor de la clase) no puede esperar de manera razonable que establecer un valor de propiedad, o incluso peor, obtener un valor de propiedad pueda provocar un comportamiento, entonces esa lógica probablemente pertenezca a otra parte. En otras palabras, la lógica debe estar relacionada y ser consistente con obtener o establecer la propiedad.

citando el artículo enlazado más arriba:

Las propiedades son los miembros que proporcionan un mecanismo flexible para leer, escribir o calcular los valores de los campos privados. Las propiedades se pueden usar como si fueran miembros de datos públicos, pero en realidad son métodos especiales llamados accesos . Esto permite que los datos sean accedidos fácilmente mientras se proporciona la seguridad y flexibilidad de los métodos.

+0

¿Qué tipo de lógica es válida en un getter/setter? –

+1

@Robert: es difícil dar una definición completa, pero debería pasar la prueba del olfato. Por ejemplo, es razonable esperar que cambiar el precio o la cantidad de un pedido cambie su costo. No esperaría que cambie el proveedor desde el que se entrega. – tvanfosson

+0

Estoy de acuerdo, en principio, aunque escribí clases que leen archivos de texto, donde establecer una propiedad en particular rebobinó el archivo al principio (porque de lo contrario, al establecer esa propiedad concreta, el lector de archivos pasaría a un estado inválido). –

4

Aquí se aplica una respuesta común: Depende.

En general, no es una buena idea implementar negocio lógica en getters y setters. Si su objeto es un DTO (objeto de transferencia de datos) simple, esto violaría la Responsabilidad individual.

Sin embargo, la lógica de seguimiento de estado y otras tareas domésticas a menudo se encuentran en las propiedades. Por ejemplo, las entidades de auto-seguimiento de Entity Framework 4 tienen lógica de administración de estado en cada sistema de propiedad primitivo para permitir el seguimiento.

Una alternativa a la lógica en las propiedades es la Programación Orientada a Aspectos (AOP). Usando AOP, puede "inyectar" lógica entre los objetos y el proceso de alojamiento.El acceso a los objetos puede ser "interceptado" y manejado condicionalmente.

+0

De acuerdo, usted resumió lo que estaba pensando. :) En un proyecto de mascota pequeña que tengo, incluí un poco de lógica en la propiedad de una "Player" class para configurar el equipo de un jugador en el juego. Primero verifica para asegurarse de que el equipo actual del jugador y el nuevo "valor" del equipo no sea el mismo y luego envía un comando de consola para cambiar el equipo del jugador al "valor". – Zack

0

Por lo general, una propiedad solo afecta a 1 variable, ya que se hizo principalmente para ese fin. Pero en algún momento, desea una propiedad de más alto nivel que no sea solo una variable de 1 a 1. Entonces, en este caso, es normal que contenga código. Pero debe tener en cuenta que una propiedad no está destinada a ser utilizada como una función. Cuando llamas a una función, sabes que hará algo de procesamiento. Cuando llamas a una propiedad, esperas que sea rápida.

Pero, por último, es una cuestión de preferencias, y al igual que el estándar de codificación, lo que su superior le está diciendo es a su discreción. Entonces no está mal y depende de tu juicio.

0

En mi opinión, la lógica de negocios solo está permitida en Setter/Getter en ciertas situaciones. Por ejemplo: se permite poner la lógica que es responsable de validar la entrada, porque los instaladores son responsables de mantener el estado del objeto, por lo que no se debe violar el estado. Por lo tanto, debe cortar esa lógica comercial a la porción más pequeña de código que es responsable solo de un tema.

La otra cosa es que su clase debería estar (en la mejor situación) POCO. ¿Por qué? Porque debe ser reutilizable y cuando la clase contiene lógica en Propiedades, la reutilización se puede bloquear simplemente. Piensa que tienes SqlServerPerson con alguna validación de SQLServer en propiedades, entonces puede ser difícil reemplazarlo, por ejemplo, con NHibernatePerson cuando cambias el acceso ORM/DB.

1

Poner la lógica comercial en un setter puede ocasionarle problemas si alguna vez necesita serializar/deserializar sus objetos con JSon, XML o un ORM. Un ejemplo de esto puede ser cuando se usa un almacén de datos NoSql como una base de datos de documentos o un ORM. Algunos de estos (por ejemplo, NHibernate) se pueden configurar para acceder a los campos de respaldo en lugar de al colocador.

Me parece que usar un Getter público y un setter privado junto con un método para establecer el valor con una lógica adicional según se requiera es un buen enfoque. La mayoría de los serializadores pueden acceder al setter privado, por lo que lo que se obtiene es una representación precisa del objeto persistente sin una lógica de disparo accidental que podría potencialmente cambiar los valores incorrectamente al deserializarse.

Sin embargo, si no crees que alguna vez habrá una necesidad de serializar/deserializar, entonces esto no debería ser un problema.

1

En mi opinión, esto está absolutamente bien. De la forma en que lo veo, la única justificación para tener propiedades como característica de idioma es que puedes tener lógica en ellas. De lo contrario, también puede permitir el acceso directo a los miembros de datos subyacentes.

+1

Kinda siempre pensó lo mismo: los modificadores de acceso es una razón más, y la declaración explícita para incrustar la lógica en él ... Obviamente teniendo en cuenta el contexto de la clase ... –

Cuestiones relacionadas