sábado, 18 de enero de 2014

Object Modeling Framework (OMF)

 Sitio web de descarga del framework:

http://christiansalazar.github.io/omf/

Qué es OMF ?

OMF son las siglas de Object Modeling Framework, un marco de desarrollo de software que sirve para crear y manipular los objetos, sus propiedades y sus relaciones con independencia del método de persistencia.


OMF esta hecho para proveer a tu aplicación de Objetos, sus propiedades y sus relaciones entre otros objetos, permitiendo además buscar, listar, eliminar. 

La Persistencia en OMF.

OMF almacena todos sus objetos, relaciones y propiedades en un único almacenamiento, el cual puede cambiar, puedes almacenar usando un motor mySQL, Oracle, RAM, o cualquier otro, OMF no depende del método de persistencia.

Para un uso rápido de OMF he creado una clase que viene lista para almacenar los objetos de omf en una base de datos MySQL, pudiendo portarse a otras sin mayor esfuerzo. 

Una característica de OMF es que en cualquier momento puedes cambiar de modelo de persistencia, sin alterar en lo absoluto al sistema entero.


Abstracción

Debido a que todo en OMF se guarda como un objeto o una relación sin importar la especificación para la cual fue creado tal objeto entonces el modelo de datos en OMF pasa a ser inexistente, permitiendo que tu aplicación solo sea diseñada con un modelo de clases pero sin un modelo de datos.


Sin Modelo de Datos, en OMF solo usas un Modelo de Objetos.

En un sistema tradicional un modelo de datos se representa mediante tablas y relaciones entre estas, herramientas como MySQL Workbench son ejemplos de modeladores de datos, en OMF estas herramientas no aplican porque no hay un modelo de datos, solo de objetos.

Normalmente en un sistema tradicional concurren dos modelos: Uno de datos y uno de objetos, mucha gente los confunde y los trata como modelos análogos, lo cual es un error de concepto.  Puedes detectar este tipo de comportamiento en el desarrollador del sistema cuando éste va a crear un nuevo sistema y lo primero que piensa es en: "diseñar las tablitas en mysql".

Un sistema de información esta compuesto básicamente de un modelo de objetos que almacena su información mediante un modelo de persistencia, o modelo de datos.  En OMF solo hay un modelo de objetos, la persistencia es manejada por OMF de una forma abstracta y sin requerir intervención de tu parte.


Los datos almacenados por OMF no se parecen a lo que estas acostumbrado a ver en un esquema tradicional de datos.

En OMF no hay un modelo de datos para ser visto, obviamente puedes ir a ver como OMF almacena la información y hacer una vista, esto está sobre entendido, la diferencia es que no verás la información como tradicionalmente la verías en un modelo de datos relacional tradicional. 

Este esquema no es nuevo, no lo estoy inventando en OMF, es bien conocido en otras áreas de desarrollo, por ejemplo cuando quieres crear una aplicación en Google Apps lo primero con lo que chocarás será con el método de almacenamiento: orientado a objetos, tal cual como es OMF.


Cómo puedo explorar los datos en OMF ¡?


Piensa que OMF almacena objetos, la clase de cada objeto la das tu, las relaciones las das tú según la lógica de tu negocio, si quieres ver que has almacenado entonces deberás crear una vista que explore los objetos que has creado.

OMF está en una fase inicial, muy seguramente mas adelante se creará un explorador de datos que pueda ser usado en cualquier aplicación, por ahora no existe. Bienvenido aquel que ayude a crearlo. 

OMF: Objetos, Relaciones y Propiedades

En OMF todo es un objeto relacionado quizá con otro objeto, y teniendo propiedades con sus valores, también consideradas objetos.

Por ejemplo:

[ jamboree :Mascota ]-----es_mascota_de---->[ christian: Persona ]

en este simple ejemplo tenemos: 

1. dos clases: Mascota y Persona
2. dos instancias: jamboree y christian
3. una relación: "es mascota de"

Mas relaciones entre los objetos, agregando una nueva clase "Marca" y nuevas relaciones: "padre_de" y "consume_alimento"

[ jamboree :Mascota ]-----es_mascota_de---->[ christian: Persona ]

[ jamboree :Mascota ]-----consume_alimento---->[ proplan: Marca ]

[ jamboree :Mascota ]-----padre_de---->[ coco: Mascota ]
[ jamboree :Mascota ]-----padre_de---->[ kim: Mascota ]


