domingo, 3 de abril de 2016

Introducción al patrón Arquitectónico MVC - Parte III

El Patrón Arquitectónico modelo-vista-controlador (MVC)
Habiendo dejado en claro de qué hablamos exactamente cuando nos referimos a “patrón arquitectónico”, estamos en condiciones de ahondar en los detalles del patrón MVC.

Aclarciones previas

Antes de caer inmersos en el conocimiento sobre el patrón MVC, quiero dejar en claro que en este libro, no hará referencia a ningún framework.
El objetivo de POO y MVC en PHP no es el de formar a programadores en el uso de frameworks, sino que el mismo, parte de una clara pregunta ¿a caso los frameworks no han sido desarrollados por programadores?
Tenemos la alternativa de utilizar frameworks para ahorrar tiempo de programación o, si realmente nos apasiona programar, adquirimos los conocimientos necesarios, tenemos la capacidad y nos animamos, podemos crear nuestros propios frameworks. De hecho, no se trata de reinventar la rueda, sino de crear una, adaptada a nuestras necesidades. Y si lo que necesitamos es una rueda para acoplar a un mueble que acabamos de crear ¿cuál sería el sentido de intentar modificar una rueda de camión si tenemos todas las herramientas necesarias para ser “creadores” y no “modificadores”?
Claro que esto, depende de la pasión, gusto, capacidad y por qué no, de la ambición de cada uno. El tiempo, es discutible. Pues puede demandarte más tiempo modificar algo que ya existe, que crearlo. Si quieres reparar un mueble te llevará más tiempo repararlo que ir a comprar uno nuevo. Y si eres ebanista, seguramente te llevará menos tiempo hacer un nuevo mueble que ir a comprarlo. Pues sabes exactamente lo que necesitas y como hacerlo y eso, hará que ahorres el tiempo de recorrer todas las mueblerías y termines comprando “el mueble que más se asemeje al que quieres”. El mueble, será similar, pero no exactamente igual al que tu imaginaste. De todas formas, la alternativa de modificar, siempre la tienes... al igual que también tienes la de crear. Todo dependerá del criterio de elección que apliques y sea cual sea, tu elección será la correcta, justamente porque habrás “elegido” y eso, es lo más importante.

¿Qué es el patrón MVC?

El patrón MVC es un patrón de arquitectura de software encargado de separar la lógica de negocio de la interfaz del usuario y es el más utilizado en aplicaciones Web, ya que facilita la funcionalidad, mantenibilidad y escalabilidad del sistema, de forma simple y sencilla, a la vez que permite “no mezclar lenguajes de programación en el mismo código”.
MVC divide las aplicaciones en tres niveles de abstracción:

• Modelo: representa la lógica de negocios. Es el encargado de accesar de forma directa a los datos actuando como “intermediario” con la base de datos. Lo que en nuestro ejemplo de programación orientada a objetos, serían las clases DBAbstractModel y Usuario.
• Vista: es la encargada de mostrar la información al usuario de forma gráfica y “humanamente legible”.
• Controlador: es el intermediario entre la vista y el modelo. Es quien controla las interacciones del usuario solicitando los datos al modelo y entregándolos a la vista para que ésta, lo presente al usuario, de forma “humanamente legible”.

Introducción al patrón Arquitectónico MVC - Parte II

De lo general a lo particular: del estilo arquitectónico al patrón de diseño
Existe una diferencia entre Estilo Arquitectónico, Patrón Arquitectónico y Patrón de Diseño, que debe marcarse a fin de evitar las grandes confusiones que inevitablemente, concluyen en el mal entendimiento y en los resultados poco satisfactorios. Éstos, son los que en definitiva, aportarán “calidad” al sistema resultante. En lo sucesivo, trataremos de establecer la diferencia entre estos tres conceptos, viendo como los mismos, se relacionan entre sí, formando parte de un todo: la arquitectura de software.

Relación y Diferencia
Estilo Arquitectónico, Patrón Arquitectónico y Patrón de Diseño, representan, de lo general a lo particular, los niveles de abstracción que componen la Arquitectura de Software. En este sentido, puede decirse que:

