You are on page 1of 20

Talleres de Ingeniería del Software 3 – Patrones de Diseño

3 – PATRONES DE DISEÑO
Preámbulo
Uno de los errores de implementación de software más frecuentes es el alto acoplamiento que se da entre
aspectos que tienen que ver con la interfaz de usuario y el modelo lógico que responde a las necesidades
funcionales de los usuarios. Normalmente quienes se dedican a fabricar “programitas” sin tener idea del
diseño de software, mezclan de manera horrible el código de la presentación con algoritmos de
manipulación de datos.

Un ejemplo de lo anterior lo puede ver en el código propuesto en el taller 2 donde se mezcló HTML con CSS
o con PHP, pero si desea un mejor ejemplo observe la siguiente porción de código tomada de
http://www.todoexpertos.com/ en donde el autor de manera irresponsable hace un “guiso” de PHP,
Javascript, HTML y CSS.

<form method="post" action="carrocerias.php" >


<?php
/* ********************* */
/* Conexion a PostgreSQL */
/* ********************* */
/* Conexion a la base de datos phpinfo();*/
$db_conexion = pg_connect("port=5432 dbname=Rodamiento user=postgres password= santa");
if (!$db_conexion) {
echo "<CENTER>
Tengo Problemas de conexion con la base de datos.
</CENTER>";
exit;
}
else {
echo "Base de Datos Conectada........Rodamiento";
// ...
<script languaje=javascript>alert ('Datos Repetidos');</script>
";
// ...
if( $modificar ){
if( !$codigo or !$nombre ){
echo "<script languaje = javascript>alert('Digite Codigo a Modificar')</script>
";
}
// ...
<b>Datos Carroceria</b>
// ...
<table>
<tr>
<td><b>Codigo</b><font color = "#ff0000" face="Arial">*</font>:
<td><input type = "text" name = "codigo" size = 7 maxlength = 5 value= "<?php echo $cod1 ?>">
<br>
<tr>
<td><b>Descripcion</b><font color = "#ff0000" face="Arial">*</font>:
<td><input type = "text" name = "nombre" size = 20 value= "<?php echo $nom1 ?>">
<br>
</table>
// ...
</form>

¿Ha pensado cómo se sentiría un desarrollador de software o un auditor de sistemas revisando centenares o
miles de líneas de código con este “estilo” de programación?

Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página 1


Talleres de Ingeniería del Software 3 – Patrones de Diseño

Para evitar una desastrosa presentación de código como la mostrada y los problemas que ello conlleva, en
1979 Trygve Reenskaug planteó por primera vez el patrón Modelo–Vista–Controlador (MVC) cuando
trabajaba en el desarrollo de Smalltalk. Su propuesta trata de realizar un diseño que desacople la vista o
interfaz de usuario del modelo de dominio, con la finalidad de mejorar la reusabilidad. De esta forma las
modificaciones en las vistas impactan en menor medida en la lógica de negocio o de datos, en donde debe
procesarse solamente lo relacionado con los requisitos funcionales.

La figura siguiente muestra un diagrama de secuencia que describe la manera en que viajan los mensajes y
las respuestas por las diferentes capas que conforman el MVC:

De acuerdo a la figura:

1. El modelo tiene tres responsabilidades básicas:

o Acceder a la capa de almacenamiento de datos,

o Definir las reglas de negocio o lo que es lo mismo, cumplir con los requisitos funcionales de
la aplicación y

o Llevar a cabo validaciones que deban hacerse en el servidor.

2. El controlador es responsable de:

o Recibir los eventos de entrada que llegan desde la capa de presentación.

o Aplicar reglas de gestión de eventos que permiten delegar de manera correcta las acciones a
distintos componentes del modelo.

o Recibir las respuestas del modelo para comunicarlas a la capa de presentación.

o Ejercer control de usuarios, de visitas, de sesiones, etc.

o Registrar o instanciar elementos de la capa de dominio para poderse comunicar con ésta.

Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página 2


Talleres de Ingeniería del Software 3 – Patrones de Diseño

3. Las vistas son responsables de:

o Permitir la interfaz actor/aplicación para recibir datos o eventos del actor y enviarlos al
controlador o

o Recibir información del controlador para entregarla al actor.

Como lo ideal es que el modelo sea independiente del sistema de almacenamiento enseguida se modifica el
modelo de Reenskaug para incluir una capa adicional de servicios técnicos que por ahora se encargue de las
acciones CRUD (Create, Retrieve, Update, Delete) y que más adelante puede incluir otros servicios como por
ejemplo interfaces con otros sistemas. La figura siguiente muestra el diagrama de secuencia del MVC
modificado:

En este primer ensayo de MVC ampliado la responsabilidad de la capa de presentación estará a cargo de una
vista creada a partir de HTML; el controlador será un script de PHP que establecerá la conexión con los
servicios técnicos y se encargará de gestionar el intercambio de información entre el modelo y la vista; y el
modelo estará conformado por un conjunto de clases interrelacionadas de tal manera que se cumplan los
objetivos propuestos a partir de los requisitos del sistema.

Competencias
Posibilidad de crear aplicaciones Web 2.0 básicas, con bajo acoplamiento entre capas a partir del uso del
MVC ampliado y de otros patrones de diseño como: Fachada, Bajo Acoplamiento, Alta Cohesión, Singleton y
Experto.

Herramientas necesarias
Además de las utilizadas en los talleres anteriores, aquí hay que incorporar un complemento para Mozilla
Firefox llamado FireBug. Esta extensión está especialmente pensada para inspeccionar al detalle el código
fuente y el funcionamiento de un sitio web, localizando e incluso depurando cualquier error.

Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página 3


Talleres de Ingeniería del Software 3 – Patrones de Diseño

Como se muestra en la figura siguiente, la extensión abre una ventana a modo de consola en el navegador,
donde muestra los posibles errores en el código. También permite inspeccionar el código HTML de la web
examinando objeto por objeto y mostrando el diseño de todos los datos del Modelo de Objetos del
Documento (DOM) web.

Esta extensión está disponible en https://addons.mozilla.org/es-ES/firefox/addon/1843. Queda claro


entonces que las pruebas se realizarán en el navegador Mozilla Firefox, utilizando FireBug.

El problema planteado
¿Cómo soportar bajas dependencias, bajo impacto del cambio e incrementar la reutilización de código en
aplicaciones?

La práctica siguiente demuestra cómo a partir del uso de algunos patrones de diseño es posible terminar con
problemas como:

• Dificultad en los cambios al tener que modificar grandes cantidades de código.


• Complejidad en la comprensión del código fuente por no poderse entender de manera aislada
aspectos relacionados con presentación y dominio del problema.
• Dificultad al reutilizar puesto que la dependencia entre partes es elevada.

Práctica
Enseguida se retoma la práctica del segundo taller, esta vez implementando clases para todo lo que tiene
que ver con la lógica de la aplicación.

1. Compruebe que tiene disponible el FireBug en el navegador Mozilla Firefox. Si es así, aparecerá en la
parte inferior derecha un icono como este: , si no aparece, se recomienda instalarlo ahora.

2. Cree un nuevo proyecto con el nombre y estructura de carpetas que se muestra enseguida:

Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página 4


Talleres de Ingeniería del Software 3 – Patrones de Diseño

3. Como lo indica la figura anterior, elimine la página que NetBeans crea por defecto y en su lugar cree una
PHP Web Page llamada index, justo dentro de Source Files.

4. Modifique a index.php de acuerdo al siguiente código:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>

<body>
<p>Opciones disponibles</p>
<a href=”vista/mostrarTemas.php”>Mostrar temas de congresos</a>
<br>
<a href=”vista/agregarTemas.php”>Agregar temas de congresos</a>
<br>
<a href=”vista/eliminarTema.php”>Eliminar un tema de congreso</a>
<br>
<a href=”vista/editarTema.php”>Actualizar un tema de congreso</a>
</body>
</html>

Como puede ver, ahora los hipervínculos referencian a páginas que deberán incluirse dentro de la
carpeta vista. En los siguientes pasos se crearán dichas páginas.

5. Dentro de la carpeta vista cree una PHP Web Page llamada agregarTemas a partir del siguiente código:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Agregar temas de congresos</title>
<link rel="stylesheet" type="text/css" href="estiloFormulario.css" />
</head>

<body>
<fieldset>
<legend>Agregar temas de congresos</legend>
<form action="../controlador/fachada.php" method="post"> .
<input type="hidden" name="clase" value="TemaCongreso" />
<input type="hidden" name="oper" value="add" /> .
<ul>
<li>
<label for="txtTema">Nuevo tema:</label>
<input type="text" name="descripcion" id="descripcion" size="50" />
</li>
<li>
<label for="submit"></label>
<button type="submit" id="submit">Enviar</button>
</li>
</ul>
</form>
</fieldset>
</body>
</html>

Lo primero que hay que resaltar del código anterior es que es HTML puro. Observe que ya no aparece un
bloque de código CSS que se incorporaba en el formulario en el punto 17 del taller anterior y que en su
lugar aparece un link a una stylesheet o CSS que se creará en el siguiente punto.

Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página 5


Talleres de Ingeniería del Software 3 – Patrones de Diseño

Otro detalle es que la acción de enviar los datos del formulario, estará dirigida a un script llamado
fachada.php. Observe:
<form action="../controlador/fachada.php" method="post">

Dicho script hará las veces de controlador. El nombre se le ha dado en honor a muchos funcionarios que
son de fachada, se dedican a delegar pero todo pareciera que lo hicieran ellos. ¡Mentira! El nombre se
basa en la implementación del patrón GoF Fachada que según Larman es útil cuando “… se requiere
una interfaz común, unificada para un conjunto de implementaciones o interfaces dispares…”

Por último observe que se han incorporado dos entradas ocultas:


<input type="hidden" name="clase" value="TemaCongreso" />
<input type="hidden" name="oper" value="edit" /> .

Por ser ocultas no estarán visibles en el formulario pero cuando se envíen los datos a la fachada,
además de los datos visibles se enviarán los valores TemaCongreso y edit. La razón de enviar estos
datos adicionales se explica en el punto 8.

6. Centremos la atención sobre el siguiente código:


<link rel=”stylesheet” type=”text/css” href=”estiloFormulario.css” />

Para crear el CSS al que se hace referencia, pulse clic derecho sobre la carpeta vista, elija Hoja de Estilo
en Cascada y asigne como nombre: estiloFormulario. Si no aparece disponible este tipo de archivo,
busque dentro de la opción Otros… hasta encontrarlo. El código necesario es exactamente igual al del
CSS del punto 17 del taller anterior, o sea este:
fieldset ul, fieldset li{
list-style:none;
}

fieldset li{
clear:both;
list-style:none;
padding:10px;
}

fieldset input{
float:left;
}

fieldset label{
width:90px;
float:left;
}

De esta manera se han hecho dos mejoras: el código HTML aparece menos ofuscado y ahora el archivo
CSS es reutilizable.

7. Agregue a la carpeta vista las siguientes tres PHP Web Pages para complementar la capa de
presentación o vista y observar tres cosas importantes: 1) sí es posible reutilizar el archivo CSS, 2) ahora
todas las páginas de la capa de presentación se comunican con un script que hace las veces de
controlador de fachada y 3) los datos de los campos ocultos hacen referencia a la misma clase pero a
distintas operaciones.

Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página 6