En tu sistema de información la clave es definir que objetos tienes y cómo estos se relacionan entre sí. OMF va a guardar (persistir) esta información permitiéndote saber que objetos tienes, cómo se relacionan entre sí y que propiedades tiene cada objeto. 

El diseño de clases se da en tiempo real, no tienes que definir clases en un archivo aparte como lo harías en un sistema tradicional, esto da una ventaja enorme: agilidad de diseño, pero hay que tratarla con cuidado.


Las Propiedades de los Objetos con OMF

En OMF las propiedades de los objetos también son tratadas como objetos y el gran beneficio es que no se requiere alterar el esquema de datos para agregar nuevas propiedades:


[aveo: Vehiculo]-----[color]----->[: Metadata, data=azul]
[aveo: Vehiculo]-----[marca]----->[: Metadata, data=chevrolet]

Este nuevo concepto puede parecer raro pero es muy útil, permite cosas que antes no eran posible de hacer con facilidad: como ejemplo podemos decidir "quien puede leer" la propiedad "color" de un "Vehiculo", quizá las demás propiedades puedan ser accesibles por un usuario dado, pero no el color.

OMF te da un getter y un setter para acceder a propiedades de los objetos.

Un Ejemplo con OMF

Hagamos un ejemplo simple, para que se comprenda la idea:


El caso de negocio:

"..Una empresa vende vehículos y quiere saber cuantos vende en un mes y mediante que vendedor..."

Análisis del modelo:

Tenemos las siguientes clases:  Empresa, Vehiculo, Vendedor

y las siguientes relaciones entre sus instancias:

[:empresa]----vende--->[:vehiculo]---mediante--->[:vendedor]

Según el punto de vista podriamos decir que el Vendedor "ha vendido" tales Vehiculos, por tanto cambiemos un poco las relaciones:

[:empresa]---vende--->[:vehículo]
[:vendedor]---ha_vendido---->[:vehículo]
[:vehículo]---vendido_por--->[:vendedor]


Por qué es importante esto de ver la información desde distintos puntos de vista ? porque depende de cómo el negocio quiere obtener la información, el dueño de la tienda de vehiculos puede preguntarnos:

"Cuantos vehículos ha vendido este agente"
o
"Que agente vendió este vehículo"


Podríamos también decir que es una relación redundante si lo vemos desde el punto de vista de un sistema tradicional porque mediante una relación llegas a la otra, pero en programación orientada a objetos: hablamos de objetos, no de modelos de datos y en esto se enfoca OMF.

Como se implementa una solución con OMF ?

Siguiendo lo expuesto en el párrafo anterior, vamos a programarlo con OMF.


