lunes, 15 de diciembre de 2008

Generando código PHP desde UML

Creative Commons License

Esta obra está bajo una licencia de Creative Commons.

© 2008 Jaime M. Tan Nozawa. Usted es libre de copiar, distribuir y comunicar públicamente la obra y hacer obras derivadas bajo las condiciones siguientes: a) Debe reconocer y citar al autor original. b) No puede utilizar esta obra para fines comerciales (incluyendo su publicación, a través de cualquier medio, por entidades con fines de lucro). c) Si altera o transforma esta obra, o genera una obra derivada, sólo puede distribuir la obra generada bajo una licencia idéntica a ésta. Al reutilizar o distribuir la obra, tiene que dejar bien claro los términos de la licencia de esta obra. Alguna de estas condiciones puede no aplicarse si se obtiene el permiso del titular de los derechos de autor. Los derechos derivados de usos legítimos u otras limitaciones no se ven afectados por lo anterior. Licencia completa en castellano. La información contenida en este documento y los derivados de éste se proporcionan tal cual son y los autores no asumirán responsabilidad alguna si el usuario o lector hace mal uso de éstos.


Continuando con el artículo de herramientas CASE UML para PHP 5, veremos ahora la creación de código a partir de un diagrama de clases de dos herramientas: BoUML y ArgoUML.

Indice de secciones:
  1. Revisando la generación de código
  2. Revisando las asociaciones entre clases
    1. Dependencia
    2. Asociación simple
    3. Asociación de agregación y composición
    4. Asociación de generalización

1) Revisando la generación de código








Clase creada en ArgoUML / Clase Creada en BoUml

Se ha una clase Carrito, pero en diferentes herramientas. Veamos el código generado

>> Código generado en BoUML <<
Se puede verificar lo siguiente:
  • Vemos que genera el nombre de clase en PHP con el mismo nombre que en el UML
  • IMPORTANTE: Dispone de unas etiquetas de comentario // Bouml preserved body begin/end que permitirá evitar la sobre-escritura de tus implementaciones una vez que hayas generado tu código
  • Detectó bien la inicialización de un atributo y la visibilidad
  • Se crea las carpeta según el paquete donde se encuentra (previa configuración)
  • PROBLEMA: Los valores de retorno siempre son null, a pesar de haberle especificado entero o cadena.
  • PROBLEMA: Se crea un comentario, pero no comenta el tipo de dato de los atributos, los parámetros del método o la visibilidad.
<?php

/**
* Clase Carrito de compras
*/
class Carrito {
/**
* Cantidad de productos en el carrito
*/
private $cantidad = 0;

/**
* Contructor
*/
public function __construct()
{
// Bouml preserved body begin 0001F503

$return=NULL;

return($return);
// Bouml preserved body end 0001F503
}

public function count()
{
// Bouml preserved body begin 0001F583

$return=NULL;

return($return);
// Bouml preserved body end 0001F583
}

public function guardar()
{
// Bouml preserved body begin 0001F603

$return=NULL;

return($return);
// Bouml preserved body end 0001F603
}

}
?>

>>Código generado en ArgoUML<<
Se puede verificar lo siguiente:
  • Vemos que genera el nombre de clase en PHP con el estilo de formato largo, con el separados underline(_) y como prefijo al nombre original en UML
  • Se crea un comentario estilo PHPdoc, lo realizo de forma excelente documentando casi todo. Inclusive el creador, fecha y otros detalles minucios.
  • Dispone de unas etiquetas de comentario similares al BoUML, que permitirá evitar la sobre-escritura de tus implementaciones una vez que hayas generado tu código
  • Los valores de retorno son detectado, inclusive te realiza un cast de las variables.
  • Detectó bien la inicialización de un atributo y la visibilidad
  • Te genera una carpeta por paquete.
  • Dispone de unas secciones especiales como /* user defined includes */ para agregar includes o requires y no ser sobre-escritos.
  • Para generar un tipo String, se debe especificar el tipo "char"
  • Problema: Tiene demasiado "código extra", un código para detectar si es PHP 5, y fuerza mostrar los errores inclusive los de tipo "Notice".
  • Te crea un include para cada archivo donde se aloja la clase que necesitas. si esta clase estuviera relacionada a muchas otras generaría mucho código (una para cada asociacion). Este código se consideraría tambien "extra" o "de más" si es que utilizamos el método mágico __autoload, para la carga automática de clases. O bueno claro! con los namespaces que vienen ya en PHP 5.3
