lunes, 5 de marzo de 2012

Patrones de diseño III - Adaptadores

Los adaptadores son un tipo de clase que nos permiten unificar una interfaz para poder cambiar fácilmente entre distintas librerías, haciéndolas así compatibles con nuestra aplicación.

Para ejemplificar este patrón, consideraremos que tenemos una aplicación con la que queremos tener acceso a base de datos con el conector Mysqli, pero queremos dejar la aplicación preparada para poder cambiar de conector fácilmente.

Para empezar a realizar un adaptador, lo primero que tenemos que definir es un interfaz. Pese a que no es un requisito obligatorio, definir un interfaz hará que sea más fácil la implementación del adaptador, evitando así muchos problemas. Para quien no sepa lo que es una interfaz (interface en inglés), le aconsejo que se lea la documentación oficial de php sobre interfaces.

La interfaz que definiremos será un método para poder conectar a la base de datos y otro método para poder ejecutar las consultas y que además nos devuelva su resultado. Un posible código para la interfaz podría ser el siguiente:
<?php
/**
 * Interfaz para la conexión a una base de datos
 */
interface conexionBd
{
        /**
         * Permite al usuario conectarse a la base de datos indicada.
         *
         * @param string $servidor Dirección del servidor.
         * @param string $usuario Nombre de usuario.
         * @param string $contrasena Contraseña.
         * @param string $base_de_datos Nombre de la base de datos a conectar.
         * @return boolean Devuelve TRUE si todo ha ido bien, si no FALSE.
         */
        public function conectar( $servidor, $usuario, $contrasena, $nombre_base_de_datos );

        /**
         * Realiza una petición al motor sql y devuelve el resultado
         * de su ejecución.
         *
         * @param string $sql Petición SQL.
         * @return mixed
         */
        public function peticion( $sql );
}
?>

Como puedes ver, aquí no definimos ningún tipo de implementación, por lo que los métodos están vacíos. Será la clase que implemente esta interfaz, la que deberá programar su lógica.

Ahora que ya tenemos una interfaz común para el acceso a todo tipo de conectores de bases de datos, vamos a crear una clase adaptador que adapte el objeto Mysqli original a  la interfaz genérica que hemos definido.

El código de nuestra clase adaptador es:
<?php
/**
 * Adaptador para Mysqli
 */
class AdaptadorMysqli implements conexionBd
{
        /**
         * Conexión a la base de datos.
         *
         * @var Mysqli
         */
        protected $conexion;

        /**
         * Permite al usuario conectarse a la base de datos indicada.
         *
         * @param string $servidor Dirección del servidor.
         * @param string $usuario Nombre de usuario.
         * @param string $contrasena Contraseña.
         * @param string $base_de_datos Nombre de la base de datos a conectar.
         * @return boolean Devuelve TRUE si todo ha ido bien, si no FALSE.
         */
        public function conectar( $servidor, $usuario, $contrasena, $nombre_base_de_datos )
        {
                $this->conexion = new Mysqli( $servidor, $usuario, $contrasena, $nombre_base_de_datos );
        }

        /**
         * Realiza una petición al motor sql y devuelve el resultado
         * de su ejecución.
         *
         * @param string $sql Petición SQL.
         * @return mixed
         */
        public function peticion( $sql )
        {
                $resultado = $this->conexion->query( $sql );
                if ( $resultado->num_rows > 0 )
                {
                        $datos = array();
                        while( $row = $resultado>fetch_assoc() )
                        {
                                $datos[] = $row;
                        }

                        return $datos;
                }

                return $resultado;
        }

}
?>


Como puedes ver lo primero que hace el código es decir que la clase que implementa la interfaz que hemos definido.
class AdaptadorMysqli implements conexionBd 
De esta forma ahora PHP nos obligará a crear en nuestra clase  todas las funciones que se indiquen en la interfaz que implementa.

En él método de conectar hemos implementado como se realiza la conexión a Mysqli, mientras que en él método de petición hemos implementado una petición más una obtención de resultados. Como ves, no es necesario, ni práctico, que la interfaz se adapte a Mysqli, si no que es al revés, Mysqli debe adaptarse a la interfaz, ya que ahora mismo es Mysqli el que es adaptado, pero al día siguiente puede ser PDO el que quieras adaptar y la misma interfaz te debe servir para cualquiera.

Con todo esto, ya hemos terminado nuestro adaptador pero, ¿esto que nos aporta?. Ahora podemos utilizar en toda nuestra aplicación objetos del tipo conexionBd sin que nos importe que conector a base de datos haya detrás, ya que todos se accederán de la misma forma por la aplicación.

Os dejo el código completo del ejemplo para descargar.

No hay comentarios:

Publicar un comentario