Talleres de Ingeniería del Software 3 – Patrones de Diseño

a. editarTema:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Agregar temas de congresos</title>
<link rel="stylesheet" type="text/css" href="estiloFormulario.css" />
</head>
<body>
<fieldset>
<legend>Editar temas de congresos</legend>
<form action="../controlador/fachada.php" method="post">

<input type="hidden" name="clase" value="TemaCongreso" />


<input type="hidden" name="oper" value="edit" />

<ul>
<li>
<label for="txtTema">ID tema:</label>
<input type="text" name="id" id="id" size="50" />
</li>
<li>
<label for="txtTema">Descripción:</label>
<input type="text" name="descripcion" id="descripcion" size="50"/>
</li>
<li>
<label for="submit"></label>
<button type="submit" id="submit">Enviar</button>
</li>
</ul>
</form>
</fieldset>
</body>
</html>

b. eliminarTema:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Agregar temas de congresos</title>
<link rel="stylesheet" type="text/css" href="estiloFormulario.css" />
</head>
<body>
<fieldset>
<legend>Eliminar temas de congresos</legend>
<form action="../controlador/fachada.php" method="post">

<input type="hidden" name="clase" value="TemaCongreso" />


<input type="hidden" name="oper" value="del" />

<ul>
<li>
<label for="txtTema">ID a eliminar:</label>
<input type="text" name="id" id="id" size="50" />
</li>
<li>
<label for="submit"></label>
<button type="submit" id="submit">Enviar</button>
</li>
</ul>
</form>
</fieldset>
</body>
</html>

Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página 7


