[Php-avanzado] Properties, busco feedback, gracias.

Leonardo Tadei - Pegasus Tech Supply leonardot en pegasusnet.com.ar
Vie Oct 24 20:41:19 ART 2014


Hola Gabriel!


El vie, 24-10-2014 a las 17:53 -0300, Gabriel Nicolás González Ferreira
escribió:
> > 	Bueno... y cómo se supone que tenés código en común en diferentes
> > Objetos si no es por Herencia o por repetir código en un archivo???
> >
> 
> Eso es cierto, solo buscaba como no tener que escribirlo nuevamente en
> la clase que use properties.


	Si no lo vas a escribir de nuevo, la solución es herencia o algún
manejo raro con Inyección de Dependencias.

> > 	Respecto a las "properties", son solamente una invocación
> automática a
> > los getter y setters de un atributo. Desde el punto de: vista del
> > paradigma POO, no aporta ningún concepto nuevo.
> 
> Puede ser, pero yo no dije que aportara nada nuevo, me gustaría
> contarte personalmente porqué en otros lenguajes nos gusta usarlas.
> Hasta a veces tienen un sentido idiomático y casi estético, que para
> vos no debe ser importante pero como yo soy medio artista (no olvides
> que nací en esto como Músico, jejeje). En fin permiten que unifiquemos
> la forma de acceder a los attributos privados sin violar
> encapsulación. Pero hay otras opiniones más interesantes para vos que
> estoy seguro que me las vas a complementar, yo no estoy a favor o en
> contra de los setters y getters:
> 
> http://typicalprogrammer.com/doing-it-wrong-getters-and-setters/
> http://www.javaworld.com/article/2073723/core-java/why-getter-and-setter-methods-are-evil.html


	Ahh!!! El argumento es de optimización... esa cosa que está
documentadísimo que no hay que hacer al principio de un proyecto, sino
al final, porque lo que uno suele creer que tarda en realidad no suele
resultar se un cuello de botella, y otras cosas que no se preveen sí.


> > 	Fijate que los lenguajes de objetos puros no implementan ningún
> > mecanismo para que esto exista (los atributos son privados y se
> acceden
> > mediante setters y getters y punto).
> 
> Claro, PHP no es un lenguaje de objetos puros.


	Lo que no significa que no se pueda implementar POO de forma pura: solo
no hay que usar las cosas que violan el paradigma.
	Cuál es la metodología que querés implementar? y en caso de ser POO,
por qué no querés hacerlo de la forma más prolija posible desde el punto
de vista de ese paradigma?


> > 	Los traits son un mecanismo relativamente nuevo para implementar una
> > especia de herencia múltiple parcial: si usás traits, estás heredando, y
> > es lo que decís que no querés hacer al principio.
> 
> Claro, es una herencia múltiple parcial que me permite evitar el problema de la herencia multiple total, quizás me equivoque en mi expresión, quiero herencia múltiple parcial, ya que el extends de PHP está limitado a herencia de implementación única.

	Sí, pero como no se conoce ningún problema cuya solución requiera
herencia múltiple, no hace falta agregarla para hacer POO.


> CITO el manual de PHP:
> "La semántica a la hora combinar Traits y clases se define de tal
> manera que reduzca su complejidad y se eviten los problemas típicos
> asociados a la herencia múltiple y a los Mixins."

	Claro, la intención es evitar los problemas de la herencia múltiple, y
por eso implementarla en un diseño se considera una mala práctica.
	El lenguaje PHP, como quiere ser muy usado por todos los que se
acerquen, implementa estas cosas y otras muchas para atraer
programadores, y eso para mi está bien.
	Luego queda al criterio de cada uno si vale la pena usarlo o no...

> "Un Trait es similar a una clase, pero con el único objetivo de
> agrupar funcionalidades muy específicas y de una manera coherente. No
> se puede instanciar directamente un Trait. Es por tanto un añadido a
> la herencia tradicional, y habilita la composición horizontal de
> comportamientos; es decir, permite combinar miembros de clases sin
> tener que usar herencia." 

	Una salvedad a esto: cuando dice "permite combinar miembros de clases
sin tener que usar herencia" hay que leer "permite combinar miembros de
clases sin tener que usar la palabra reservada extend", ya que un trait,
al agregar código a una clase, es un mecanismo de herencia.
	El manual habla del lenguaje y sus características, no de buenas
prácticas respecto a un paradigma de programación (y no sería un buen
manual del lenguaje si te dijera eso)