ver el codigo en pastebin.com

    #podemos crear objetos y asignar propiedades a estos de forma dinámica:
    $api = new OmfDb();
    $id = $api->create('Empresa');
    $api->set($id, 'razonsocial', 'Vehiculos ABC');
    $api->set($id, 'rif', '123456');
    $api->set($id, 'direccion', 'en algun lugar del mundo');
     
    #podemos buscar los objetos creados:
    foreach($api->find("Empresa","rif","123456") as $obj){
         list($empresa_id) = $obj;
         printf("razonsocial=%s\n", $api->get($empresa_id, "razonsocial"));
    }
     
    #podemos listar que propiedades se han definidos para una instancia 
    #(no la clase, en OMF cada instancia maneja sus propiedades)
    foreach($api->listPropertys($empresa_id) as $propertyname)
       printf("propiedad: %s, valor: %s\n",
            $propertyname, $api->get($empresa_id, $propertyname));
     
    #podemos listar todas las instancias de clase "Empresa":
    # (find y listObjets se parecen, find busca objetos de clase pero 
    # conteniendo un atributo, en cambio listObjects busca todos los objetos 
    #de una clase, con opciones para paginar)
    foreach($api->listObjects("Empresa") as $obj){
       list($empresa_id) = $obj;
       printf("razonsocial=%s\n", $api->get($empresa_id, "razonsocial"));
    }

 Muy bien, este último ejemplo es para crear la empresa, establecer sus propiedades, listar, buscar,  lo mismo aplica para crear el Vendedor, el Vehiculo, ahora vamos a concentrarnos en mostrar cómo crear las relaciones:

 

    #podemos crear objetos y asignar propiedades a estos de forma dinámica:
    $api = new OmfDb();
    $id = $api->create('Empresa');
    $api->set($id, 'razonsocial', 'Vehiculos ABC');
    $api->set($id, 'rif', '123456');
    $api->set($id, 'direccion', 'en algun lugar del mundo');
     
    #podemos buscar los objetos creados:
    foreach($api->find("Empresa","rif","123456") as $obj){
         list($empresa_id) = $obj;
         printf("razonsocial=%s\n", $api->get($empresa_id, "razonsocial"));
    }
     
    #podemos listar que propiedades se han definidos para una instancia 
    #(no la clase, en OMF cada instancia maneja sus propiedades)
    foreach($api->listPropertys($empresa_id) as $propertyname)
       printf("propiedad: %s, valor: %s\n",
            $propertyname, $api->get($empresa_id, $propertyname));
     
    #podemos listar todas las instancias de clase "Empresa":
    # (find y listObjets se parecen, find busca objetos de clase pero conteniendo 
    # un atributo, en cambio listObjects busca todos los objetos de una clase, 
    #con opciones para paginar)
    foreach($api->listObjects("Empresa") as $obj){
       list($empresa_id) = $obj;
       printf("razonsocial=%s\n", $api->get($empresa_id, "razonsocial"));
    }
     
    #creamos Vehiculos para ser ofrecido en la lista de vehiculos de la Empresa:
    #
    $vid1 = $api->create('Vehiculo');
    $api->set($vid1, 'vin', '991991991');
    $api->set($vid1, 'marca', 'Chevrolet');
    $api->set($vid1, 'color', 'Azul');
     
    $vid2 = $api->create('Vehiculo');
    $api->set($vid2, 'vin', '991991992');
    $api->set($vid2, 'marca', 'Ford');
    $api->set($vid2, 'color', 'Fiesta');
     
    $vid3 = $api->create('Vehiculo');
    $api->set($vid3, 'vin', '991991993');
    $api->set($vid3, 'marca', 'Chevrolet');
    $api->set($vid3, 'color', 'Malibu');
     
    # hasta este momento los vehiculos estan creados, pero no relacionados con 
    # ningun otro objeto, hagamos las relaciones:
    $empresas =$api->find("Empresa","rif","123456");
    list($empresa_id) = $empresas[0];
     
    # relacion: la empresa vende vehiculo
    $api->createRelation($empresa_id, $vid1, "vende");
    $api->createRelation($empresa_id, $vid2, "vende");
     
    #ahora un vendedor vende estos dos unicos vehiculos ofrecidos:
    $ag1 = $api->create('Vendedor');
    $api->set($ag1, 'rif', '881881881');
    $api->set($ag1, 'nombres', 'Christian Salazar');
     
    $ag2 = $api->create('Vendedor');
    $ap2->set($ag2, 'rif', '881881882');
    $ap2->set($ag2, 'nombres', 'Otro Vendedor');
     
    $api->createRelation($ag1, $vin1, "vendedor");
    $api->createRelation($ag1, $vin2, "vendedor");
    $api->createRelation($ag2, $vin3, "vendedor");
     
    #como sabemos que vehiculos vende "Christian Salazar" ?
    foreach($api->getChilds($ag1, "vendedor", "Vehiculo") as $obj){
       list($vehiculo_id) = $obj;
       printf("vende: %s %s %s\n",
         $api->get($vehiculo_id, "vin"),
         $api->get($vehiculo_id, "marca"),
         $api->get($vehiculo_id, "color")
       );
    }
 
Tras ver este ejemplo te darás cuenta que:

1.  Las clases se han definido en tiempo real, sin recurrir a creación de archivos, ni tablas en la base de datos.

2. Las propiedades de los objetos se crearon tambien en tiempo real, sin requerir hacer modificaciones en la estructura de datos.

3. Los objetos son independientes, las relaciones los unen, dejando a los objetos como lo que son, sin interferirlos con datos propios de las relaciones con otros objetos.

4. Todo persiste en un modelo de datos fijo manejado por OMF, si mas adelante no te gusta mySQL puedes pasar a otro modelo y la lógica de negocios permanece intacta.

5. OMF se lleva bien con un análisis UML, enfocando el desarrollo en aquello que has planificado en tu arquitectura de sistemas.

6. Adiós al modelo relacional del pasado.


Para conocer los detalles del API de OMF :

https://github.com/christiansalazar/omf

1 comentario:

  1. OMF necesita ayuda.

    TODO list:

    1. [Yii Framework] hacer una implementacion de CDataProvider para OMF.
    o que inmediatamente hara funcionar OMF con CGridView CListView CDetailView.

    2. [Yii Framework] hacerlo consumible por CModel.
    usando el setter de omf capaz de recibir array de propiedades y valores se puede hacer con sencillez para que datos omf puedan presentarse en un formulario CFormModel.

    ResponderEliminar