• El Estilo Arquitectónico es el encargado de:
◦ Describir la estructura general de un sistema, independientemente de otros estilos
◦ Definir los componentes del sistema, su relación e interactividad
◦ Ejemplos : flujo de datos, llamada y retorno, etc.

• El Patrón Arquitectónico es el nivel en el cual la arquitectura de software:
◦ Define la estructura básica de un sistema, pudiendo estar relacionado con otros patrones
◦ Representa una plantilla de construcción que provee un conjunto de subsistemas aportando las normas para su organización
◦ Ejemplos : Capas, MVC, Tuberías y Filtros, Pizarra, etc.

• El Patrón de Diseño es el tercer nivel de abstracción de la arquitectura de software, cuya finalidad es la de precisar en detalle los subsistemas y componentes de la aplicación
◦ Ejemplos : Proxy, Command, Factory, etc..

Introducción al patrón Arquitectónico MVC - Parte I

MVC, son las siglas de modelo-vista-controlador (o en inglés, model-view-controller), que es uno de los tantos patrones de arquitectura de software.
Antes de abordar de lleno este patrón, vamos a intentar hacer una introducción a la arquitectura de software, desmembrándola de lo general hacia lo particular, para al fin llegar al detalle, procurando entender exactamente de que se trata, en el contexto adecuado.
Probablemente, este capítulo sea el más complejo (y mucho más extenso en relación al Capítulo I). Pero si quieres poder aplicar de forma decuada el patrón MVC, debes hacer el esfuerzo de seguirlo con especial interés y actitud “entuciasta”.

Introducción a la Arquitectura de Software
 
¿Qué es la arquitectura de software?
Es necesario aclarar, que no existe una definición única, exacta, abarcativa e inequívoca de “arquitectura de software”. La bibliografía sobre el tema es tan extensa como la cantidad de definiciones que en ella se puede encontrar. Por lo tanto trataré, no de definir la arquitectura de software, sino más bien, de introducir a un concepto simple y sencillo que permita comprender el punto de vista desde el cual, este libro abarca a la arquitectura de software pero, sin ánimo de que ello represente “una definición más”.
A grandes rasgos, puede decirse que “la Arquitectura de Software es la forma en la que se organizan los componentes de un sistema, interactúan y se relacionan entre sí y con el contexto, aplicando normas y principios de diseño y calidad, que fortalezcan y fomenten la usabilidad a la vez que dejan preparado el sistema, para su propia evolución”.
Tal vez estés pensando “...al fin y al cabo, me haz dado una definición más...”. La respuesta es sí. Probablemente no pude contenerme de hacerlo – no lo niego -. Pero, no debes tomar lo anterior como una definición, sino como la forma en la que en este libro, se abarca la arquitectura de software.

Tendencias de la Arquitectura de Software

Si bien no puede decirse o mejor dicho, no es muy académico decirlo, voy a tomarme el atrevimiento de mencionar solo dos tendencias arquitectónicas, claramente diferenciadas entre sí:

• La Arquitectura de Software Orientada a Objetos (como “ingeniría” de sistemas)
• La Arquitectura Estructurada (como “desarrollo” de una aplicación)

Como podemos ver, en este libro, es a la primera a la cual nos enfocamos.
A fin de satisfacer la inquietud de curiosos (y de paso, no ocultar que existen), voy a mencionar la existencia de otras dos corrientes: la arquitectura basada en patrones y la arquitectura basada en procesos y metodologías.
Personalmente, no las considero como cuatro corrientes ¿Por qué? Porque independientemente de cual te agrade más, si la AS orientada o objetos o la AS estructural, implican necesariamente dos corrientes que deben aplicarse de forma optativa (o utilizas una o la otra pero no las dos simultáneamente), mientras que la AS basada en patrones y la AS basada en procesos, pueden utilizarse como complemento de las dos primeras. Pero esto, es mera filosofía propia, con la cual, no he encontrado demasiado consenso. Pues no los aburriré con ello e iremos a lo práctico. 