Talleres de Ingeniería del Software 3 – Patrones de Diseño

c. mostrarTemas:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>

<body onload="document.forms['frmTemas'].submit()">
<form id="frmTemas" action="../controlador/fachada.php" method="post">
<input type="hidden" name="clase" value="TemaCongreso" />
<input type="hidden" name="oper" value="getList" />
</form>
</body>
</html>

Este último formulario a pesar de lo pequeño tiene tres detalles importantes:

a. Como se muestra en el código resaltado, cuando se carga (onload), inmediatamente


envía los datos del formulario frmTemas al controlador de fachada.
b. No se separan las capas de HTML y Javascript puesto que la instrucción resaltada es de
Javascript y está embebida en una instrucción HTML.
c. Con lo anterior se incumple la buena práctica de escribir “Javascript no obstructivo”.
Esta buena práctica dice que se debe separar la funcionalidad JavaScript tanto de la capa
de estructura (CSS) como del contenido y presentación de una página (HTML).

Con esto termina la creación de la capa de presentación; enseguida se crea el script que hará de
controlador de dominio.

8. Agregue a la carpeta controlador un PHP File llamado fachada con el siguiente código fuente:
1 <?php
2 /**
3 * Controlador de fachada que recibe mensajes de la capa de presentación,
4 * Instancia la base de datos,
5 * Delega a otras clases las peticiones recibidas y en algunas ocasiones
6 * Envía las respuestas recibidas a la capa de presentación.
7 * Basado en el patron GoF "Facade", ver Larman
8 * @author Carlos Cuesta Iglesias
9 */
10
11 header('Content-Type: text/html; charset=UTF-8');
12 error_reporting(E_ALL);
13
14 try {
15 include_once("adodb/adodb-exceptions.inc.php");
16 include_once('adodb/adodb.inc.php');
17 include('adodb/tohtml.inc.php');
18
19 $conexion = Conexion::getInstance('postgres', 'localhost', 'postgres', 'admin', 'congresos');
20 $clase = $_REQUEST['clase'];
21 $metodo = $_REQUEST["oper"];
22 $obj = new $clase($conexion);
23 $obj->$metodo($_REQUEST);
24 } catch (Exception $e) {
25 echo json_encode(array("mensaje" => $e->getMessage()));
26 }
27

Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página 8


Talleres de Ingeniería del Software 3 – Patrones de Diseño

