martes, 3 de mayo de 2016

El Patrón MVC en PHP - Parte I

Para que el concepto de modelo-vista-controlador nos queda más claro, vamos a ir analizándolo con ejemplos concretos en PHP.

El modelo

Con respecto al modelo, no tenemos demasiada novedad. El modelo, no es más que el conjunto de clases con las que hemos trabajado hasta ahora, incluyendo entre ellas, la capa de abstracción de la base de datos.

Interfaces en PHP: un nuevo concepto para crear modelos

En esta etapa, podemos ampliar las referencias de PHP, incorporando un nuevo concepto: las interfaces.
El Manual Oficial de PHP describe las interfaces de la siguiente forma:  
“Las interfaces de objetos permiten crear código con el cual especificar qué métodos deben ser implementados por una clase, sin tener que definir cómo estos métodos son manipulados.
Las interfaces son definidas utilizando la palabra clave interface, de la misma forma que con clases estándar, pero sin métodos que tengan su contenido definido. Todos los métodos declarados en una interfaz deben ser public, ya que ésta es la naturaleza de una interfaz.”8[...] 

Una interface se define utilizando la palabra clave interface y se la implementa utilizando la palabra clave implements.
En varias ocasiones, las interfaces nos servirán para ampliar los modelos.

Generamos la interface:

interface Postre {
   public function set_ingredientes();
}

Implementamos la interface:

class Bizcochuelo implements Postre {
   var $ingredientes = array();
   public function set_ingredientes() {
      $this->ingredientes = array('harina'=>'2 tazas', 'leche'=>'1 taza',
                                              'azucar'=>'1 taza', 'huevo'=>1);
   }
}

Extendemos una clase (que por defecto, implementará la interface):

class BizcochueloVainilla extends Bizcochuelo {
   public function set_ingredientes() {
      $this->ingredientes['escencia de vainilla'] = 'a gusto';
   }
   function __construct() {
      parent::set_ingredientes();
      $this->set_ingredientes();
   }
}

También podemos crear otra clase que implemente la interface:

class Alfajor implements Postre {
   public function set_ingredientes() {
      $this->ingredientes = array('Tapas de maizena' => 2,
                                             'dulce de leche'=>'1 cda. sopera',
                                             'coco rallado'=>'1 cdta. de te');
   }
   function __construct() {
      $this->set_ingredientes();
   }
}

Diferencia entre Interfaces y Clases abstractas
Probablemente te preguntes ¿cuál es la diferencia entre una interface y una clase abstracta? Créeme: todos nos lo hemos preguntado alguna vez :)
En principio, existe una diferencia conceptual que a niveles “prácticos” tal vez no es del todo clarificadora. Esta diferencia, radica en que las clases abstractas, no dejan de ser “clases”, las cuales representan la “abstracción de un objeto” siguiendo un orden de “relación jerarquíca” entre ellas: Clase B hereda de Clase A y Clase C hereda de Clase B, pero no puede tener herencias múltiples, es decir no puede heredar de más de una clase, ya que ellas, guardan una relación de orden jerárquico entre sí.

class A { }
class B extends class A { } #correcto
class C extends class B { } #correcto
class D { } #correcto
class E extends class A, class D { } # incorrecto!!! no se puede hacer!!!
# lo correcto sería:
class D extends class A { }
class E extends class D { }

A diferencia de las clases abstractas, conceptualmente, las interfaces son solo un conjunto de métodos característicos de diversas clases, independientemente de la relación que dichas clases mantengan entre sí. De hecho, una misma clase, puede implementar múltiples interfaces:

interface A { }
interface B { }
interface C { }
class MiClase implements A, B, C { }

No obstante la diferencia conceptual, podemos establecer claras diferencias prácticas, que nos ayudarán a asimilar mejor estos conceptos:

• Las interfaces no pueden definir propiedades (de hecho, no poseen propiedades porque a diferencia de las clases abstractas no tienen relación con un objeto, y solo los objetos tienen propiedades)
• Las interfaces no pueden tener métodos definidos con su algoritmo correspondiente (solo pueden declarar los métodos pero no pueden indicar el “qué” ni el “cómo” hacerlo, mientras que las clases abstractas, sí pueden)
• Las interfaces no pueden instanciarse porque no tienen referencias asociadas a objetos, mientras que las clases abstractas no pueden instanciarse, porque sus objetos son “entes abstractos” que necesitan de una clase no abstracta para definirse con exactitud y poder ser instanciados.
• Todos los métodos declarados en una interface deben ser públicos, puesto que la finalidad de una interface, es brindar un “ámbito público de un modelo”. Las clases abstractas, pueden tener métodos abstractos tanto públicos como protegidos (aquellos que deberán ser obligatoriamente redefenidos por las clases que la hereden) y métodos privados que solo ella utilice.

Lo que NO deben hacer las insterfaces
Las interfaces no pueden:
• Tener el mismo nombre que una clase (PHP las interpreta como una clase más. Crear una interface con el mismo nombre que una clase, sería interpretado por PHP como una “re-declaración de clase”)
• Diferentes interfaces no pueden tener nombres de métodos idénticos si serán implementadas por la misma clase

No hay comentarios.:

Publicar un comentario