Características de la Arquitectura de Software: Atributos de calidad
La Calidad del Software puede definirse como los atributos implícitamente requeridos en un sistema que deben ser satisfechos. Cuando estos atributos son satisfechos, puede decirse (aunque en forma objetable), que la calidad del software es satisfactoria.
Estos atributos, se gestan desde la arquitectura de software que se emplea, ya sea cumpliendo con aquellos requeridos durante la ejecución del software, como con aquellos que forman parte del proceso de desarrollo de éste.
Atributos de calidad que pueden observarse durante la ejecución del software

1. Disponibilidad de uso
2. Confidencialidad, puesto que se debe evitar el acceso no autorizado al sistema
3. Cumplimiento de la Funcionalidad requerida
4. Desempeño del sistema con respecto a factores tales como la capacidad de respuesta
5. Confiabilidad dada por la constancia operativa y permanente del sistema
6. Seguridad externa evitando la pérdida de información debido a errores del sistema
7. Seguridad interna siendo capaz de impedir ataques, usos no autorizados, etc. Atributos de calidad  inherentes al proceso de desarrollo del software
8. Capacidad de Configurabilidad que el sistema otorga al usuario a fin de realizar ciertos cambios
9. Integrabilidad de los módulos independientes del sistema
10. Integridad de la información asociada
11.Capacidad de Interoperar con otros sistemas (interoperabilidad)
12.Capacidad de permitir ser Modificable a futuro (modificabilidad)
13.Ser fácilmente Mantenible (mantenibilidad)
14.Capacidad de Portabilidad, es decir que pueda ser ejecutado en diversos ambientes tanto de software como de hardware
15.Tener una estructura que facilite la Reusabilidad de la misma en futuros sistemas
16.Mantener un diseño arquitectónico Escalable que permita su ampliación (escalabilidad)
17.Facilidad de ser Sometido a Pruebas que aseguren que el sistema falla cuando es lo que se espera (testeabilidad)

martes, 1 de marzo de 2016

Explicando ejemplo de POO con PHP - PARTE 4

1. Respuestas a preguntas frecuentes de la clase DBAbstractModel

1.1 ¿Por qué la clase está definida como abstracta?
Una base de datos, puede tener varios métodos, como insertar datos, editar datos, eliminar datos o simplemente consultar datos. El algoritmo de cada uno de esos métodos no puede definirse con exactitud ¿por qué? Porque cada dato que se inserte, modificque, elimine o consulte, variará en infinidad de aspectos: desde los tipos de datos hasta las tablas y los campos a los que se deba acceder, etc.
Basados en el principio de modularidad de la POO, es necesario tener en cuenta, que HOY, necesito un ABM de usuarios, pero mañana, este requisito puede ampliarse y, debo dejar todo preparado para que el sistema pueda ser escalable y modular (otros módulos pueden ser requeridos en el futuro).
Si solo contemplara los métodos de inserción, edición, consulta y eliminación de usuarios en
esta clase, estaría cometiendo dos errores imperdonable:

1. No estaría respetando el principio de modularidad de la POO
2. Los métodos mencionados ¿no son a caso métodos de un nuevo objeto llamado Usuario?

Por otro lado, por cuestiones de seguridad, se hacía necesario no permitir instanciar esta clase desde ningún lugar de la aplicación y controlar con mucha precaución, el acceso a sus métodos y propiedades, ya que una base de datos, es el "alma" de toda aplicación.

1.2 ¿Para qué declarar propiedades estáticas?
En principio, tanto el host como el usuario y contraseña de la base de datos, en esta aplicación, son únicos. No varían. De allí, que como característica se les asignó ser estáticos, a fin de, por cuestiones de seguridad, no puedan ser modificados dinámicamente (tengamos en cuenta que una clase abstracta debe ser heredada sí o sí para ser utilizada).

1.3 ¿Por qué propiedades estáticas y no constantes de clase?

Porque a las constantes, aunque lógicamente guardan en sí mismas la condición de "estáticas" en el sentido de que "no pueden ser modificadas", pueden ser accedidas desde cualquier clase que herede de la clase que las declare. Pues entonces, la pregunta es ¿Para qué querría una clase "hija" conocer el host, usuario y contraseña de una base de datos?
Es una cuestión nétamente de seguridad, ya que a una constante no se la puede definir como privada y si se la quiere ocultar a las clases "hijas", no quedará otra alternativa que declararlas como propiedades estáticas.