28 /**
29 * Intenta cargar aquellas clases que no se incluyen explícitamente.
30 * @param <type> $nombreClase el nombre de la clase que se intentará cargar
31 * desde la ruta ../modelo/
32 * IMPORTANTE: include_once no lanza excepciones
33 */
34 function __autoload($nombreClase) {
35 if ($nombreClase == "Conexion") {
36 $nombreClase = "../serviciosTecnicos/$nombreClase.php";
37 } else {
38 $nombreClase = "../modelo/$nombreClase.php";
39 }
40
41 if (file_exists($nombreClase)) {
42 include_once($nombreClase);
43 } else {
44 throw new Exception("No existe la clase $nombreClase");
45 }
46 }
47
48 ?>

Es muy importante que entienda el código anterior desde dos puntos de vista: uno desde la visión de
programador de PHP y otro desde la visión de ingeniería del software. Por lo tanto además de
comprender la documentación incluida en el código fuente, se ruega tener especial cuidado con las
siguientes notas complementarias:

• Línea 19: Por deducción de la sintaxis utilizada, al objeto conexion se le asigna lo que retorna el
método estático getInstance. Se conjetura que es un mensaje a un método estático porque PHP
utiliza la sintaxis Clase::método para enviar un mensaje a un método estático.
Por los argumentos enviados, también se puede deducir que la instancia que retorna este
método es una conexión a la base de datos.
Si le aburren las suposiciones consulte ahora el paso 9 donde se documenta la implementación
del método getInstance.
• Líneas 20 y 21: Gracias al array asociativo1 $_REQUEST2 el controlador tiene acceso a los
nombres de la clase y de la operación que se van a usar. Si no se pasan estos argumentos
esperados (clase y oper como mínimo) la línea 25 produce el error fatal: “Class name must be a
valid object or a string”, si dicho argumentos llegan correctamente, en las variables clase y oper
quedan asignados los valores que se envían desde los formularios.
• Línea 22: Se crea un objeto a partir de una clase cuyo nombre se proporciona desde la capa de
presentación y por la forma de la instrucción se supone que el constructor de dicha clase está en
capacidad de recibir como argumento, un objeto de tipo Conexion. Sin embargo realmente no se
sabe de qué tipo es el objeto pues esto depende de los datos que se reciben mediante el array
$_REQUEST.
• Línea 23: Se hace un llamado al método del objeto recién creado y se le envía como argumento,
el array $_REQUEST. Como en el caso anterior, el nombre del método llamado, depende de los
datos que llegan desde la capa de presentación.

1
Un array asociativo es una formación o arreglo de pares (clave, valor). $_POST o $_GET son arrays asociativos que
contienen datos enviados por los formularios del cliente, capa de presentación o vista.
2
En PHP se dispone del array asociativo $_REQUEST que recoge los valores GET, POST o COOKIEs enviados desde un
formulario al servidor.

Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página 9


Talleres de Ingeniería del Software 3 – Patrones de Diseño

• Línea 25: En caso de presentarse un error entre las líneas 15 y 23, el manejador de excepciones
enviará el mensaje de error a la capa vista en formato JavaScript Object Notation (JSON).3
• Pregunta: ¿cómo hace PHP para cargar la clase solicitada a partir de la línea 22 si no hay una
instrucción include que indique dónde encontrarla? – Sencillo, mediante un método mágico.
A partir de PHP 5 no es necesario utilizar include para cargar explícitamente los archivos que
contienen las clases. Por el contrario se puede hacer de forma implícita si se define una función
__autoload, la cual es llamada automáticamente en caso de que intente usar una clase que no
ha sido definida aún. Al llamar esta función la ejecución del script da una última oportunidad de
cargar la clase antes de que PHP falle con un error fatal.
A partir de la línea 34 del código anterior, se indica cómo el método mágico __autoload recibe
como argumento el nombre de la clase y la misma se busca en la capa de servicios técnicos o en
la de dominio. En caso de que el archivo exista, éste se incorpora a la aplicación.
• Citando nuevamente a Larman, la fachada creada se comporta como un “… objeto ‘front-end’
que es el único punto de entrada para los servicios de un subsistema”. De esta manera
fachada.php se convierte en el único punto de entrada para llevar a cabo la comunicación
cliente/servidor (C/S), o lo que es lo mismo, comunicar la vista con el subsistema que se definirá
como modelo de dominio a partir del siguiente diseño de clases UML:

3
Para saber más de JSON consulte: http://www.json.org/json-es.html o si quiere algo más detallado, existe este
manual: http://www.ua.es/es/servicios/si/documentacion/mootools/json/t4_json.pdf. La idea es que JSON cumple con
la misma funcionalidad del XML, es mucho más sencillo y está tomando un auge enorme.
Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página
10
Talleres de Ingeniería del Software 3 – Patrones de Diseño