<?php

error_reporting(E_ALL);

/**
* Modelo Test PHP 5 y UML - modelo\class.Carrito.php
*
* $Id$
*
* This file is part of Modelo Test PHP 5 y UML.
*
* Automatically generated on 16.12.2008, 00:46:11 with ArgoUML PHP module
* (last revised $Date: 2008-04-19 08:22:08 +0200 (Sat, 19 Apr 2008) $)
*
* @author Jaime M. Tan Nozawa, <jtnozawa@gmail.com>
* @package modelo
*/

if (0 > version_compare(PHP_VERSION, '5')) {
die('This file was generated for PHP 5');
}

/* user defined includes */
// section -64--88-1-33--101592aa:11e3c5ee07c:-8000:0000000000000CB6-includes begin
// section -64--88-1-33--101592aa:11e3c5ee07c:-8000:0000000000000CB6-includes end

/* user defined constants */
// section -64--88-1-33--101592aa:11e3c5ee07c:-8000:0000000000000CB6-constants begin
// section -64--88-1-33--101592aa:11e3c5ee07c:-8000:0000000000000CB6-constants end

/**
* Short description of class modelo_Carrito
*
* @access private
* @author Jaime M. Tan Nozawa, <jtnozawa@gmail.com>
* @package modelo
*/
class modelo_Carrito
{
// --- ASSOCIATIONS ---


// --- ATTRIBUTES ---

/**
* Short description of attribute cantidad
*
* @access private
* @var int
*/
private $cantidad = 0;

// --- OPERATIONS ---

/**
* Short description of method __construct
*
* @access public
* @author Jaime M. Tan Nozawa, <jtnozawa@gmail.com>
* @return void
*/
public function __construct()
{
// section -64--88-1-33--101592aa:11e3c5ee07c:-8000:0000000000000CFA begin
// section -64--88-1-33--101592aa:11e3c5ee07c:-8000:0000000000000CFA end
}

/**
* Short description of method count
*
* @access public
* @author Jaime M. Tan Nozawa, <jtnozawa@gmail.com>
* @return int
*/
public function count()
{
$returnValue = (int) 0;

// section -64--88-1-33--101592aa:11e3c5ee07c:-8000:0000000000000CF4 begin
// section -64--88-1-33--101592aa:11e3c5ee07c:-8000:0000000000000CF4 end

return (int) $returnValue;
}

/**
* Short description of method guardar
*
* @access public
* @author Jaime M. Tan Nozawa, <jtnozawa@gmail.com>
* @return boolean
*/
public function guardar()
{
$returnValue = (bool) false;

// section -64--88-1-33--101592aa:11e3c5ee07c:-8000:0000000000000CF6 begin
// section -64--88-1-33--101592aa:11e3c5ee07c:-8000:0000000000000CF6 end

return (bool) $returnValue;
}

} /* end of class modelo_Carrito */

?>



2) Revisando las asociaciones entre clases
Analizaremos varias asociaciones entre clases y la generación del código en PHP:

Asociacion de dependencia
Es una relación de uso, es decir una clase usa a otra, que la necesita para su cometido. Se representa con una flecha discontinua va desde la clase utilizadora a la clase utilizada. Con la dependencia mostramos que un cambio en la clase utilizada puede afectar al funcionamiento de la clase utilizadora, pero no al contrario.



ArgoUML





BoUml




>>Código generado en BoUML<<
No hubo ningún cambio en el código con ésta asociación

>>Código generado en ArgoUML<<
Por la linea 22, antes de los includes de usuario del código ArgoUML generado anteriormente, se insertan estas nuevas lineas. La clase utilizadora(dependiente) "Carrito", realiza un include_once a la clase utilizada "BD". Ésto implica que dentro de la vida de un objeto Carrito requerirá llamar a un método o una instancia de BD.