1.5 ¿Con qué sentido declarar las propiedades como protegidas?
Es simple. Algunos módulos pueden necesitar utilizar una base de datos diferente. Todos los módulos, necesitarán queries personalizados para sus consultas. Y lógicamente, todos necesitarán acceder y conocer los resultados de los datos arrojados por una consulta. Es decir, que tanto la propiedad db_name como query y rows, deben tener permisos para ser leídas y modificadas, pero ¡Ojo! Solo por las clases hijas de DBAbstractModel ¿Qué sentido tendría permitir a un programador acceder a estas propiedades si puede ser la clase hija, quien las controle?

1.6 ¿Por qué los métodos open y close_connection son privados?
Pues porque la clase es la única con permiso para abrir y cerrar conexiones a la base de datos. Es una cuestión de control y seguridad.
Si necesitas insertar datos, consultarlos o hacer con ellos otras actividades, tienes métodos protegidos pero no privados, que te permiten hacerlo.

1.7 ¿Por qué los métodos de consulta y ejecución son protegidos y no públicos?
Consultar una base de datos, modificar o eliminar sus datos, así como insertar nuevos, no puede ser una tarea que se deje librada al azar y al libre acceso de cualquiera. Es necesario "proteger" los datos a fin de resguardar su integridad y, la forma de hacerlo, es "proteger" los métodos que se encuentran al servicio de dichos datos.

1.8 ¿Por qué hay métodos declarados como abstractos y además protegidos?
Esta pregunta, en gran parte, la responde la respuesta de la pregunta 1.1. El hecho de que se definan como abstractos, es porque necesariamente DEBEN ser métodos comunes a toda clase que los hereden. Pero solo la clase hija, podrá definirlos (re-definirlos técnicamente hablando) ya que tal cual se
explicó en la pregunta 1.1., solo ellas conocen los requerimientos específicos.
Se declaran además como protegidos, por una cuestión de seguridad ("por las dudas" para que solo puedan ser vistos por clases heredadas). Esto, da lugar a las clases hijas, a que modifiquen su visibilidad de acuerdo al criterio de cada una de ellas.

2. Respuestas a preguntas sobre la clase Usuario
 
2.1 ¿Por qué la clase Usuario es una extensión de DBAbstractModel?
La clase usuario TIENE necesariamente que heredar de DBAbstractModel ya que DEBE utilizar sus métodos (propios y definidos para acceder a la base de datos) y redefinir obligadamente aquellos declarados como abstractos, a fin de continuar un modelo de administración de los ABM (altas, bajas y
modificaciones).

2.2 ¿Con qué fin nombre, apellido e email son propiedades públicas mientras que clave es privada y id, protegida?
Pensemos esto como en la vida real: tu nombre, apellido e e-mail, puede ser necesario para cientos de "trámites" y acciones de tu vida diaria y no andas por la vida negándolos a todo quien te los pida.
Podríamos decir, que no tiene nada de malo que facilites públicamente estos datos, a quien decidas.
Ahora bien ¿le das tu contraseña a cualquiera? Si lo haces, deja de hacerlo. La contraseña es un dato que debe ser privado. Nadie puede tener acceso a él. Es una cuestión de seguirdad.
El número de ID, sería como tu número de documento o pasaporte. Es un dato que debes mantener protegido pero que en algunos casos, te será requerido y necesitarás darlo obligadamente. Por ejemplo, no podrías negarte a mostrar tu pasaporte en migraciones. Sin embargo, DEBES negarte a decirle el PIN de tu tarjeta de crédito a cualquier persona. 

2.3 ¿Por qué se utiliza el método __construct() para modificar el nombre de la base de datos? ¿Por qué no se encarga la clase madre de modificar ese valor?
El nombre de la base de datos, es algo que variará de acuerdo al módulo que lo esté trabajando. Seguramente, de existir en el futuro una clase llamada Producto, ésta, sobreescribirá el valor de db_name. Modificarlo automáticamente utilizando un cosntructor, nos asegura instanciar el objeto con un valor de propiedad adecuado.