> > 	Por otra parte, no se conoce ningún problema que para ser solucionado
> > en la POO requiera herencia múltiple y por esto los lenguajes de Objetos
> > puros no la implementan.
> 
> Otra vez no estoy hablando de algo en un lenguaje de programación de
> objetos puros.

	Yo tampoco: de lo que estoy hablando es de implementar un Modelo puro
que respete el paradigma de la POO en este lenguaje.

>  Y respecto a la herencia multiple en PHP estaba limitada a la
> herencia de interfaces por eso se puede usar, pasa que está oculta
> bajo la palabrita implements (a bajo nivel es igual a un extend de una
> clase con todos sus métodos virtuales igualados a 0).

	Pero Gabriel! Una interfaz define protocolo, no herencia!
	A bajo nivel no es igual a la herencia, es solo parecida porque define
a los nombres de la interfaz como miembros del espacio de nombres de la
clase.
	La herencia a bajo nivel en PHP, además de declarar el espacio de
nombres, hace la preinterpretación de los métodos y carga en la tabla de
valores los parámetros y las variables pasadas por referencia.

>  Yo se que vos que sos un programador con mucha experiencia y sabés
> que en otro lenguajes puede ser usada,

	Sí, y también puede ser usado el goto(), y se pueden definir todos los
atributos como públicos y otras muchas cosas, como en todo lenguaje
híbrido.

>  te invito a buscar ejemplos de casos de uso en el libro de Bertrand
> Meyer que te pasé hace un año
> (http://en.wikipedia.org/wiki/Object-Oriented_Software_Construction si
> no lo encontrás avisame), pero solo como anécdota porque yo prefiero
> no usar herencia multiple de implementación pero si herencia multiple
> de interface.
> 
> http://es.wikipedia.org/wiki/Problema_del_diamante
> http://es.wikipedia.org/wiki/Herencia_virtual


	El problema del diamante se plantea porque en un escenario de herencia
múltiple, hay que determinar qué método responde si está en las 2
superclases de las que hereda.
	En un lenguaje con herencia simple, este problema no existe...


> > 	PHP también implementa goto
> > http://ar2.php.net/manual/en/control-structures.goto.php lo que está muy
> > bien para un lenguaje.
> > 	Se conocen desde hace décadas los efectos perjudiciales al código de
> > usar saltos incondicionales.
> > 	Lo que está muy mal es que un programador lo use!
> > 
> 
> Por supuesto, también el if puede ser mal utilizado, eso no significa
> que el if sea malo. El infame go to, no es malo en un main.cpp y
> utilizado una sola vez para ir a la salida, jajaja. 


	La tecnología nunca es ni buena ni mala por sí misma.
	El mismo martillo que sirve para poner clavos también sirve para romper
cabezas.
	Si releés lo que puse arriba, vas a ver que nunca digo que el goto()
sea malo (ni los martillos llegado el caso): lo que digo es que si un
programador está haciendo POO, se equivoca al elegir cualquiera de esas
dos herramientas (el martillo y el goto) porque no respetan el paradigma
que eligió usar.
	

> No creo que Alan Kay hubiese podido implementar en la cultura de AT&T
> Smalltalk donde todos ya sabían C,


	Estoy completamente de acuerdo: había un montón de programadores, había
conocimiento de un lenguaje y había un a cultura organizacional. En ese
caso, lo mejor era plantear un híbrido e irlos llevando de a poco del
paradigma PE al POO.

	Lo que no veo es qué tiene que ver esto en tu caso. O te hacen falta
las properties para que muchos programadores que usan PHP haciendo PE se
vayan pasando a la POO y hacerles menos traumático el tener 1 variable
más 2 métodos para usarla???


>  el quería algo nuevo, puro y principalmente orgánico, no olvidemos su
> formación en Biología Molecular que el siempre cita (¡Genial!). Lo
> híbrido fue necesario, parece que los paradigmas en programación se
> violan todo el tiempo, si vos hacés referencia a purismo deberíamos
> hablar de esto en la lista de Smalltalk, no en la de PHP ;).


	No, mi querido Gabriel: tu pregunta es sobre cómo implementar algo en
PHP, y por eso la discusión corresponde a la lista de PHP.
	Como en tu planteo nombrás un montón de técnicas propias de la POO,
debemos asumir que estás queriendo implementar ese paradigma (si no,
simplemente definí los atributos públicos y se acabó el problema!)

	Claro que los paradigmas de programación se violan todo el tiempo!!!
	Pero hay a groso modo dos escenarios de violación: uno es el que no