9. Como indican los rombos vacíos de la gráfica anterior, la asociación4 que existe entre TemaCongreso y
Conexion es una agregación, es decir, TemaCongreso tiene una referencia a una instancia de tipo
Conexion. Por esta razón lo mejor es agregar primero a la carpeta serviciosTecnicos la siguiente PHP
Class con el nombre Conexión y luego sí crear la clase TemaCongreso:
1 <?php
2 /**
3 * Description of Conexion:
4 * Implementación del patrón Singleton para proporcionar una única instancia de esta clase
5 * que será la encargada de proporcionar la conexión a la base de datos.
6 * Como puede verse, sólo hay dos métodos públicos:
7 * getInstance: que devuelve un objeto de tipo Conexión y
8 * getADO : que devuelve una referencia al atributo ado
9 * El constructor y el método __clone() son privados para evitar su uso fuera de la clase.
10 * @author Carlos Cuesta Iglesias
11 */
12
13 class Conexion {
14
15 private static $ado; // Una referencia a un objeto de tipo ADONewConnection
16 private static $conexion;
17
18 /**
19 * La función construct es privada para evitar que el objeto pueda ser creado mediante new.
20 * Cuando este método se llama, crea una conexión a una base de datos.
21 */
22 private function __construct() { }
23
24 /**
25 * Es posible que un script envié varios mensajes getInstance(...) a un objeto de tipo Conexion,
26 * sinembargo siempre se retornará la misma instancia de Conexión, garantizando así
la
27 * implementacion del Patrón Singleton
28 * @param <type> $driver El tipo de driver: postgres, mysql, etc.
29 * @param <type> $servidor El host: localhost o cualquier IP válida
30 * @param <type> $usuario El usuario que tiene privilegios de acceso a la base de datos
31 * @param <type> $clave La clave del usuario
32 * @param <type> $db El nombre de la base de datos
33 * @return <type> Una instancia de tipo Conexion
34 */
35 public static function getInstance($driver, $servidor, $usuario, $clave, $baseDeDatos) {
36 // la siguiente condición garantiza que sólo se crea una conexion de esta clase
37 if (!isset(self::$conexion)) { // Si la conexion no ha sido creada…
38 self::$conexion = new self(); // llamado al constructor
39 self::$ado = ADONewConnection($driver);
40 self::$ado->Connect($servidor, $usuario, $clave, $baseDeDatos);
41 }
42 return self::$conexion;
43 }
44
45 /**
46 * Se sobreescribe este 'método mágico' para evitar que se creen clones de esta clase
47 */
48 private function __clone() { }
49
50 /**
51 * Retorna el Objeto de Conexión de Datos (ado)
52 * @return <type> Retorna el objeto de tipo ADONewConnection activo
53 */

4
Recuerde que las asociaciones de composición se representan con rombos rellenos y que los objetos que forman
parte del compuesto son destruidos cuando se destruye el compuesto. En cambio los objetos referenciados en la
agregación sobreviven a la destrucción del objeto que los referencia.
Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página
11
Talleres de Ingeniería del Software 3 – Patrones de Diseño

54 public function getADO() {


55 return self::$ado;
56 }
57 }
58 ?>

Como puede ver, es más la documentación que el código fuente. La conexión sigue haciéndose en dos
simples líneas de código y lo demás es para garantizar que el constructor y el método clone no se
puedan utilizar por fuera de la clase para crear conexions de ésta (self). Así se obliga a usar el método
getInstance que verifica si ya hay una conexion de esta clase (self) o si por el contrario hay que crear una
y sólo una.

Puesto que la clase está tan documentada, no se redundará en explicaciones, más bien se invita a
estudiar el código y a consultar las posibles instrucciones desconocidas.

10. Según el modelo de clases mostrado en la figura anterior, la clase TemaCongreso implementa una
interface llamada Persistible, entonces lo mejor es definirla ahora. Para ello pulse clic derecho sobre la
carpeta modelo y elija crear una nueva PHP Interface de nombre Persistible, con el código que se
proporciona enseguida:
<?php

/**
* Esta interface servirá de ejemplo para explicar el patrón Estrategia
* @author Carlos Cudesta Iglesias
*/
interface Persistible {

function add($pDatos);

function edit($pDatos);

function del($pDatos);

function select($pDatos);

function getList();
}
?>

11. Ya se tiene la interface Persistible que implementarán muchas de las clases del modelo de dominio y
también se tiene la clase Conexion que también será referenciada por todas las clases que necesiten el
servicio de conexión a la base de datos. Ahora sí se puede proceder a crear la clase TemaCongreso en la
carpeta modelo y con base en el siguiente código:
<?php

/**
* Description of TemaCongreso
* Es un sencillo ejemplo del ‘Patrón Experto’ que reune en una sola clase toda la lógica
* del menajo de temas de congresos.
* @author Carlos
*/

