22-02-2008 Disclaimer: Este es un post computronico. Si esperan algo mas terricola salteen este post.Leyendo la lista de internals de PHP (version web: http://news.php.net/php.internals) Stefan Marr mando un patch mas que interesante.
Se trata de una implementacion de Traits para PHP.
Pero qué son traits?
Traits son básicamente Behavioral Blocks (en castellano, bloques de comportamiento) que engloban "funcionalidad" (lo pongo entre comillas porque en realidad engloban funciones).
En general estamos acostumbrados (o no, depende del lenguaje de programación...) a usar interfaces y hacer que nuestras jerarquías de clase implementen esas interfaces. Por ejemplo: (en algún lenguaje de programació que se lo banque)
Interface LaInterface
{
public void metodo1();
public int metodo2();
...
}
interface LaInterface
{
public void metodoA();
public int metodoB();
...
}
class LaClase implements LaInterface, LaOtraInterface
{
/* Aca deben estar implementados todos los
* metodos de LaInterface y LaOtraInterface
*/
}
Pero qué pasa con las jerarquías de clases? A veces tenemos que elegir entre un diseño elegante y bien objetoso, respetando los conceptos que aprendimos en
OOP (o_O) como abstracción, encapsulamiento, bajo acoplamiento, polimorfismo, etc. (debo admitir que los tuve que buscar... ya que no me los acordaba...) que respete el problema a modelar o bien, hacer un codigo mas pulenta y que sea mas reusable faltando un poquito nomas, a los principios puristas de la OOP.
Entonces tenemos jerarquías de clases, donde hay clases que extienden a otras, creando familias complejas de padres con hijos herederos de algunos metodos que pueden modificar, o no, visibles dentro de la familia, privados a la clase o publicos al mundo en general...
Pero a veces, tenemos funcionalidades que queremos que muchas familias disfruten, por ejemplo: queremos que todas sepan hacer
asado, sean del origen que sean... ya que viven en
Argentina.
Entonces supongamos el siguiente ejemplo:

Acá tenemos una jerarquí (no muy util por cierto) que modela familias, de distinto origen. Todas las familias tienen un apellido, y saben tener hijos (espero sepan entender el propósito ilustrativo del ejemplo).
Entonces las familias saben cocinar diferentes tipos de comidas, dependiendo de donde son originarios. En el caso de los tanos: cocinar pasta, risotto y canoli. Los japoneses cocinan sushi y saben tomar sake y los argentinos, sabemos hacer asado, tomar mate e ir a la cancha (yo no, no voy a la cancha :D).
Pero estaría bueno que cualquier familia que viva en argentina sepa cocinar asado y tomar mate (lo mismo vale para cualquier actividad...). Entonces podemos hacer un "paquetito", o Trait (que ni por asomo se parece a un package) con distintas "habilidades". Por ejemplo:
trait CostumbresArgentinas
{
public void cocinarAsado(){
// codigo para cocinar asado...
}
public void tomarMate(){
// codigo para tomar mate...
}
}
Entonces podriamos tener una clase por ejemplo:
class FamiliaItaliana
{
use CostumbresArgentinas;
public void cocinarRisotto(){...}
public void cocinarPasta(){...}
public void cocinarCanoli(){...}
}
Y tener facilmente una familia italiana que tiene costumbres argentinas (raro no???).
A mi me gusta pensar en una forma de atravesar una jerarquía de clases de manera horizontal, como intento mostrar en este dibujo (click para agrandar):

Traits para PHP
Hay muchos detalles con que lidiar, por ejemplo los conflictos. Qué pasa si 2 traits tienen métodos con igual nombre? quién los rsuelve?
En esta primer implementacion para PHP, los traits son "Aplanados" dentro del c&código de la clase, el propio lenguaje no decide a quién darle prioridad con los conflictos (como se hace en algunos lenguajes) esto se dejo a decision del programador. Uno puede hacer cosas como:
class Hablador {
use A { !smallTalk }
use B { !bigTalk }
}
Donde la clase Hablador tiene los metodos del Trait A y del Trait B, pero excluyendo el metodo smallTalk del Trait A y el bigTalk del trait B. También se pueden renombrar métodos al incluir un Trait en una clase.
Una ventaja que tiene esto es que no tiene penalizaci&ocaute;n en runtime, ya que solo es una forma de copy-pastear codigo de una manera formal entre clases.
Les recomiendo leer lo que escribio este hombre Stefan, esta muy bien explicado el caso para PHP.
Bueno, dejo de escribir porque si no se van a aburrir. Espero que se entienda lo suficiente para que si les interesa, lean mas.
/g
Lean
aca.
Mas info sobre traits
aca.
O pueden leer mas sobre esto en la
Tesis de Nathanael Schäarli.