conoce bien el paradigma e implementa las cosas como mejor le parece;
otro es el que conoce el paradigma y por una necesidad puntual, luego de
sopesar pros, contras e impacto en el diseño, elije violarlo.
	Yo siempre trato de que todos estemos en el 2do escenario, y siempre
que puedo, no estoy en ninguno de los dos: y uso el paradigma prolijito
prolijito...


>  Recuerdo un chiste de Stroustrup: "Existen dos tipos de lenguajes de
> programación: por un lado, aquellos de los que la gente se queja todo
> el tiempo; por otro, los que nadie utiliza."
> 
> Vos me mostraste este sitio una vez:
> http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html y se
> nota que los lenguajes más utilizados son híbridos, eso también puede
> significar también que hasta ahora nadie entendió a esos genios de
> Xerox Parc.


	No Gabriel: estás poniendo de nuevo el carro adelante del caballo. Que
los lenguajes más utilizados sean híbridos, significa que son los que
usa la mayoría de la gente, y no dice absolutamente nada de qué
paradigma o mezcla de ellos usan para trabajar.

	Cuando usás un lenguaje "puro" del paradigma que sea, tenés siempre
menos usuarios, porque lo usan solo los que usan ese paradigma
determinado.


> > 	Pero todo esto es una discusión en el aire: qué problema de diseño
> > estás queriendo resolver que te hace necesaria la implementación de
> > properties???
> > 
> > 
> 
> El desafío de hacer properties era académico, planteado por el mismo
> profesor del chico (Alexander) que publicó ese código. Por supuesto
> que tiene sentido, varios lenguajes las tienen disponible.


	Así que porque varios lenguajes implementen properties la cosa pasa a
tener sentido?
	Desde el punto de vista de quién? Desde lo que hacen el lenguaje seguro
que sí, porque cuanto más cosas soporten, más programadores tendrán.


>  Pero ese sentido puede no ser importante para vos, pero para otros
> sí:
> 
> "Una propiedad es un miembro que proporciona un mecanismo flexible
> para leer, escribir o calcular el valor de un campo privado. Las
> propiedades pueden ser utilizadas como si fueran miembros de datos
> públicos, pero en realidad son métodos especiales llamados
> descriptores de acceso. Esto permite que los datos sean accedidos
> fácilmente y todavía ayuda a promover la seguridad y la flexibilidad
> de los métodos." http://msdn.microsoft.com/es-es/library/x9fsa0sw.aspx


	Mirá, yo usé properties por primeras vez allá por 1994 con Delphi 1.
	Era un mecanismo estrictamente usado por el Inspector de Objetos para
poder interactuar con la Biblioteca de Componentes Visuales (VLC), es
decir, para poder cambiar atributos de un componente de pantalla y ver
como va quedando la ventana simultáneamente.
	En ese contexto, siempre me pareció y me sigue pareciendo una solución
muy elegante respecto a la alternativa, que hubiera sido tener una regla
fija para los nombres de los setters y los getters, es decir, de las 2
soluciones, las properties son por mucho la mejor.

	Ahora bien: si no hay un problema concreto que dé contexto al uso de
una forma de escribir el código o a otra, pareciera como una violación
de la POO innecesaria.

	Querés comodidad y no escribir setters y getters? Hacé esto:


class Algo {

//  --------- bloque ---------------
    private $v = array();

    function __set($varName, $varValue) {
        $this->v[$varName] = $varValue;
    }

    function &__get($varName) {
        if(!isset($this->v[$varName]))
            $this->v[$varName] = NULL;
        return $this->v[$varName];
    }
//  --------- fin bloque ---------------
}

$o = new Algo();

$o->nombre = "Leo";
$o->paradigma = "POO";

print "{$o->nombre} perfiere {$o->paradigma}";


	También podés poner el pedazo de código marcado como "bloque" en un
archivo aparte y con un include() usarlo en todas tus clases: lo tenés
escrito una sola vez, funciona, y no usás herencia... si es por aplicar
soluciones fuera del paradigma de la POO, esta es muy simple y cómoda de
implementar!

class Sueldo{
	include('bloque.php');

	function __construct(){ ... }
	// etc
	// ...
	// etc
}


> ¡Muchísimas gracias por todo lo que me comentaste que me hizo pensar
> un montón y leer más para contestarte!
> 
> ¡Abrazos!

	=mente!


-- 
Leonardo Tadei
leonardot en pegasusnet.com.ar
Web: http://leonardo.tadei.com.ar
Firma pública: http://www.pegasusnet.com.ar/LeonardoTadei-public.key



Más información sobre la lista de distribución Php-avanzado