Patrones de respuesta. Y excepciones.

Publicado por Kentaurus en el blog Rigel Kentaurus. Vistas: 118

(Adéndum: estoy consciente de que existe PDO, pero por motivos de simplicidad, no trataré nada relativo a él en esta entrada)

vBulletin en particular utilizar un "wrapper" para la base de datos. Esta es una práctica bastante extendida. En el mundo de Java los llamamos decoradores, en caso de los objetos nativos, los llamamos wrappers. La razón para esto es, dada la definición de un objeto, extender la funcionalidad, pero respetando el API original, lo cuál permite que la clase sea intercambiable.

Ejemplificando esto un poco, quiere decir que el código para enviar un query a la base de datos, es el siguiente:

Código:
$result = mysql_query("SELECT * FROM YabaDabaDoo") or die(mysql_error());
Después de un rato, y a menos de que estén escribiendo un script muy corto, esto comienza a rayar en lo absurdo. Es donde entramos con nuestro patrón de "wrapper" (no es precisamente una clase así que un decorador sería absurdo. Entonces el código se transforma a lo siguiente:

Código:
class Db
{
  public function query($stmt)
  {
     $result = mysql_query($stmt) or die(mysql_error());
     return $result;
  }
}
Lo cuál, como supondrán, permite llamar rápidamente:

Código:
$result = $db->query("SELECT * FROM YabaDabaDoo");
Esta ha sido la forma de programar de usuarios de PHP durante muchos años. Sin embargo, pretendo proponer un cambio, de perdida a los que estén utilizando PHP 5.0. Este approach tiene una desventaja enorme:

No es posible recuperarse de los fallos.

Estudiemos esto en capas. Simplemente le estamos dando a nuestra capa de acceso a datos la facultad y poder de terminar la aplicación completa. Ni siquiera la capa de negocio debe de tener esta facultad.

Regla de oro: Solamente el controlador debe poder decidir el destino de la aplicación, leyendo los mensajes de la capa de negocio.

Esto quiere decir, que podemos hacer un cambio básico en nuestro wrapper, de forma que quede como sigue:


Código:
class Db
{
  public function query($stmt)
  {
     $result = mysql_query($stmt) or [B]throw new Exception[/B](mysql_error());
     return $result;
  }
}
La diferencia, aunque simple es notable. Si no hacemos nada, de forma predeterminada la aplicación muere con un mensaje de "uncaught exception", lo que quire decir que la excepción se ha propagado desde la capa de base de datos hasta la instanciación del script de PHP, y como nadie se hizo responsable de la excepción, simplemente la aplicación "se muere". Este es el comportamiento anterior.

Sin embargo, esto permite cambiar nuestro código de llamada a lo siguiente:

Código:
try
{
  $result = $db->query("SELECT * FROM YabaDabaDoo");
}
catch (Exception $ex)
{
   // código de recuperación aquí
}
No intentaré decirles cuál debe ser el código de recuperación, ya que cada caso es distinto. Podemos ser tan rogue como de crear la tabla en caso de que no exista (el detalle de la excepción nos da el error detallado), o podemos revisar la base de datos, podemos realizar un log de la excepción.

El caso más simple es presentar un mensaje de error al usuario y dejar morir la aplicación. En caso de transacciones agrupadas, el código de recuperación sería responsable de dar "marcha atrás" a todo lo que hemos realizado.


Este conocimiento es bastante básico para las personas que trabajan en el mundo de java. En el mundo de PHP, parece ser una ciencia bastante inexacta. Si les interesa todavía algo más robusto, investigar sobre pdo/mysql es interesante, aunque como PDO no se encuentra disponible hasta la versión 5.1 de PHP, todavía no es completamente ubicuo.
  • veta
  • Cracken
  • Kraderif
Necesitas tener sesión iniciada para dejar un comentario