/**
* include modelo_BD
*
* @author Jaime M. Tan Nozawa, <jtnozawa@gmail.com>
*/
require_once('modelo/class.BD.php');


Asociacion simple
Permite asociar objetos que colaboran entre si. La diferencia con la dependencia radica en que se guarda una referencia de la otra clase.
Esta asociación dispone de navegabilidad, esta dirección significa que uno puede obtener o "ver" el objeto apuntado, a través del objeto cliente. También implica, al igual que la dependencia, el llamar a un método u obtener la instancia de una clase.



ArgoUml




BoUml



>>Código generado en BoUML<<
Para Bouml es necesario crearle el atributo donde guardará la referencia a la clase, esta se encontrará en los extremos de la asociación. En este caso Carrito solita una instancia de BD, y esta se almacenará en el nuevo atributo "conexion".
Revisar al final del código, notar que generó un atributo más


<?php

/**
 * Clase Carrito de compras
 */
class Carrito {
  /**
   * Cantidad de productos en el carrito
   */
  private $cantidad = 0;

  /**
   * Contructor
   */
  public function __construct()
  {
    // Bouml preserved body begin 0001F503

$return=NULL;

return($return);
    // Bouml preserved body end 0001F503
  }

  public function count()
  {
    // Bouml preserved body begin 0001F583

$return=NULL;

return($return);
    // Bouml preserved body end 0001F583
  }

  public function guardar()
  {
    // Bouml preserved body begin 0001F603

$return=NULL;

return($return);
    // Bouml preserved body end 0001F603
  }

  /**
   * instacion de clase DB en asociacion conexion
   */
  private $conexion = null;

}
?>

>>Código generado en ArgoUML<<
En ArgoUML no se crea el atributo en la clase Carrito, pero si crea un comentario sobre la asociación y el nombre bautizado para el extremo. Por ello he creado manualmente un atributo "conexion" en la clase.
OJO, solo puse la primera parte: revisar la linea 47 y 48 del código
<?php

error_reporting(E_ALL);

/**
 * Modelo Test PHP 5 y UML - modelo\class.Carrito.php
 *
 * $Id$
 *
 * This file is part of Modelo Test PHP 5 y UML.
 *
 * Automatically generated on 16.12.2008, 01:57:32 with ArgoUML PHP module 
 * (last revised $Date: 2008-04-19 08:22:08 +0200 (Sat, 19 Apr 2008) $)
 *
 * @author Jaime M. Tan Nozawa, <jtnozawa@gmail.com>
 * @package modelo
 */

if (0 > version_compare(PHP_VERSION, '5')) {
    die('This file was generated for PHP 5');
}

/**
 * include modelo_BD
 *
 * @author Jaime M. Tan Nozawa, <jtnozawa@gmail.com>
 */
require_once('modelo/class.BD.php');

/* user defined includes */
// section -64--88-1-33--101592aa:11e3c5ee07c:-8000:0000000000000CB6-includes begin
// section -64--88-1-33--101592aa:11e3c5ee07c:-8000:0000000000000CB6-includes end

/* user defined constants */
// section -64--88-1-33--101592aa:11e3c5ee07c:-8000:0000000000000CB6-constants begin
// section -64--88-1-33--101592aa:11e3c5ee07c:-8000:0000000000000CB6-constants end

/**
 * Short description of class modelo_Carrito
 *
 * @access private
 * @author Jaime M. Tan Nozawa, <jtnozawa@gmail.com>
 * @package modelo
 */
class modelo_Carrito
{
    // --- ASSOCIATIONS ---
    // generateAssociationEnd : conexion

    // --- ATTRIBUTES ---

    /**
     * Short description of attribute cantidad
     *
     * @access private
     * @var int
     */
    private $cantidad = 0;

    // --- OPERATIONS ---

Continuará... con multiplicidad, agregación/composición y generalización

1 comentario:

Unknown dijo...

Bien con esa pequeña introduccion... estaba buscando algo similar, Gracias por despejar algunas dudas de la utilizacion de esa herramienta.