class TemaCongreso implements Persistible {

private $conexion;
private $adodb; // conexion a la base de datos

Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página


12
Talleres de Ingeniería del Software 3 – Patrones de Diseño

/**
* Se crea una conexion de TemaCongreso que proporciona
* acceso a la información persistente de temas de congresos con el propósito
* de permitir operaciones CRUD.
* @param <ADODB> $ado
*/
function __construct($conexion) {
$this->conexion = $conexion;
$this->adodb = $this->conexion->getADO();
}

/**
* Inserta el nuevo congreso enviado por $_POST
* @param <type> $pDatos El array que contiene los argumentos enviados por $_POST
*/
function add($pDatos) {
// Se transfieren a variables locales los argumentos que llegan por $_POST
foreach($pDatos as $argumento => $valor) {
eval("\$$argumento = '$valor';");
}

$sql = "SELECT tema_congreso_insertar('$descripcion')";


try {
$this->adodb->Execute($sql);
echo json_encode(array("mensaje" => "ok"));
} catch (Exception $e) {
echo json_encode(array("mensaje" => $e->getMessage()));
}
}

/**
* Actualiza una fila de temas de congresos.
* @param <type> $pDatos Un array con el id a buscar y el nuevo tema
*/
function edit($pDatos) {
// Se transfieren a variables locales los argumentos que llegan por $_POST
foreach($pDatos as $argumento => $valor) {
eval("\$$argumento = '$valor';");
}

$sql = "SELECT tema_congreso_actualizar($id, '$descripcion')";


try {
$this->adodb->Execute($sql);
echo json_encode(array("mensaje" => "ok"));
} catch (Exception $e) {
echo json_encode(array("mensaje" => "Error al actualizar el registro. Verifique los datos"));
}
}

/**
* Elimina los temas de congresos cuyos IDs se pasen como argumentos.
* @param <type> $pDatos los IDs de los temas de congresos a ser eliminados.
* $pDatos es un cadena que contiene uno o varios números separados por
* comas, que corresponden a los IDs de las filas a eliminar.
*/
function del($pDatos) {
// El formato que espera postgres es: SELECT usuario_eliminar('{v1,...,vn}');
$datos = "'{".$pDatos['id']."}'";
$sql = "select tema_congreso_eliminar($datos)";
try {
$total = $this->adodb->Execute($sql)->RecordCount();
echo json_encode(array("mensaje" => "ok"));
} catch (Exception $e) {
echo json_encode(array("mensaje" => $e->getMessage()));
}
}

Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página


13
Talleres de Ingeniería del Software 3 – Patrones de Diseño

/**
* Devuelve los datos necesarios para construir una tabla dinámica.
* @param <type> $pDatos los argumentos enviados por:
* TemaCongreso.js.crearTablaTemasCongreso()
*/
function select($pDatos) {
// pendiente... ¿qué sucede si se elimina este método?
}

/**
* Por ahora devuelve una tabla con la información de temas de congresos
*/
function getList() {
$sql = "SELECT * FROM tema_congreso_lista";
$rs = $this->adodb->Execute($sql);
rs2html($rs, 'border=2 cellpadding=3',array('Descripción','ID Tema'));
echo "<a href='../index.php'>Regresar al menú principal</a>";
}
}

?>

12. Ya puede probar la aplicación. Para ello, utilice la página index.php, a partir de la cual tendrá disponible
el comportamiento que se describe a continuación:

• index.php mostrará un sencillo menú como este:

• Mostrar temas de congresos deberá presentar una tabla como esta:

• Agregar temas de congresos se verá así:

Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página


14
Talleres de Ingeniería del Software 3 – Patrones de Diseño

• Eliminar un tema de congreso en realidad permitirá eliminar varios de una sola vez, si separa
varios ID por comas.

• Actualizar un tema de congreso debe permitirle ingresar un ID de un tema existente y establecer


una nueva descripción para dicho tema.

Actividades complementarias
Como pudo darse cuenta, este taller ya empieza a tocar temas que van más allá de la programación básica,
puesto que incluye conceptos de Ingeniería del Software, concretamente de aspectos relacionados con el
manejo de patrones en diseño. Las actividades complementarias que se proponen a continuación, están
orientadas a que domine no solo estos conceptos, sino la práctica de los principios vistos en este taller de
Ingeniería del Software.

1. Empecemos por citar lo que es ingeniería de software para Roger Pressman: es una disciplina que
integra el proceso, los métodos, y las herramientas para el desarrollo de software de computadora.
[Pressman, 2005]. Sin embargo este no es el único autor que la ha definido, consulte las de otros autores
como Ian Sommerville, Alfredo Weitzenfield, Bernd Bruegge y Shari Lawrence Pfleeger, Ivar Jacobson,
Grady Booch y James Rumbaugh. También la de organizaciones como la IEEE.

2. Cuando se habla de procesos y métodos en la definición anterior hay que decir que dentro de la
ingeniería de software existen modelos para dichos procesos que se pueden catalogar como
Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página
15
Talleres de Ingeniería del Software 3 – Patrones de Diseño

prescriptivos y ágiles. La siguiente gráfica tomada del libro “De


De Gestión de Proyectos en Ingeniería de
5
Software a Gobierno de Tecnologías de Información
Inform ”, muestra los modelos más representativos de las
tendencias prescriptiva y ág ágil;
il; por favor consulte sobre dichos modelos y elabore un resumen al
respecto.

En cascada Programación extrema

Incrementales Desarrollo Adaptativo de


• Incremental Software
• Desarrollo Rápido de Aplicaciones

Desarrollo de Sistemas
Evolutivos Dinámicos
• Prototipos
• Espiral
• Concurrente
Cristal