2.4 ¿Por qué se utiliza require_once y no include_once?
La diferencia entre include y require es que require, si no puede incluir el archivo al que se está importando, frena la ejecución del script, siendo que include, solo arroja un error, pero continúa la ejecución. Al tratarse de una clase que "requiere" sí o sí, de su clase madre, no tendría sentido permitir que se continúe ejecutando, si no ha podido cargarse el archivo.

3. Respuestas a preguntas sobre el archivo de instancias
 
3.1 ¿Por qué el archivo tiene cuatro instancias al mismo objeto?
Es necesario hacer notar que si bien los objetos comparten propiedades y métodos en común, no todos son idénticos. Es decir, todos los seres humanos tenemos ciertas características en común y realizamos acciones similares. Pero cada uno de nosotros, tiene una única identidad. Por eso, no puede
decirse que se instancia cuadro veces el mismo objeto, porque en realidad, son cuatro objetos diferentes donde cada uno de ellos, tiene una identidad propia. 

Ejemplo de POO con PHP - PARTE 3



Archivo abm_example.php
<?php
require_once('usuarios_model.php');
# Traer los datos de un usuario
$usuario1 = new Usuario();
$usuario1->get('user@email.com');
print $usuario1->nombre . ' ' . $usuario1->apellido . ' existe<br>';
# Crear un nuevo usuario
$new_user_data = array(
'nombre'=>'Alberto',
'apellido'=>'Jacinto',
'email'=>'albert2000@mail.com',
'clave'=>'jacaranda'
);
$usuario2 = new Usuario();
$usuario2->set($new_user_data);
$usuario2->get($new_user_data['email']);
print $usuario2->nombre . ' ' . $usuario2->apellido . ' ha sido creado<br>';
# Editar los datos de un usuario existente
$edit_user_data = array(
'nombre'=>'Gabriel',
'apellido'=>'Lopez',
'email'=>'marconi@mail.com',
'clave'=>'69274'
);
$usuario3 = new Usuario();
$usuario3->edit($edit_user_data);
$usuario3->get($edit_user_data['email']);
print $usuario3->nombre . ' ' . $usuario3->apellido . ' ha sido editado<br>';

# Eliminar un usuario

$usuario4 = new Usuario();
$usuario4->get('lei@mail.com');
$usuario4->delete('lei@mail.com');
print $usuario4->nombre . ' ' . $usuario4->apellido . ' ha sido eliminado';
?>
 

Ejemplo de POO con PHP - PARTE 2



Archivo usuarios_model.php
<?php
require_once('db_abstract_model.php');
class Usuario extends DBAbstractModel {
public $nombre;
public $apellido;
public $email;
private $clave;
protected $id;
function __construct() {
$this->db_name = 'book_example';
}
public function get($user_email='') {
if($user_email != ''):
$this->query = "
SELECT id, nombre, apellido, email, clave
FROM usuarios
WHERE email = '$user_email'
";
$this->get_results_from_query();
endif;
if(count($this->rows) == 1):
foreach ($this->rows[0] as $propiedad=>$valor):
$this->$propiedad = $valor;
endforeach;
endif;
}
public function set($user_data=array()) {
if(array_key_exists('email', $user_data)):
$this->get($user_data['email']);
if($user_data['email'] != $this->email):
foreach ($user_data as $campo=>$valor):
$$campo = $valor;
endforeach;
$this->query = "
INSERT INTO usuarios
(nombre, apellido, email, clave)
VALUES
('$nombre', '$apellido', '$email', '$clave')
";
$this->execute_single_query();
endif;
endif;
}
public function edit($user_data=array()) {
foreach ($user_data as $campo=>$valor):
$$campo = $valor;
endforeach;
$this->query = "
UPDATE usuarios
SET nombre='$nombre',
apellido='$apellido',
clave='$clave'
WHERE email = '$email'
";
$this->execute_single_query();
}
public function delete($user_email='') {
$this->query = "
DELETE FROM usuarios
WHERE email = '$user_email'
";
$this->execute_single_query();
}
function __destruct() {
unset($this);
}
}
?>