En los lenguajes que se basan en getters y setters, como Java, no se supone ni se espera que hagan nada más que lo que dicen. Sería sorprendente que x.getB()
hiciera algo más que devolver el valor actual del atributo lógico b
, o si x.setB(2)
hizo algo más que cualquier pequeña cantidad de trabajo interno que se necesita para hacer x.getB()
return 2
.
Sin embargo, no hay garantías lingüísticas impuestas acerca de este comportamiento esperado, es decir, las limitaciones del compilador-forzada en el cuerpo de métodos cuyos nombres comienzan con get
o set
: más bien, se deja hasta el sentido común, las convenciones sociales , "guías de estilo" y pruebas.
El comportamiento de x.b
accesos y las asignaciones tales como x.b = 2
, en los idiomas que sí tienen propiedades (un conjunto de idiomas que incluye pero no se limita a Python) es exactamente el mismo que para los métodos getter y setter en, por ejemplo, Java: las mismas expectativas, la misma falta de garantías impuestas por el lenguaje.
El primer triunfo de las propiedades es la sintaxis y la legibilidad. Tener que escribir, por ejemplo,
x.setB(x.getB() + 1)
en lugar de lo obvio
x.b += 1
clama venganza a los dioses. En los idiomas que admiten propiedades, no hay absolutamente ninguna buena razón para obligar a los usuarios de la clase a pasar por los giros de dicho modelo bizantino, lo que afecta la legibilidad de su código sin ninguna ventaja.
En Python específicamente, hay una ventaja adicional al usar propiedades (u otras descripciones) en lugar de getters y setters: si reorganiza su clase para que el setter y getter subyacentes ya no sean necesarios, puede (sin romper la API publicada de la clase) simplemente elimine esos métodos y la propiedad que se basa en ellos, haciendo que b
sea un atributo "almacenado" normal de la clase x
en lugar de uno "lógico" obtenido y establecido computacionalmente.
En Python, hacer cosas directamente (cuando sea factible) en lugar de mediante métodos es una optimización importante, y el uso sistemático de propiedades le permite realizar esta optimización siempre que sea posible (siempre exponiendo "atributos almacenados normales" directamente, y solo necesita cálculo en el acceso y/o configuración a través de métodos y propiedades).
Por lo tanto, si se utiliza captadores y definidores en lugar de propiedades, más allá de afectar la legibilidad del código de sus usuarios, que son también gratuitamente malgastar recursos de la máquina (y la energía que va a su equipo durante los ciclos ;-) , otra vez sin ningún motivo justificado.
Su único argumento en contra de las propiedades es, p. que "un usuario externo no esperaría ningún efecto secundario como resultado de una asignación, por lo general"; pero te pierdes el hecho de que el mismo usuario (en un lenguaje como Java donde getters y setters son omnipresentes) no esperaría (observables) "efectos secundarios" como resultado de llamar a un setter, tampoco (y aún menos por un getter) ;-). Son expectativas razonables y depende de usted, como autor de la clase, intentar acomodarlas, ya sea que su setter y getter se usen directamente o a través de una propiedad, no hace ninguna diferencia. Si tiene métodos con importantes efectos secundarios observables, haga no nómbrelos getThis
, setThat
, y no los utilice a través de propiedades.
La queja de que las propiedades "esconden la implementación" es totalmente injustificada: más todo de programación orientada a objetos es sobre la implementación de ocultación de información - haciendo una clase responsable de presentar una interfaz lógica con el mundo exterior e implementar internamente como mejor poder. Getters y setters, exactamente como propiedades, son herramientas para alcanzar este objetivo. Las propiedades solo hacen un mejor trabajo (en los idiomas que los admiten ;-).
Lo entendiste mal. .setB() es un parche para idiomas que no tiene propiedades reales. Python, C# y algunos otros tienen propiedades, y la solución es la misma. – liori
He visto a chicos de Java algo peor, que es escribir getters y setters para cada atributo, por si acaso, porque es un esfuerzo refaccionarlo todo más tarde. –
@gnibbler, en lenguajes que no admiten propiedades (o al menos posibilidades algo equivalentes como '__getattr__' de Python' '' '' '' '' '' '' '' '' 'heredadas''), no hay mucho más" tipos de Java "(en ninguno de esos idiomas, incluyendo C++! -) posiblemente, para preservar la encapsulación. –