Especializados
• Basado en componentes Desarrollo conducido por
• Métodos formales características
• Orientado a aspectos

Modelado Ágil
Proceso Unificado

Proceso Unificado Ágil

3. En lo que tiene que ver con el desarrollo de software, existen muchos patrones que se pued
pueden aplicar a
nuestros desarrollos, dichos patrones se clasifican en creacionales, de comportamiento y estructurales.
Para continuar adelante, debe quedar claro por qué se definen así, cuáles patrones pertenecen a cada
grupo y conocer una breve definición de
d cada uno de ellos.

4. Aunque usted no lo crea, es posible que la práctica anterior tuviera en cuenta varios patrones de diseño,
como por ejemplo:

• Alta cohesión,
• Bajo acoplamiento,
• Estrategia,
• Experto,
• Facade,
• MVC y
• Singleton.

5
Cuesta C., Gómez C., Marulanda C. De Gestión de Proyectos en Ingeniería de Software a Gobierno de Tecnologías de
Información. Editorial Universidad de Caldas.
Cald Manizales, 2010.
Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página
16
Talleres de Ingeniería del Software 3 – Patrones de Diseño

Confronte la información obtenida en el punto 4 con el diseño y el código fuente y escriba un


documento donde se justifique qué parte del modelo o del código tiene en cuenta algún patrón.
Enseguida se presenta un breve ejemplo de lo que se pide:

El script fachada.php implementa el patrón Facade porque dicho script proporciona una interfaz
unificada y sencilla que hace las veces de intermediaria entre un cliente ubicado en la capa vista y un
paquete de clases que se encuentra en el servidor, exactamente en la capa de dominio.

De la manera mostrada puede continuar documentando cada uno de los casos en que se utilizaron
patrones de diseño.

5. Suponga los siguientes cambios en la clase Conexion:

• Se agrega el siguiente atributo:


private static $i = 0;

• Se modifica el constructor así:


private function __construct() {
self::$i++;
}

• Se agrega este método:


public function getI() {
return self::$i;
}

Recuerde que getInstance(…) utiliza el constructor de la clase Conexion. Ahora diga qué valor se muestra
en el navegador luego de ejecutar las siguientes instrucciones que se garantiza son correctas:
$conexion = Conexion::getInstance('postgres', 'localhost', 'postgres', 'admin', 'congresos');
$conexion2 = Conexion::getInstance('postgres', 'localhost', 'postgres', 'admin', 'congresos2');
$conexion3 = Conexion::getInstance('postgres', 'localhost', 'postgres', 'admin', 'congresos3');
$conexion4 = Conexion::getInstance('postgres', 'localhost', 'postgres', 'admin', 'congresos4');
$i = $conexion4->getI();
echo "El valor de i es: $i";

Justifique la respuesta dada y tenga en cuenta que se demora menos haciendo el seguimiento mental
del algoritmo que intentando probar los cambios en el sistema.

6. Afortunadamente usted puede encontrar en la Web mucha información relacionada con los temas que
se están tratando. Por ejemplo en el sitio http://www.desarrolloweb.com/articulos/1326.php, se
encuentra un artículo relacionado con el uso de la función eval de PHP.

Vamos a probar si lo que dice el autor del sito es cierto y por lo tanto se recomienda que lea el artículo
antes de intentar lo siguiente:

Modifique el bloque try {…} de la fachada para incluir el código que a continuación se resalta:

Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página


17
Talleres de Ingeniería del Software 3 – Patrones de Diseño

...
try {
include_once("adodb/adodb-exceptions.inc.php");
include_once('adodb/adodb.inc.php');
include('adodb/tohtml.inc.php');

$conexion = Conexion::getInstance('postgres', 'localhost', 'postgres', 'admin', 'congresos');

foreach($_POST as $nombre_campo => $valor){


$asignacion = "\$$nombre_campo = '$valor';";
echo "$asignacion<br>";
eval($asignacion);
}
echo "Se va a llamar a $clase->$oper(...)<br>";

// los valores que llegan por POST desde la capa de presentación se pasan a variables
$clase = $_POST['clase'];
...

Ensaye la opción Actualizar un tema de congreso y verifique si al aceptar los cambios de un registro, el
navegador muestra una información similar a esta:
$clase = 'TemaCongreso';
$oper = 'edit';
$id = '55';
$descripcion = 'Agentes y Web 3.0';
Se va a llamar TemaCongreso->edit(…)
...

Luego de realizar el ensayo deben quedar claro cuatro asuntos: 1) el paso de información por POST
desde el cliente hasta el servidor, 2) el uso de la instrucción foreach, 3) el uso de la función eval y 4) una
forma rápida de asignar a variables locales lo que llega por POST. Terminado el ejercicio deshaga los
cambios realizados, ya que esto era sólo una prueba.6

7. La instrucción siguiente, aparece varias veces en el código fuente de esta práctica. Claramente indica
que se crea un array asociativo que se envía como argumento a la función json_encode y que lo que
devuelve esta función lo toma el comando echo para imprimir dentro de una página.
echo json_encode(array(“mensaje” => $e->getMessage()));

Documente por qué los arrays asociativos están llegando al navegador con el formato siguiente:
{"mensaje":"ok"}

