Traits, lo nuevo de PHP 5.4

Balu18 Julio 2011 - 2:14pm 0 comentarios
Enviar por Email Imprimir

Traits, lo nuevo de PHP 5.4Desde hace años se venía comentando la inclusión de Traits en PHP, tal ves para la versión 6 se decía. Pero, lo cierto es que esperar tanto impacienta. Por lo que luego de debates internos, se decidió incluir soporte a Traits para la versión 5.4 de PHP, la cual acaba de ser lanzada en versión Alpha.

¿Qué son los Traits?

Los Traits son un mecanismo para reutilizar código en un lenguaje que no soporta la herencia múltiple, cómo es el caso de PHP. Un Trait busca reducir las limitaciones de la herencia simple, permitiendo a los desarrolladores reutilizar un conjunto de métodos en varias clases independientes de jerarquías. La semántica para combinar los Traits y las Clases es definida de una manera en la cual, se reduce la complejidad y evita los problemas típicos asociados con la herencia múltiple y/o Mixins.

Los Traits son reconocidos por su potencial soporte a una mejor composición y reutilización del código; e ahí el motivo por el cual, las nuevas versiones de otros lenguajes como Perl 6, Squeak, Scala, Slate y Fortress lo incluyen. Los Traits también han sido portados a Java y C#...

El dominio de los Traits

Cuando una clase extiende de otra clase, se dice que esa clase es hija de la segunda. Hablamos de un tipo-de clase padre, la cual le proporciona propiedades, métodos y funcionalidad. Por ello, la herencia ofrece acceso a todo el código que no sea privado de la clase padre, siguiendo el patrón de Reusabilidad vertical del código.

Sin embargo, mientras que la herencia es una buena forma de reutilizar código, no resuelve todos los problemas de duplicidad. Hay momentos en que dos objetos requieren la misma funcionalidad, pero no pueden derivar de la misma clase padre. Por ejemplo:

class A { ... }
class B extends ArrayObject {
    // Uso de la funcionalidad ArrayObject de la librería stándard de PHP
}

Ahora imaginemos que necesitamos hacer que ambas clases actúen como singletons (recuerden los patrones de diseño con PHP). Con las actuales características de PHP 5.3 tendríamos un problema. La clase B no podría extender de una clase Singleton común, ya que al estar PHP fuertemente influenciado por Java, no esta permitido heredar de varias clases. En lenguajes como C++ se podría resolver este problema utilizando Templates o la herencia múltiple (Mixins en otros lenguajes como Ruby), pero ninguna de estas funcionalidades están disponibles en PHP.

Aunque los Traits son técnicamente diferentes que los Mixins, ambos están diseñados para llenar el vacío dejado por el mismo modelo de herencia simple:

trait Singleton {
    public static function getInstance() { ... }
}

class A {
    use Singleton;
    // ...
}

class B extends ArrayObject {
    use Singleton;
    // ...
}

// El método Singleton ahora esta disponible para ambas clases
A::getInstance();
B::getInstance();

Cómo precisa Stefan Marr, autor original de esta actualización, los Traits no son más que un compilador que nos ayuda a copiar y pegar código. Una funcionalidad común se puede agrupar dentro de la definición de un Trait y luego ser incluida en diferentes clases mediante la declaración use. Aquí vendría bien recordar un poco sobre los nombres de espacio en PHP.

Conflictos y Alias de Traits

Cuando dos Traits han definido un método con el mismo nombre y luego se necesita utilizar ambos en la misma clase, surge un conflicto de nombres. Si bien esto es muy poco probable que ocurra, vale la pena mencionar que hay una sintaxis especial para resolver este tipo de problemas:

// Asumimos que los trait A y B tienen un método hello() definido
class Test {
    use A, B {
        B::hello insteadof A;
    }
}

// La clase Test tendrá implementado el método "hello" del trait B

Esto se logra utilizando el nuevo operador insteadof que excluye un método en favor del otro. Y si hubiera necesidad de utilizar las implementaciones de ambos métodos en la misma clase, se podría utilizar un alias:

class Test {
    use A, B {
        B::hello insteadof A;
        A::hello as helloA;
    }
}

// La clase Test tendrá implementado el método "hello" y "helloA"

As es un operador adicional que también podría servirnos para cambiar la visibilidad de un método y otros modificadores (con la excepción de static, que no es compatible):

Como un extra - operador de alias como también se puede utilizar para cambiar la visibilidad de método y otros modificadores (la única excepción es estática, que no es soportada):

sayHello();
$o->sayWorld();
$o->sayExclamationMark();
// El resultado será: Hello World!

Expresar los requisitos de un Trait

Las definiciones de los métodos de un Trait soportan todos los modificadores utilizados para definir los métodos de una clase normal, incluyendo los de visibilidad, modificadores, final, static y abstract. Este último puede ser utilizado para definir un método abstracto que exprese el requisito particular de un Trait.

trait Printer {

    public function print() {
        print $this->getData();
    }

    // Deberá ser definido en una clase que use el trait Printer
    abstract protected function getData();
}

Los Traits no tienen estado y se limitan sólo a definir métodos y/o requisitos abstractos; sin embargo, debido a la naturaleza dinámica de PHP, es posible usar variables de instancia o métodos informales también. Por ejemplo, veamos la siguiente implementación de este trait:

trait A {

    public function hello() {

        // El código que depende de la variable de instancia "test"
        if (isset($this->test)) { ... }
    }
}

El código dentro de la declaración if será ejecutado cuando la clase tenga una variable de instancia definida como "test". Aunque esto funcionaría, lo recomendable sería definir los métodos setters y getters de los datos requeridos como definiciones de métodos abstractos del Trait, mencionado anteriormente.

Algunos datos a precisar

  • Los Traits sólo participan en el proceso de construcción de una clase y no añaden nada nuevo en tiempo de ejecución. Esto significa que la funcionalidad conocida de la OOP de PHP funciona igual con la inclusión de los traits.
  • Los Traits integran un orden de precedencia para la sobre escritura de métodos, donde los métodos de la clase actual sobre escriben los métodos del trait, que a su vez sobre escriben los métodos de la clase padre.
  • Los Traits pueden estar compuestos de otros traits (al igual que con las clases, se usa use para llamar a un trait).
  • Los Traits no son un nuevo concepto de PHP, otras implementaciones parecidas están disponibles en otros lenguajes de programación, como ya lo mencionamos al principio.

Tutoriales

Cómo descargar videos de VK.com
En este artículo voy a explicar como descargar videos y películas...
Descargar Facebook Móvil Gratis
Por si aún no lo han hecho, es posible descargar Facebook Móvil...
Cómo generar tráfico web con las redes sociales - Paso a Paso
Muchas empresas están publicando contenidos como la forma de crear...

Artículo Recomendado

3 Tips cruciales para recuperar archivos eliminados
¿Te imaginas perder el trabajo de toda una semana en tan solo unos segundos? Todos hemos pasado por este problema. Quizás eliminamos por error un archivo importante o lo borramos sin pensar que era valioso para otro... más