8. Si cree que ya comprende todo lo que necesita saber de JSON, intente enviar mediante la instrucción:
echo json_encode(…); la siguiente información , pero no necesariamente con los saltos de línea que
se muestra:
{"paginas" :"1",
"total" :1,
"registros":6,
"filas":
[ {"id_tema_congreso":"4","celda":["4","Agentes y Web 3.0"]},
{"id_tema_congreso":"3","celda":["3","Comunicaciones y Redes"]},
{"id_tema_congreso":"2","celda":["2","Inteligencia artificial"]},
{"id_tema_congreso":"1","celda":["1","Bioingeniería"]}
]
}

6
No olvide visitar la sección de vínculos interesantes de su grupo.
Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página
18
Talleres de Ingeniería del Software 3 – Patrones de Diseño

9. Volvamos al modelo conceptual de la base de datos que se muestra en la página 3 del taller 1; esta vez
para continuar elaborando el modelo de clases que se muestra en la página 10 de este taller. Por ahora
sólo agregue las clases necesarias para manipular la información de las tablas marcadas con color verde.

10. Revise los comentarios que Craig Larman hace en su libro “UML y Patrones, 2ª edición” con respecto a
los patrones bajo acoplamiento y alta cohesión y diga si dichos patrones se cumplen para el diseño del
punto 9. Sustente su respuesta y además opine si como está quedando el modelo de dominio está
quedando correcto o no. Para su opinión tenga siempre en cuenta la teoría del uso de patrones.

11. Implemente las clases modeladas siguiendo la estrategia utilizada para la clase TemaCongreso.

12. Si le quedaron dudas sobre los siguientes términos, por favor consúltelos:

• HTML: Link, POST, GET, onload.

• PHP: array(…), $_POST, $_GET, $_REQUEST header, error_reporting, include_once, include,


manejo de excepciones mediante try {…} catch(…) {…}, json_encode, __autoload, métodos
mágicos, file_exists, __construct, self, __clone, interface, this.

• ADODB: RecordCount, rs2HTML.

• Javascript no obstructivo.

13. Hasta ahora se ha trabajado con base en un problema especificado en el primer taller, el cual se
documentó además con un modelo de bases de datos y con algunas clases. Sin embargo no siempre se
cuenta con esta suerte, algunas veces tendrá que hacer ingeniería inversa sobre una solución para
entenderla y luego complementarla o corregirla; otras veces se le pedirá que haga reingeniería total y
muchas otras veces deberá empezar de cero, con las solas indicaciones de lo que quieren clientes y
usuarios.

El caso de estudio que se presenta a continuación es uno de reingeniería total en el cual el docente hará
las veces de cliente-usuario y con el cual se espera prestar un servicio sin ánimo de lucro. La idea es la
siguiente:

Según lo reglamenta la Comisión Nacional de Televisión (CNTV), en Colombia existe el servicio de


televisión comunitaria cerrada sin ánimo de lucro, el cual puede ser prestado por comunidades
organizadas.7 Normalmente estas comunidades ofrecen el servicio básico de televisión a muy bajo costo
y cuentan con alguna forma de sistematizar la información de su servicio. Estas formas de
sistematización van desde los simples libros físicos, pasando por documentos de texto u hojas de cálculo
digitales, hasta algunos programas hechos a la medida.

Uno de estos programas a la medida ya cumplió su ciclo. Es una aplicación stand-alone que viene
funcionando desde el siglo pasado y cuya última actualización se hizo en el 2007.

7
Información adicional puede ser consultada en:
• http://www.cntv.org.co/cntv_bop/basedoc/arbol/10087.html,
• http://www.cntv.org.co/cntv_bop/basedoc/arbol/9928.html o
• http://www.cntv.org.co/cntv_bop/servicio_cober/tarifas/comunitaria_3_07a.pdf.
Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página
19
Talleres de Ingeniería del Software 3 – Patrones de Diseño

Lo que se quiere inicialmente es conservar la funcionalidad de dicha aplicación pero en una versión Web
2.0, de distribución libre, creada como proyecto de Ingeniería del Software I. Más adelante se espera
que en la medida en que las más de 100 comunidades potenciales que la usen y posiblemente aporten
críticas y sugerencias, se vaya fortaleciendo con la incorporación de los cambios necesarios.

En resumen, la aplicación actual lo que hace es permitir manejar la información de los suscriptores y
suscripciones del servicio, los conceptos de cobro y los recibos de aportes para sostenimiento. Aquí hay
que aclarar que la televisión comunitaria no factura sino que recoge y registra aportes mensuales en
unos impresos como el de la figura siguiente:

La idea es que como proyecto de Ingeniería del Software I, elabore el análisis, diseño e implementación
de una aplicación Web 2.0 que permita la administración de la información sobre suscripciones y
aportes del servicio de televisión comunitaria, teniendo en cuenta además que dichos aportes están
exentos de IVA y que su registro y control requiere de diversos tipos de reportes y consultas similares al
que se muestra enseguida:

Universidad de Caldas Ingeniería de Sistemas y Computación carlos.cuesta@ucaldas.edu.co Página


20

You might also like